diff --git a/Content.Client/Entry/IgnoredComponents.cs b/Content.Client/Entry/IgnoredComponents.cs index 14086f402f..8bbad8b1ad 100644 --- a/Content.Client/Entry/IgnoredComponents.cs +++ b/Content.Client/Entry/IgnoredComponents.cs @@ -326,7 +326,13 @@ namespace Content.Client.Entry "GrowingKudzu", "MonkeyAccent", "ReplacementAccent", - "ResistLocker" + "ResistLocker", + "SpawnArtifact", + "TelepathicArtifact", + "ArtifactGasTrigger", + "ArtifactInteractionTrigger", + "Artifact", + "RandomArtifactSprite" }; } } diff --git a/Content.Client/Xenoarchaeology/XenoArtifacts/RandomArtifactVisualizer.cs b/Content.Client/Xenoarchaeology/XenoArtifacts/RandomArtifactVisualizer.cs new file mode 100644 index 0000000000..ba8484b784 --- /dev/null +++ b/Content.Client/Xenoarchaeology/XenoArtifacts/RandomArtifactVisualizer.cs @@ -0,0 +1,29 @@ +using Content.Shared.Xenoarchaeology.XenoArtifacts; +using Robust.Client.GameObjects; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; + +namespace Content.Client.Xenoarchaeology.XenoArtifacts; + +public class RandomArtifactVisualizer : AppearanceVisualizer +{ + public override void OnChangeData(AppearanceComponent component) + { + base.OnChangeData(component); + + var entities = IoCManager.Resolve(); + if (!entities.TryGetComponent(component.Owner, out ISpriteComponent? sprite)) return; + + if (!component.TryGetData(SharedArtifactsVisuals.SpriteIndex, out int spriteIndex)) + return; + + if (!component.TryGetData(SharedArtifactsVisuals.IsActivated, out bool isActivated)) + isActivated = false; + + var spriteIndexStr = spriteIndex.ToString("D2"); + var spritePrefix = isActivated ? "_on" : ""; + + var spriteState = "ano" + spriteIndexStr + spritePrefix; + sprite.LayerSetState(0, spriteState); + } +} diff --git a/Content.Server/Xenoarchaeology/XenoArtifacts/ArtifactComponent.cs b/Content.Server/Xenoarchaeology/XenoArtifacts/ArtifactComponent.cs new file mode 100644 index 0000000000..8b5386a15c --- /dev/null +++ b/Content.Server/Xenoarchaeology/XenoArtifacts/ArtifactComponent.cs @@ -0,0 +1,37 @@ +using System; +using Robust.Shared.GameObjects; +using Robust.Shared.Serialization.Manager.Attributes; +using Robust.Shared.ViewVariables; + +namespace Content.Server.Xenoarchaeology.XenoArtifacts; + +[RegisterComponent] +public class ArtifactComponent : Component +{ + public override string Name => "Artifact"; + + /// + /// Should artifact pick a random trigger on startup? + /// + [DataField("randomTrigger")] + public bool RandomTrigger = true; + + /// + /// List of all possible triggers activations. + /// Should be same as components names. + /// + [DataField("possibleTriggers")] + public string[] PossibleTriggers = { + "ArtifactInteractionTrigger", + "ArtifactGasTrigger" + }; + + /// + /// Cooldown time between artifact activations (in seconds). + /// + [DataField("timer")] + [ViewVariables(VVAccess.ReadWrite)] + public double CooldownTime = 10; + + public TimeSpan LastActivationTime; +} diff --git a/Content.Server/Xenoarchaeology/XenoArtifacts/ArtifactSystem.cs b/Content.Server/Xenoarchaeology/XenoArtifacts/ArtifactSystem.cs new file mode 100644 index 0000000000..ca62871709 --- /dev/null +++ b/Content.Server/Xenoarchaeology/XenoArtifacts/ArtifactSystem.cs @@ -0,0 +1,70 @@ +using Content.Server.Xenoarchaeology.XenoArtifacts.Events; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Random; +using Robust.Shared.Timing; + +namespace Content.Server.Xenoarchaeology.XenoArtifacts; + +public class ArtifactSystem : EntitySystem +{ + [Dependency] private readonly IGameTiming _gameTiming = default!; + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly IComponentFactory _componentFactory = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnInit); + } + + private void OnInit(EntityUid uid, ArtifactComponent component, ComponentInit args) + { + if (component.RandomTrigger) + { + AddRandomTrigger(uid, component); + } + } + + public void AddRandomTrigger(EntityUid uid, ArtifactComponent? component = null) + { + if (!Resolve(uid, ref component)) + return; + + var triggerName = _random.Pick(component.PossibleTriggers); + var trigger = (Component) _componentFactory.GetComponent(triggerName); + trigger.Owner = uid; + + EntityManager.AddComponent(uid, trigger); + } + + public bool TryActivateArtifact(EntityUid uid, EntityUid? user = null, + ArtifactComponent? component = null) + { + if (!Resolve(uid, ref component)) + return false; + + // check if artifact isn't under cooldown + var timeDif = _gameTiming.CurTime - component.LastActivationTime; + if (timeDif.TotalSeconds < component.CooldownTime) + return false; + + ForceActivateArtifact(uid, user, component); + return true; + } + + public void ForceActivateArtifact(EntityUid uid, EntityUid? user = null, + ArtifactComponent? component = null) + { + if (!Resolve(uid, ref component)) + return; + + component.LastActivationTime = _gameTiming.CurTime; + + var ev = new ArtifactActivatedEvent() + { + Activator = user + }; + RaiseLocalEvent(uid, ev); + } +} diff --git a/Content.Server/Xenoarchaeology/XenoArtifacts/Effects/Components/SpawnArtifactComponent.cs b/Content.Server/Xenoarchaeology/XenoArtifacts/Effects/Components/SpawnArtifactComponent.cs new file mode 100644 index 0000000000..154759887a --- /dev/null +++ b/Content.Server/Xenoarchaeology/XenoArtifacts/Effects/Components/SpawnArtifactComponent.cs @@ -0,0 +1,37 @@ +using System.Collections.Generic; +using Robust.Shared.GameObjects; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.Manager.Attributes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; +using Robust.Shared.ViewVariables; + +namespace Content.Server.Xenoarchaeology.XenoArtifacts.Effects.Components; + +/// +/// When activated artifact will spawn an entity from prototype. +/// It could be an angry mob or some random item. +/// +[RegisterComponent] +public class SpawnArtifactComponent : Component +{ + public override string Name => "SpawnArtifact"; + + [DataField("random")] + public bool RandomPrototype = true; + + [DataField("possiblePrototypes", customTypeSerializer:typeof(PrototypeIdListSerializer))] + public List PossiblePrototypes = new(); + + [ViewVariables(VVAccess.ReadWrite)] + [DataField("prototype", customTypeSerializer:typeof(PrototypeIdSerializer))] + public string? Prototype; + + [DataField("range")] + public float Range = 0.5f; + + [DataField("maxSpawns")] + public int MaxSpawns = 20; + + public int SpawnsCount = 0; +} diff --git a/Content.Server/Xenoarchaeology/XenoArtifacts/Effects/Components/TelepathicArtifactComponent.cs b/Content.Server/Xenoarchaeology/XenoArtifacts/Effects/Components/TelepathicArtifactComponent.cs new file mode 100644 index 0000000000..00ecdd9790 --- /dev/null +++ b/Content.Server/Xenoarchaeology/XenoArtifacts/Effects/Components/TelepathicArtifactComponent.cs @@ -0,0 +1,45 @@ +using Robust.Shared.GameObjects; +using Robust.Shared.Serialization.Manager.Attributes; +using Robust.Shared.ViewVariables; + +namespace Content.Server.Xenoarchaeology.XenoArtifacts.Effects.Components; + +/// +/// Harmless artifact that broadcast "thoughts" to players nearby. +/// Thoughts are shown as popups and unique for each player. +/// +[RegisterComponent] +public class TelepathicArtifactComponent : Component +{ + public override string Name => "TelepathicArtifact"; + + /// + /// Loc string ids of telepathic messages. + /// Will be randomly picked and shown to player. + /// + [DataField("messages")] + [ViewVariables(VVAccess.ReadWrite)] + public string[] Messages = default!; + + /// + /// Loc string ids of telepathic messages (spooky version). + /// Will be randomly picked and shown to player. + /// + [DataField("drastic")] + [ViewVariables(VVAccess.ReadWrite)] + public string[] DrasticMessages = default!; + + /// + /// Probability to pick drastic version of message. + /// + [DataField("drasticProb")] + [ViewVariables(VVAccess.ReadWrite)] + public float DrasticMessageProb = 0.2f; + + /// + /// Radius in which player can receive artifacts messages. + /// + [DataField("range")] + [ViewVariables(VVAccess.ReadWrite)] + public float Range = 10f; +} diff --git a/Content.Server/Xenoarchaeology/XenoArtifacts/Effects/Systems/SpawnArtifactSystem.cs b/Content.Server/Xenoarchaeology/XenoArtifacts/Effects/Systems/SpawnArtifactSystem.cs new file mode 100644 index 0000000000..9dc8559a23 --- /dev/null +++ b/Content.Server/Xenoarchaeology/XenoArtifacts/Effects/Systems/SpawnArtifactSystem.cs @@ -0,0 +1,67 @@ +using Content.Server.Clothing.Components; +using Content.Server.Xenoarchaeology.XenoArtifacts.Effects.Components; +using Content.Server.Xenoarchaeology.XenoArtifacts.Events; +using Content.Shared.Hands.Components; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Maths; +using Robust.Shared.Random; + +namespace Content.Server.Xenoarchaeology.XenoArtifacts.Effects.Systems; + +public class SpawnArtifactSystem : EntitySystem +{ + [Dependency] private readonly IRobustRandom _random = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnInit); + SubscribeLocalEvent(OnActivate); + } + private void OnInit(EntityUid uid, SpawnArtifactComponent component, ComponentInit args) + { + ChooseRandomPrototype(uid, component); + } + + private void OnActivate(EntityUid uid, SpawnArtifactComponent component, ArtifactActivatedEvent args) + { + if (component.Prototype == null) + return; + if (component.SpawnsCount >= component.MaxSpawns) + return; + + // select spawn position near artifact + var artifactCord = Transform(uid).Coordinates; + var dx = _random.NextFloat(-component.Range, component.Range); + var dy = _random.NextFloat(-component.Range, component.Range); + var spawnCord = artifactCord.Offset(new Vector2(dx, dy)); + + // spawn entity + var spawned = EntityManager.SpawnEntity(component.Prototype, spawnCord); + component.SpawnsCount++; + + // if there is an user - try to put spawned item in their hands + // doesn't work for spawners + if (args.Activator != null && + EntityManager.TryGetComponent(args.Activator.Value, out SharedHandsComponent? hands) && + EntityManager.HasComponent(spawned)) + { + hands.TryPutInAnyHand(spawned); + } + } + + private void ChooseRandomPrototype(EntityUid uid, SpawnArtifactComponent? component = null) + { + if (!Resolve(uid, ref component)) + return; + + if (!component.RandomPrototype) + return; + if (component.PossiblePrototypes.Count == 0) + return; + + var proto = _random.Pick(component.PossiblePrototypes); + component.Prototype = proto; + } +} diff --git a/Content.Server/Xenoarchaeology/XenoArtifacts/Effects/Systems/TelepathicArtifactSystem.cs b/Content.Server/Xenoarchaeology/XenoArtifacts/Effects/Systems/TelepathicArtifactSystem.cs new file mode 100644 index 0000000000..90736f6edc --- /dev/null +++ b/Content.Server/Xenoarchaeology/XenoArtifacts/Effects/Systems/TelepathicArtifactSystem.cs @@ -0,0 +1,46 @@ +using Content.Server.Xenoarchaeology.XenoArtifacts.Effects.Components; +using Content.Server.Xenoarchaeology.XenoArtifacts.Events; +using Content.Shared.Popups; +using Robust.Server.GameObjects; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Localization; +using Robust.Shared.Player; +using Robust.Shared.Random; + +namespace Content.Server.Xenoarchaeology.XenoArtifacts.Effects.Systems; + +public class TelepathicArtifactSystem : EntitySystem +{ + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly IEntityLookup _lookup = default!; + [Dependency] private readonly SharedPopupSystem _popupSystem = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnActivate); + } + + private void OnActivate(EntityUid uid, TelepathicArtifactComponent component, ArtifactActivatedEvent args) + { + // try to find victims nearby + var victims = _lookup.GetEntitiesInRange(uid, component.Range); + foreach (var victimUid in victims) + { + if (!EntityManager.HasComponent(victimUid)) + continue; + + // roll if msg should be usual or drastic + var isDrastic = _random.NextFloat() <= component.DrasticMessageProb; + var msgArr = isDrastic ? component.DrasticMessages : component.Messages; + + // pick a random message + var msgId = _random.Pick(msgArr); + var msg = Loc.GetString(msgId); + + // show it as a popup, but only for the victim + _popupSystem.PopupEntity(msg, victimUid, Filter.Entities(victimUid)); + } + } +} diff --git a/Content.Server/Xenoarchaeology/XenoArtifacts/Events/ArtifactActivatedEvent.cs b/Content.Server/Xenoarchaeology/XenoArtifacts/Events/ArtifactActivatedEvent.cs new file mode 100644 index 0000000000..32da8b5fde --- /dev/null +++ b/Content.Server/Xenoarchaeology/XenoArtifacts/Events/ArtifactActivatedEvent.cs @@ -0,0 +1,16 @@ +using Robust.Shared.GameObjects; + +namespace Content.Server.Xenoarchaeology.XenoArtifacts.Events; + +/// +/// Invokes when artifact was successfully activated. +/// Used to start attached effects. +/// +public class ArtifactActivatedEvent : EntityEventArgs +{ + /// + /// Entity that activate this artifact. + /// Usually player, but can also be another object. + /// + public EntityUid? Activator; +} diff --git a/Content.Server/Xenoarchaeology/XenoArtifacts/RandomArtifactSpriteComponent.cs b/Content.Server/Xenoarchaeology/XenoArtifacts/RandomArtifactSpriteComponent.cs new file mode 100644 index 0000000000..abacdeb76a --- /dev/null +++ b/Content.Server/Xenoarchaeology/XenoArtifacts/RandomArtifactSpriteComponent.cs @@ -0,0 +1,22 @@ +using System; +using Robust.Shared.GameObjects; +using Robust.Shared.Serialization.Manager.Attributes; + +namespace Content.Server.Xenoarchaeology.XenoArtifacts; + +[RegisterComponent] +public class RandomArtifactSpriteComponent : Component +{ + public override string Name => "RandomArtifactSprite"; + + [DataField("minSprite")] + public int MinSprite = 1; + + [DataField("maxSprite")] + public int MaxSprite = 14; + + [DataField("activationTime")] + public double ActivationTime = 2.0; + + public TimeSpan? ActivationStart; +} diff --git a/Content.Server/Xenoarchaeology/XenoArtifacts/RandomArtifactSpriteSystem.cs b/Content.Server/Xenoarchaeology/XenoArtifacts/RandomArtifactSpriteSystem.cs new file mode 100644 index 0000000000..4bbe2a3e67 --- /dev/null +++ b/Content.Server/Xenoarchaeology/XenoArtifacts/RandomArtifactSpriteSystem.cs @@ -0,0 +1,58 @@ +using System; +using Content.Server.Xenoarchaeology.XenoArtifacts.Events; +using Content.Shared.Xenoarchaeology.XenoArtifacts; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Random; +using Robust.Shared.Timing; + +namespace Content.Server.Xenoarchaeology.XenoArtifacts; + +public class RandomArtifactSpriteSystem : EntitySystem +{ + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly IGameTiming _time = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnInit); + SubscribeLocalEvent(OnActivated); + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + var query = EntityManager.EntityQuery(); + foreach (var (component, appearance) in query) + { + if (component.ActivationStart == null) + return; + + var timeDif = _time.CurTime - component.ActivationStart.Value; + if (timeDif.Seconds >= component.ActivationTime) + { + appearance.SetData(SharedArtifactsVisuals.IsActivated, false); + component.ActivationStart = null; + } + } + } + + private void OnInit(EntityUid uid, RandomArtifactSpriteComponent component, ComponentInit args) + { + if (!TryComp(uid, out AppearanceComponent? appearance)) + return; + + var randomSprite = _random.Next(component.MinSprite, component.MaxSprite + 1); + appearance.SetData(SharedArtifactsVisuals.SpriteIndex, randomSprite); + } + + private void OnActivated(EntityUid uid, RandomArtifactSpriteComponent component, ArtifactActivatedEvent args) + { + if (!TryComp(uid, out AppearanceComponent? appearance)) + return; + + appearance.SetData(SharedArtifactsVisuals.IsActivated, true); + component.ActivationStart = _time.CurTime; + } +} diff --git a/Content.Server/Xenoarchaeology/XenoArtifacts/Triggers/Components/ArtifactGasTriggerComponent.cs b/Content.Server/Xenoarchaeology/XenoArtifacts/Triggers/Components/ArtifactGasTriggerComponent.cs new file mode 100644 index 0000000000..3f1357d8c2 --- /dev/null +++ b/Content.Server/Xenoarchaeology/XenoArtifacts/Triggers/Components/ArtifactGasTriggerComponent.cs @@ -0,0 +1,41 @@ +using Content.Shared.Atmos; +using Robust.Shared.GameObjects; +using Robust.Shared.Serialization.Manager.Attributes; +using Robust.Shared.ViewVariables; + +namespace Content.Server.Xenoarchaeology.XenoArtifacts.Triggers.Components; + +/// +/// Activates artifact when it surrounded by certain gas. +/// +[RegisterComponent] +public class ArtifactGasTriggerComponent : Component +{ + public override string Name => "ArtifactGasTrigger"; + + /// + /// List of possible activation gases to pick on startup. + /// + [DataField("possibleGas")] + public Gas[] PossibleGases = + { + Gas.Oxygen, + Gas.Plasma, + Gas.Nitrogen, + Gas.CarbonDioxide + }; + + /// + /// Gas id that will activate artifact. + /// + [DataField("gas")] + [ViewVariables(VVAccess.ReadWrite)] + public Gas? ActivationGas; + + /// + /// How many moles of gas should be present in room to activate artifact. + /// + [DataField("moles")] + [ViewVariables(VVAccess.ReadWrite)] + public float ActivationMoles = Atmospherics.MolesCellStandard * 0.1f; +} diff --git a/Content.Server/Xenoarchaeology/XenoArtifacts/Triggers/Components/ArtifactInteractionTriggerComponent.cs b/Content.Server/Xenoarchaeology/XenoArtifacts/Triggers/Components/ArtifactInteractionTriggerComponent.cs new file mode 100644 index 0000000000..b75e86def3 --- /dev/null +++ b/Content.Server/Xenoarchaeology/XenoArtifacts/Triggers/Components/ArtifactInteractionTriggerComponent.cs @@ -0,0 +1,12 @@ +using Robust.Shared.GameObjects; + +namespace Content.Server.Xenoarchaeology.XenoArtifacts.Triggers.Components; + +/// +/// Activate artifact just by touching it. +/// +[RegisterComponent] +public class ArtifactInteractionTriggerComponent : Component +{ + public override string Name => "ArtifactInteractionTrigger"; +} diff --git a/Content.Server/Xenoarchaeology/XenoArtifacts/Triggers/Systems/ArtifactGasTriggerSystem.cs b/Content.Server/Xenoarchaeology/XenoArtifacts/Triggers/Systems/ArtifactGasTriggerSystem.cs new file mode 100644 index 0000000000..1cc7cd331f --- /dev/null +++ b/Content.Server/Xenoarchaeology/XenoArtifacts/Triggers/Systems/ArtifactGasTriggerSystem.cs @@ -0,0 +1,51 @@ +using Content.Server.Atmos.EntitySystems; +using Content.Server.Xenoarchaeology.XenoArtifacts.Triggers.Components; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Random; + +namespace Content.Server.Xenoarchaeology.XenoArtifacts.Triggers.Systems; + +public class ArtifactGasTriggerSystem : EntitySystem +{ + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!; + [Dependency] private readonly ArtifactSystem _artifactSystem = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnInit); + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + var query = EntityManager.EntityQuery(); + foreach (var (trigger, transform) in query) + { + if (trigger.ActivationGas == null) + return; + + var environment = _atmosphereSystem.GetTileMixture(transform.Coordinates, true); + if (environment == null) + return; + + // check if outside there is enough moles to activate artifact + var moles = environment.GetMoles(trigger.ActivationGas.Value); + if (moles < trigger.ActivationMoles) + return; + + _artifactSystem.TryActivateArtifact(trigger.Owner); + } + } + + private void OnInit(EntityUid uid, ArtifactGasTriggerComponent component, ComponentInit args) + { + if (component.ActivationGas == null) + { + var gas = _random.Pick(component.PossibleGases); + component.ActivationGas = gas; + } + } +} diff --git a/Content.Server/Xenoarchaeology/XenoArtifacts/Triggers/Systems/ArtifactInteractionTriggerSystem.cs b/Content.Server/Xenoarchaeology/XenoArtifacts/Triggers/Systems/ArtifactInteractionTriggerSystem.cs new file mode 100644 index 0000000000..1d51cbe097 --- /dev/null +++ b/Content.Server/Xenoarchaeology/XenoArtifacts/Triggers/Systems/ArtifactInteractionTriggerSystem.cs @@ -0,0 +1,29 @@ +using Content.Server.Xenoarchaeology.XenoArtifacts.Triggers.Components; +using Content.Shared.ActionBlocker; +using Content.Shared.Interaction; +using Content.Shared.Interaction.Helpers; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; + +namespace Content.Server.Xenoarchaeology.XenoArtifacts.Triggers.Systems; + +public class ArtifactInteractionTriggerSystem : EntitySystem +{ + [Dependency] private readonly ArtifactSystem _artifactSystem = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnInteract); + } + + private void OnInteract(EntityUid uid, ArtifactInteractionTriggerComponent component, InteractHandEvent args) + { + if (args.Handled) + return; + if (!args.InRangeUnobstructed()) + return; + + args.Handled = _artifactSystem.TryActivateArtifact(uid, args.User); + } +} diff --git a/Content.Shared/Xenoarchaeology/XenoArtifacts/SharedArtifact.cs b/Content.Shared/Xenoarchaeology/XenoArtifacts/SharedArtifact.cs new file mode 100644 index 0000000000..d10c4a325d --- /dev/null +++ b/Content.Shared/Xenoarchaeology/XenoArtifacts/SharedArtifact.cs @@ -0,0 +1,11 @@ +using System; +using Robust.Shared.Serialization; + +namespace Content.Shared.Xenoarchaeology.XenoArtifacts; + +[Serializable, NetSerializable] +public enum SharedArtifactsVisuals : byte +{ + SpriteIndex, + IsActivated +} diff --git a/Resources/Locale/en-US/xenoarchaeology/badfeeling-artifact.ftl b/Resources/Locale/en-US/xenoarchaeology/badfeeling-artifact.ftl new file mode 100644 index 0000000000..e3224af085 --- /dev/null +++ b/Resources/Locale/en-US/xenoarchaeology/badfeeling-artifact.ftl @@ -0,0 +1,22 @@ +badfeeling-artifact-1 = Something doesn't feel right. +badfeeling-artifact-2 = You get a strange feeling in your gut. +badfeeling-artifact-3 = Your instincts are trying to warn you about something. +badfeeling-artifact-4 = Someone just walked over your grave. +badfeeling-artifact-5 = There's a strange feeling in the air. +badfeeling-artifact-6 = There's a strange smell in the air. +badfeeling-artifact-7 = The tips of your fingers feel tingly. +badfeeling-artifact-8 = You feel witchy. +badfeeling-artifact-9 = You have a terrible sense of foreboding. +badfeeling-artifact-10 = You've got a bad feeling about this. +badfeeling-artifact-11 = Your scalp prickles. +badfeeling-artifact-12 = The light seems to flicker. +badfeeling-artifact-13 = The shadows seem to lengthen. +badfeeling-artifact-14 = The walls are getting closer. +badfeeling-artifact-15 = Something is wrong. + +badfeeling-artifact-drastic-1 = Someone's trying to kill you! +badfeeling-artifact-drastic-2 = There's something out there! +badfeeling-artifact-drastic-3 = What's happening to you? +badfeeling-artifact-drastic-4 = OH GOD! +badfeeling-artifact-drastic-5 = HELP ME! +badfeeling-artifact-drastic-6 = You've got to get out of here! diff --git a/Resources/Locale/en-US/xenoarchaeology/goodfeeling-artifact.ftl b/Resources/Locale/en-US/xenoarchaeology/goodfeeling-artifact.ftl new file mode 100644 index 0000000000..007138c00b --- /dev/null +++ b/Resources/Locale/en-US/xenoarchaeology/goodfeeling-artifact.ftl @@ -0,0 +1,21 @@ +goodfeeling-artifact-1 = You feel good. +goodfeeling-artifact-2 = Everything seems to be going alright +goodfeeling-artifact-3 = You've got a good feeling about this +goodfeeling-artifact-4 = Your instincts tell you everything is going to be getting better. +goodfeeling-artifact-5 = There's a good feeling in the air. +goodfeeling-artifact-6 = Something smells... good. +goodfeeling-artifact-7 = The tips of your fingers feel tingly. +goodfeeling-artifact-8 = You've got a good feeling about this. +goodfeeling-artifact-9 = You feel happy. +goodfeeling-artifact-10 = ou fight the urge to smile. +goodfeeling-artifact-11 = Your scalp prickles. +goodfeeling-artifact-12 = All the colours seem a bit more vibrant. +goodfeeling-artifact-13 = Everything seems a little lighter. +goodfeeling-artifact-14 = The troubles of the world seem to fade away. + +goodfeeling-artifact-drastic-1 = You want to hug everyone you meet! +goodfeeling-artifact-drastic-2 = Everything is going so well! +goodfeeling-artifact-drastic-3 = You feel euphoric. +goodfeeling-artifact-drastic-4 = You feel giddy. +goodfeeling-artifact-drastic-5 = You're so happy suddenly you almost want to dance and sing. +goodfeeling-artifact-drastic-6 = You feel like the world is out to help you. diff --git a/Resources/Prototypes/Entities/Markers/Spawners/Random/artifacts.yml b/Resources/Prototypes/Entities/Markers/Spawners/Random/artifacts.yml new file mode 100644 index 0000000000..97a4149946 --- /dev/null +++ b/Resources/Prototypes/Entities/Markers/Spawners/Random/artifacts.yml @@ -0,0 +1,25 @@ +- type: entity + id: RandomArtifactSpawner + name: random artifact spawner + parent: MarkerBase + components: + - type: Sprite + layers: + - state: red + - texture: Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano01.png + - type: RandomSpawner + prototypes: + - BadfeelingArtifact + - GoodfeelingArtifact + - AngryMobsSpawnArtifact + - JunkSpawnArtifact + - BananaSpawnArtifact + chance: 1 + +- type: entity + id: RandomArtifactSpawner20 + name: random artifact spawner [20] + parent: RandomArtifactSpawner + components: + - type: RandomSpawner + chance: 0.2 diff --git a/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/artifacts.yml b/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/artifacts.yml new file mode 100644 index 0000000000..75ea5de5da --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/artifacts.yml @@ -0,0 +1,124 @@ +- type: entity + parent: BaseStructureDynamic + id: BaseXenoArtifact + name: alien artifact + description: A strange alien device. + abstract: true + components: + - type: Sprite + sprite: Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi + netsync: false + state: ano01 + - type: Physics + bodyType: Dynamic + - type: Fixtures + fixtures: + - shape: + !type:PhysShapeCircle + radius: 0.45 + mass: 150 + layer: + - SmallImpassable + mask: + - VaultImpassable + - type: InteractionOutline + - type: Artifact + - type: RandomArtifactSprite + - type: Appearance + visuals: + - type: RandomArtifactVisualizer + +# Telepathic +- type: entity + parent: BaseXenoArtifact + id: BadfeelingArtifact + suffix: Badfeeling + components: + - type: TelepathicArtifact + messages: + - badfeeling-artifact-1 + - badfeeling-artifact-2 + - badfeeling-artifact-3 + - badfeeling-artifact-4 + - badfeeling-artifact-5 + - badfeeling-artifact-6 + - badfeeling-artifact-7 + - badfeeling-artifact-8 + - badfeeling-artifact-9 + - badfeeling-artifact-10 + - badfeeling-artifact-11 + - badfeeling-artifact-12 + - badfeeling-artifact-13 + - badfeeling-artifact-14 + - badfeeling-artifact-15 + drastic: + - badfeeling-artifact-drastic-1 + - badfeeling-artifact-drastic-2 + - badfeeling-artifact-drastic-3 + - badfeeling-artifact-drastic-4 + - badfeeling-artifact-drastic-5 + - badfeeling-artifact-drastic-6 + +- type: entity + parent: BaseXenoArtifact + id: GoodfeelingArtifact + suffix: Goodfeeling + components: + - type: TelepathicArtifact + messages: + - goodfeeling-artifact-1 + - goodfeeling-artifact-2 + - goodfeeling-artifact-3 + - goodfeeling-artifact-4 + - goodfeeling-artifact-5 + - goodfeeling-artifact-6 + - goodfeeling-artifact-7 + - goodfeeling-artifact-8 + - goodfeeling-artifact-9 + - goodfeeling-artifact-10 + - goodfeeling-artifact-11 + - goodfeeling-artifact-12 + - goodfeeling-artifact-13 + - goodfeeling-artifact-14 + drastic: + - goodfeeling-artifact-drastic-1 + - goodfeeling-artifact-drastic-2 + - goodfeeling-artifact-drastic-3 + - goodfeeling-artifact-drastic-4 + - goodfeeling-artifact-drastic-5 + - goodfeeling-artifact-drastic-6 + +# Spawners +- type: entity + parent: BaseXenoArtifact + id: AngryMobsSpawnArtifact + suffix: Angry Mobs Spawn + components: + - type: SpawnArtifact + maxSpawns: 5 + possiblePrototypes: + - MobCarpHolo + - MobCarpMagic + +- type: entity + parent: BaseXenoArtifact + id: JunkSpawnArtifact + suffix: Junk Spawn + components: + - type: SpawnArtifact + maxSpawns: 10 + possiblePrototypes: + - FoodPacketSyndiTrash + - FoodPacketSemkiTrash + - RandomInstruments + - ToySpawner + +- type: entity + parent: BaseXenoArtifact + id: BananaSpawnArtifact + suffix: Banana Spawn + components: + - type: SpawnArtifact + maxSpawns: 20 + possiblePrototypes: + - FoodBanana diff --git a/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano01.png b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano01.png new file mode 100644 index 0000000000..76514f26c7 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano01.png differ diff --git a/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano01_on.png b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano01_on.png new file mode 100644 index 0000000000..f63b7c469e Binary files /dev/null and b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano01_on.png differ diff --git a/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano02.png b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano02.png new file mode 100644 index 0000000000..1714be79af Binary files /dev/null and b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano02.png differ diff --git a/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano02_on.png b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano02_on.png new file mode 100644 index 0000000000..3ed39d9da2 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano02_on.png differ diff --git a/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano03.png b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano03.png new file mode 100644 index 0000000000..b0d652a679 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano03.png differ diff --git a/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano03_on.png b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano03_on.png new file mode 100644 index 0000000000..2334c50393 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano03_on.png differ diff --git a/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano04.png b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano04.png new file mode 100644 index 0000000000..9765a1e9d4 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano04.png differ diff --git a/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano04_on.png b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano04_on.png new file mode 100644 index 0000000000..320e12ed47 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano04_on.png differ diff --git a/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano05.png b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano05.png new file mode 100644 index 0000000000..d16546ebe3 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano05.png differ diff --git a/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano05_on.png b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano05_on.png new file mode 100644 index 0000000000..5e2b6c6d10 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano05_on.png differ diff --git a/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano06.png b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano06.png new file mode 100644 index 0000000000..eab50e8aac Binary files /dev/null and b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano06.png differ diff --git a/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano06_on.png b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano06_on.png new file mode 100644 index 0000000000..a8c64f6d44 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano06_on.png differ diff --git a/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano07.png b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano07.png new file mode 100644 index 0000000000..a4f78182d5 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano07.png differ diff --git a/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano07_on.png b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano07_on.png new file mode 100644 index 0000000000..4853e41b99 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano07_on.png differ diff --git a/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano08.png b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano08.png new file mode 100644 index 0000000000..e935560950 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano08.png differ diff --git a/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano08_on.png b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano08_on.png new file mode 100644 index 0000000000..820bc0046f Binary files /dev/null and b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano08_on.png differ diff --git a/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano09.png b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano09.png new file mode 100644 index 0000000000..0911c00c70 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano09.png differ diff --git a/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano09_on.png b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano09_on.png new file mode 100644 index 0000000000..b5bb79d852 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano09_on.png differ diff --git a/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano10.png b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano10.png new file mode 100644 index 0000000000..c8eb09eb55 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano10.png differ diff --git a/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano10_on.png b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano10_on.png new file mode 100644 index 0000000000..7d0b0d8389 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano10_on.png differ diff --git a/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano11.png b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano11.png new file mode 100644 index 0000000000..117b64c646 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano11.png differ diff --git a/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano11_on.png b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano11_on.png new file mode 100644 index 0000000000..888d95fb35 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano11_on.png differ diff --git a/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano12.png b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano12.png new file mode 100644 index 0000000000..c066c39b07 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano12.png differ diff --git a/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano12_on.png b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano12_on.png new file mode 100644 index 0000000000..554cdc21a0 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano12_on.png differ diff --git a/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano13.png b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano13.png new file mode 100644 index 0000000000..2ba6990a26 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano13.png differ diff --git a/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano13_on.png b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano13_on.png new file mode 100644 index 0000000000..98cd3db05b Binary files /dev/null and b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano13_on.png differ diff --git a/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano14.png b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano14.png new file mode 100644 index 0000000000..e6ae176de8 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano14.png differ diff --git a/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano14_on.png b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano14_on.png new file mode 100644 index 0000000000..cf60bc2204 Binary files /dev/null and b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/ano14_on.png differ diff --git a/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/meta.json b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/meta.json new file mode 100644 index 0000000000..fda4b97b5a --- /dev/null +++ b/Resources/Textures/Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi/meta.json @@ -0,0 +1,245 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from baystation at commit https://github.com/Baystation12/Baystation12/commit/a929584d9db319eb7484113221be25cfa1d5dc09", + "states": [ + { + "name": "ano01" + }, + { + "name": "ano01_on", + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "ano02" + }, + { + "name": "ano02_on", + "delays": [ + [ + 0.3, + 0.2, + 0.1 + ] + ] + }, + { + "name": "ano03" + }, + { + "name": "ano03_on", + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "ano04" + }, + { + "name": "ano04_on", + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "ano05" + }, + { + "name": "ano05_on", + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "ano06" + }, + { + "name": "ano06_on", + "delays": [ + [ + 0.5, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "ano07" + }, + { + "name": "ano07_on", + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "ano08" + }, + { + "name": "ano08_on", + "delays": [ + [ + 0.3, + 0.2, + 0.2, + 0.1, + 0.1 + ] + ] + }, + { + "name": "ano09" + }, + { + "name": "ano09_on", + "delays": [ + [ + 0.3, + 0.3, + 0.3, + 0.3 + ] + ] + }, + { + "name": "ano10" + }, + { + "name": "ano10_on", + "delays": [ + [ + 1.0, + 0.2, + 0.1, + 0.2, + 0.2, + 0.2 + ] + ] + }, + { + "name": "ano11" + }, + { + "name": "ano11_on" + }, + { + "name": "ano12" + }, + { + "name": "ano12_on", + "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 + ] + ] + }, + { + "name": "ano13" + }, + { + "name": "ano13_on", + "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 + ] + ] + }, + { + "name": "ano14" + }, + { + "name": "ano14_on", + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + } + ] +} \ No newline at end of file diff --git a/SpaceStation14.sln.DotSettings b/SpaceStation14.sln.DotSettings index da231d591f..9db578f9af 100644 --- a/SpaceStation14.sln.DotSettings +++ b/SpaceStation14.sln.DotSettings @@ -301,5 +301,6 @@ True True True + True True True