From 6ba1b4d8b313eda9e5ff82246ed7425e80287d0f Mon Sep 17 00:00:00 2001 From: TheGrimbeeper Date: Mon, 23 Dec 2024 22:04:34 +1100 Subject: [PATCH 1/3] New artifact effectr: animate nearby items (like a revenant) --- .../EntitySystems/RevenantAnimatedSystem.cs | 4 +- .../Components/AnimateArtifactComponent.cs | 26 ++++++++++ .../Effects/Systems/AnimateArtifactSystem.cs | 51 +++++++++++++++++++ .../Systems/KnockdownArtifactSystem.cs | 4 -- .../XenoArch/Effects/normal_effects.yml | 11 ++++ 5 files changed, 91 insertions(+), 5 deletions(-) create mode 100644 Content.Server/_Impstation/Xenoarchaeology/XenoArtifacts/Effects/Components/AnimateArtifactComponent.cs create mode 100644 Content.Server/_Impstation/Xenoarchaeology/XenoArtifacts/Effects/Systems/AnimateArtifactSystem.cs diff --git a/Content.Server/_Impstation/Revenant/EntitySystems/RevenantAnimatedSystem.cs b/Content.Server/_Impstation/Revenant/EntitySystems/RevenantAnimatedSystem.cs index a4c50677024b46..3b98e24d03a1fd 100644 --- a/Content.Server/_Impstation/Revenant/EntitySystems/RevenantAnimatedSystem.cs +++ b/Content.Server/_Impstation/Revenant/EntitySystems/RevenantAnimatedSystem.cs @@ -25,6 +25,7 @@ using Content.Shared.Mobs.Systems; using Content.Shared.Mobs; using Robust.Shared.Timing; +using Content.Shared.Construction.Components; namespace Content.Server.Revenant.EntitySystems; @@ -176,7 +177,8 @@ private void OnMobStateChange(Entity ent, ref MobStat public bool CanAnimateObject(EntityUid target) { - return !(HasComp(target) || HasComp(target) || HasComp(target)); + return !(HasComp(target) || HasComp(target) + || HasComp(target) || HasComp(target)); } public bool TryAnimateObject(EntityUid target, TimeSpan? duration = null, Entity? revenant = null) diff --git a/Content.Server/_Impstation/Xenoarchaeology/XenoArtifacts/Effects/Components/AnimateArtifactComponent.cs b/Content.Server/_Impstation/Xenoarchaeology/XenoArtifacts/Effects/Components/AnimateArtifactComponent.cs new file mode 100644 index 00000000000000..a32a74296ca839 --- /dev/null +++ b/Content.Server/_Impstation/Xenoarchaeology/XenoArtifacts/Effects/Components/AnimateArtifactComponent.cs @@ -0,0 +1,26 @@ +namespace Content.Server.Xenoarchaeology.XenoArtifacts.Effects.Components; + +/// +/// Animates a number of entities within a range for a duration. Animated objects attack nearby beings. +/// +[RegisterComponent] +public sealed partial class AnimateArtifactComponent : Component +{ + /// + /// Distance from the artifact to animate objects + /// + [DataField("range"), ViewVariables(VVAccess.ReadWrite)] + public float Range = 6f; + + /// + /// Duration of the animation. + /// + [DataField("duration"), ViewVariables(VVAccess.ReadWrite)] + public float Duration = 15f; + + /// + /// Number of objects to animate + /// + [DataField("count"), ViewVariables(VVAccess.ReadWrite)] + public int Count = 1; +} diff --git a/Content.Server/_Impstation/Xenoarchaeology/XenoArtifacts/Effects/Systems/AnimateArtifactSystem.cs b/Content.Server/_Impstation/Xenoarchaeology/XenoArtifacts/Effects/Systems/AnimateArtifactSystem.cs new file mode 100644 index 00000000000000..88471759dc5342 --- /dev/null +++ b/Content.Server/_Impstation/Xenoarchaeology/XenoArtifacts/Effects/Systems/AnimateArtifactSystem.cs @@ -0,0 +1,51 @@ +using Content.Server.Xenoarchaeology.XenoArtifacts.Effects.Components; +using Content.Server.Xenoarchaeology.XenoArtifacts.Events; +using Content.Server.Revenant.EntitySystems; +using Content.Shared.Item; +using System.Linq; +using Robust.Shared.Random; +using Robust.Shared.Containers; + +namespace Content.Server.Xenoarchaeology.XenoArtifacts.Effects.Systems; + +public sealed class AnimateArtifactSystem : EntitySystem +{ + [Dependency] private readonly EntityLookupSystem _lookup = default!; + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly RevenantAnimatedSystem _revenantAnimated = default!; + [Dependency] private readonly SharedContainerSystem _container = default!; + + + /// + public override void Initialize() + { + SubscribeLocalEvent(OnActivated); + } + + private void OnActivated(EntityUid uid, AnimateArtifactComponent component, ArtifactActivatedEvent args) + { + // Get a list of all nearby objects in range + + HashSet entsHash = _lookup.GetEntitiesInRange(uid, component.Range); + var numSuccessfulAnimates = 0; + + var unshuffledEnts = entsHash.ToList(); + var ents = unshuffledEnts.OrderBy(_ => _random.Next()).ToList(); + + foreach (var ent in ents) + { + if (numSuccessfulAnimates >= component.Count) + { + break; + } + // need to only get items not in a container + if (HasComp(ent) && _revenantAnimated.CanAnimateObject(ent) && !_container.IsEntityInContainer(ent)) + { + if (_revenantAnimated.TryAnimateObject(ent, TimeSpan.FromSeconds(component.Duration))) + { + numSuccessfulAnimates += 1; + } + } + } + } +} diff --git a/Content.Server/_Impstation/Xenoarchaeology/XenoArtifacts/Effects/Systems/KnockdownArtifactSystem.cs b/Content.Server/_Impstation/Xenoarchaeology/XenoArtifacts/Effects/Systems/KnockdownArtifactSystem.cs index 14bf412e187611..eba2ef50dff49c 100644 --- a/Content.Server/_Impstation/Xenoarchaeology/XenoArtifacts/Effects/Systems/KnockdownArtifactSystem.cs +++ b/Content.Server/_Impstation/Xenoarchaeology/XenoArtifacts/Effects/Systems/KnockdownArtifactSystem.cs @@ -1,10 +1,6 @@ using Content.Server.Xenoarchaeology.XenoArtifacts.Effects.Components; using Content.Shared.Buckle.Components; using Content.Server.Xenoarchaeology.XenoArtifacts.Events; -using Content.Shared.Maps; -using Content.Shared.Throwing; -using Robust.Server.GameObjects; -using Robust.Shared.Random; using Content.Shared.StatusEffect; using Content.Server.Stunnable; diff --git a/Resources/Prototypes/XenoArch/Effects/normal_effects.yml b/Resources/Prototypes/XenoArch/Effects/normal_effects.yml index 9f36820f49ccf5..f1b23279a03374 100644 --- a/Resources/Prototypes/XenoArch/Effects/normal_effects.yml +++ b/Resources/Prototypes/XenoArch/Effects/normal_effects.yml @@ -1070,6 +1070,17 @@ knockdownTime: 2.5 range: 15 +- type: artifactEffect + id: EffectAnimateSingle + targetDepth: 4 + effectHint: artifact-effect-hint-sentience + effectProb: 10000 + components: + - type: AnimateArtifact + range: 6 + duration: 10 + count: 1 + - type: artifactEffect id: EffectSingulo targetDepth: 10 From 847cccfaca515dfacd50af392a3ddffa35b043c5 Mon Sep 17 00:00:00 2001 From: TheGrimbeeper Date: Mon, 23 Dec 2024 22:13:59 +1100 Subject: [PATCH 2/3] nearly forgot to reduce the test probability --- Resources/Prototypes/XenoArch/Effects/normal_effects.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Prototypes/XenoArch/Effects/normal_effects.yml b/Resources/Prototypes/XenoArch/Effects/normal_effects.yml index f1b23279a03374..87ded0225ce13e 100644 --- a/Resources/Prototypes/XenoArch/Effects/normal_effects.yml +++ b/Resources/Prototypes/XenoArch/Effects/normal_effects.yml @@ -1074,7 +1074,7 @@ id: EffectAnimateSingle targetDepth: 4 effectHint: artifact-effect-hint-sentience - effectProb: 10000 + effectProb: 0.5 components: - type: AnimateArtifact range: 6 From dfa73db9033628e3fee25f9f0649efe7ef6ee1f3 Mon Sep 17 00:00:00 2001 From: TheGrimbeeper Date: Tue, 24 Dec 2024 09:48:32 +1100 Subject: [PATCH 3/3] Allow handheld artifacts to animate themselves --- .../XenoArtifacts/Effects/Systems/AnimateArtifactSystem.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Content.Server/_Impstation/Xenoarchaeology/XenoArtifacts/Effects/Systems/AnimateArtifactSystem.cs b/Content.Server/_Impstation/Xenoarchaeology/XenoArtifacts/Effects/Systems/AnimateArtifactSystem.cs index 88471759dc5342..c1efb97fea9da3 100644 --- a/Content.Server/_Impstation/Xenoarchaeology/XenoArtifacts/Effects/Systems/AnimateArtifactSystem.cs +++ b/Content.Server/_Impstation/Xenoarchaeology/XenoArtifacts/Effects/Systems/AnimateArtifactSystem.cs @@ -26,7 +26,8 @@ private void OnActivated(EntityUid uid, AnimateArtifactComponent component, Arti { // Get a list of all nearby objects in range - HashSet entsHash = _lookup.GetEntitiesInRange(uid, component.Range); + var entsHash = _lookup.GetEntitiesInRange(uid, component.Range); + entsHash.Add(uid); var numSuccessfulAnimates = 0; var unshuffledEnts = entsHash.ToList();