--- /dev/null
+using Content.Server.Xenoarchaeology.XenoArtifacts.Effects.Systems;
+using Robust.Shared.Prototypes;
+
+namespace Content.Server.Xenoarchaeology.XenoArtifacts.Effects.Components;
+
+/// <summary>
+/// When activated artifact will spawn an pair portals. First - right in artifact, Second - at random point of station.
+/// </summary>
+[RegisterComponent, Access(typeof(PortalArtifactSystem))]
+public sealed partial class PortalArtifactComponent : Component
+{
+ [DataField]
+ public EntProtoId PortalProto = "PortalArtifact";
+}
--- /dev/null
+using Content.Server.Xenoarchaeology.XenoArtifacts.Effects.Components;
+using Content.Server.Xenoarchaeology.XenoArtifacts.Events;
+using Content.Shared.Mind.Components;
+using Content.Shared.Teleportation.Systems;
+using Robust.Shared.Random;
+
+namespace Content.Server.Xenoarchaeology.XenoArtifacts.Effects.Systems;
+
+public sealed class PortalArtifactSystem : EntitySystem
+{
+ [Dependency] private readonly IRobustRandom _random = default!;
+ [Dependency] private readonly LinkedEntitySystem _link = default!;
+ [Dependency] private readonly SharedTransformSystem _transform = default!;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+ SubscribeLocalEvent<PortalArtifactComponent, ArtifactActivatedEvent>(OnActivate);
+ }
+
+ private void OnActivate(Entity<PortalArtifactComponent> artifact, ref ArtifactActivatedEvent args)
+ {
+ var map = Transform(artifact).MapID;
+ var firstPortal = Spawn(artifact.Comp.PortalProto, _transform.GetMapCoordinates(artifact));
+
+ var minds = new List<EntityUid>();
+ var mindQuery = EntityQueryEnumerator<MindContainerComponent, TransformComponent>();
+ while (mindQuery.MoveNext(out var uid, out var mc, out var xform))
+ {
+ if (mc.HasMind && xform.MapID == map)
+ minds.Add(uid);
+ }
+
+ var target = _random.Pick(minds);
+ var secondPortal = Spawn(artifact.Comp.PortalProto, _transform.GetMapCoordinates(target));
+
+ //Manual position swapping, because the portal that opens doesn't trigger a collision, and doesn't teleport targets the first time.
+ _transform.SetCoordinates(artifact, Transform(secondPortal).Coordinates);
+ _transform.SetCoordinates(target, Transform(firstPortal).Coordinates);
+
+ _link.TryLink(firstPortal, secondPortal, true);
+ }
+}
artifact-effect-hint-sentience = Neurological activity
artifact-effect-hint-polymorph = Transmogrificational activity
artifact-effect-hint-magnet = Magnetic waves
+artifact-effect-hint-visual = Visual distortions
# 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")
artifact-trigger-hint-tool = Tool usage
artifact-trigger-hint-music = Sonic vibrations
artifact-trigger-hint-water = Hydro-reactive
+artifact-trigger-hint-blood = Reaction with hemoglobin
artifact-trigger-hint-magnet = Magnetic waves
artifact-trigger-hint-death = Life essence
artifact-trigger-hint-radiation = Radiation
radius: 3
energy: 1
netsync: false
+
+- type: entity
+ id: PortalArtifact
+ parent: BasePortal
+ components:
+ - type: Sprite
+ layers:
+ - state: portal-artifact
+ - type: PointLight
+ color: "#ed85c2"
+ radius: 3
+ energy: 1
+ netsync: false
+ - type: TimedDespawn
+ lifetime: 120
+ - type: Portal
+ canTeleportToOtherMaps: true
components:
- type: KnockArtifact
+- type: artifactEffect
+ id: EffectMagnet
+ targetDepth: 1
+ effectHint: artifact-effect-hint-magnet
+ components:
+ - type: GravityWell
+ maxRange: 3
+ baseRadialAcceleration: 1
+ baseTangentialAcceleration: 3
+
+- type: artifactEffect
+ id: EffectAntiMagnet
+ targetDepth: 1
+ effectHint: artifact-effect-hint-magnet
+ components:
+ - type: GravityWell
+ maxRange: 3
+ baseRadialAcceleration: -1
+ baseTangentialAcceleration: -3
+
+- type: artifactEffect
+ id: EffectInvisibility
+ targetDepth: 2
+ effectHint: artifact-effect-hint-visual
+ components:
+ - type: Stealth
+ hadOutline: true
+ - type: StealthOnMove
+ passiveVisibilityRate: -0.10
+ movementVisibilityRate: 0.10
+
- type: artifactEffect
id: EffectExplosionScary
targetDepth: 2
maxIntensity: 50
- type: artifactEffect
- id: EffectMagnet
- targetDepth: 1
- effectHint: artifact-effect-hint-magnet
- components:
- - type: GravityWell
- maxRange: 3
- baseRadialAcceleration: 1
- baseTangentialAcceleration: 3
-
-- type: artifactEffect
- id: EffectAntiMagnet
- targetDepth: 1
- effectHint: artifact-effect-hint-magnet
+ id: EffectPortal
+ targetDepth: 3
+ effectHint: artifact-effect-hint-displacement
components:
- - type: GravityWell
- maxRange: 3
- baseRadialAcceleration: -1
- baseTangentialAcceleration: -3
+ - type: PortalArtifact
- type: artifactEffect
id: EffectSingulo
isOpen: true
solution: beaker
+- type: artifactEffect
+ id: EffectSpeedUp
+ targetDepth: 2
+ effectHint: artifact-effect-hint-displacement
+ whitelist:
+ components:
+ - Item
+ permanentComponents:
+ - type: HeldSpeedModifier
+ walkModifier: 1.2
+ sprintModifier: 1.3
+
- type: artifactEffect
id: EffectDrill
targetDepth: 3
path: /Audio/Weapons/bladeslice.ogg
- type: Sharp
-
- type: artifactEffect
id: EffectPowerGen20K
targetDepth: 3
effects:
- !type:ActivateArtifact
+- type: artifactTrigger
+ id: TriggerBlood
+ targetDepth: 1
+ triggerHint: artifact-trigger-hint-blood
+ components:
+ - type: Reactive
+ groups:
+ Acidic: [ Touch ]
+ reactions:
+ - reagents: [ Blood ]
+ methods: [ Touch ]
+ effects:
+ - !type:ActivateArtifact
+
- type: artifactTrigger
id: TriggerGas
targetDepth: 2
"y": 32
},
"license": "CC-BY-SA-3.0",
- "copyright": "Taken from tgStation at commit https://github.com/tgstation/tgstation/blob/4a367160a204db4c5b51c1f811a3b899f0bde3ea/icons/obj/stationobjs.dmi and repaletted using old tg sprites by mirrorcult",
+ "copyright": "Taken from tgStation at commit https://github.com/tgstation/tgstation/blob/4a367160a204db4c5b51c1f811a3b899f0bde3ea/icons/obj/stationobjs.dmi and repaletted using old tg sprites by mirrorcult, portal-artifact recolored by TheShuEd",
"states": [
{
"name": "portal-blue",
0.1, 0.1
]
]
+ },
+ {
+ "name": "portal-artifact",
+ "delays": [
+ [
+ 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1,
+ 0.1, 0.1
+ ]
+ ]
}
]
}