Item artifacts (#12652)

This commit is contained in:
Kara
2022-11-17 11:40:05 -06:00
committed by GitHub
parent 29224f166c
commit eaa7c0dd36
43 changed files with 690 additions and 104 deletions

View File

@@ -0,0 +1,51 @@
using System.Linq;
using Content.Server.Administration;
using Content.Shared.Administration;
using Content.Shared.Xenoarchaeology.XenoArtifacts;
using Robust.Shared.Console;
using Robust.Shared.Utility;
namespace Content.Server.Xenoarchaeology.XenoArtifacts;
public partial class ArtifactSystem
{
[Dependency] private readonly IConsoleHost _conHost = default!;
public void InitializeCommands()
{
_conHost.RegisterCommand("forceartifactnode", "Forces an artifact to traverse to a given node", "forceartifacteffect <uid> <node ID>",
ForceArtifactNode,
ForceArtifactNodeCompletions);
}
[AdminCommand(AdminFlags.Fun)]
private void ForceArtifactNode(IConsoleShell shell, string argstr, string[] args)
{
if (args.Length != 2)
shell.WriteError("Argument length must be 2");
if (!EntityUid.TryParse(args[0], out var uid) || ! int.TryParse(args[1], out var id))
return;
if (!TryComp<ArtifactComponent>(uid, out var artifact) || artifact.NodeTree == null)
return;
if (artifact.NodeTree.AllNodes.FirstOrDefault(n => n.Id == id) is { } node)
{
EnterNode(uid, ref node);
}
}
private CompletionResult ForceArtifactNodeCompletions(IConsoleShell shell, string[] args)
{
if (args.Length == 2 && EntityUid.TryParse(args[0], out var uid))
{
if (TryComp<ArtifactComponent>(uid, out var artifact) && artifact.NodeTree != null)
{
return CompletionResult.FromHintOptions(artifact.NodeTree.AllNodes.Select(s => s.Id.ToString()), "<node id>");
}
}
return CompletionResult.Empty;
}
}

View File

@@ -1,5 +1,6 @@
using System.Linq;
using Content.Server.Xenoarchaeology.XenoArtifacts.Events;
using Content.Shared.Item;
using Content.Shared.Xenoarchaeology.XenoArtifacts;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
@@ -20,7 +21,7 @@ public sealed partial class ArtifactSystem
/// </summary>
/// <param name="tree">The tree being generated.</param>
/// <param name="nodeAmount">The amount of nodes it has.</param>
private void GenerateArtifactNodeTree(ref ArtifactTree tree, int nodeAmount)
private void GenerateArtifactNodeTree(EntityUid artifact, ref ArtifactTree tree, int nodeAmount)
{
if (nodeAmount < 1)
{
@@ -33,14 +34,14 @@ public sealed partial class ArtifactSystem
while (uninitializedNodes.Any())
{
GenerateNode(ref uninitializedNodes, ref tree, nodeAmount);
GenerateNode(artifact, ref uninitializedNodes, ref tree, nodeAmount);
}
}
/// <summary>
/// Generate an individual node on the tree.
/// </summary>
private void GenerateNode(ref List<ArtifactNode> uninitializedNodes, ref ArtifactTree tree, int targetNodeAmount)
private void GenerateNode(EntityUid artifact, ref List<ArtifactNode> uninitializedNodes, ref ArtifactTree tree, int targetNodeAmount)
{
if (!uninitializedNodes.Any())
return;
@@ -69,8 +70,8 @@ public sealed partial class ArtifactSystem
uninitializedNodes.Add(neighbor);
}
node.Trigger = GetRandomTrigger(ref node);
node.Effect = GetRandomEffect(ref node);
node.Trigger = GetRandomTrigger(artifact, ref node);
node.Effect = GetRandomEffect(artifact, ref node);
tree.AllNodes.Add(node);
}
@@ -78,28 +79,31 @@ public sealed partial class ArtifactSystem
//yeah these two functions are near duplicates but i don't
//want to implement an interface or abstract parent
private ArtifactTriggerPrototype GetRandomTrigger(ref ArtifactNode node)
private ArtifactTriggerPrototype GetRandomTrigger(EntityUid artifact, ref ArtifactNode node)
{
var allTriggers = _prototype.EnumeratePrototypes<ArtifactTriggerPrototype>().ToList();
var validDepth = allTriggers.Select(x => x.TargetDepth).Distinct().ToList();
var weights = GetDepthWeights(validDepth, node.Depth);
var selectedRandomTargetDepth = GetRandomTargetDepth(weights);
var targetTriggers = allTriggers.Where(x =>
x.TargetDepth == selectedRandomTargetDepth).ToList();
var targetTriggers = allTriggers
.Where(x => x.TargetDepth == selectedRandomTargetDepth)
.Where(x => (x.Whitelist?.IsValid(artifact, EntityManager) ?? true) && (!x.Blacklist?.IsValid(artifact, EntityManager) ?? true)).ToList();
return _random.Pick(targetTriggers);
}
private ArtifactEffectPrototype GetRandomEffect(ref ArtifactNode node)
private ArtifactEffectPrototype GetRandomEffect(EntityUid artifact, ref ArtifactNode node)
{
var allEffects = _prototype.EnumeratePrototypes<ArtifactEffectPrototype>().ToList();
var validDepth = allEffects.Select(x => x.TargetDepth).Distinct().ToList();
var weights = GetDepthWeights(validDepth, node.Depth);
var selectedRandomTargetDepth = GetRandomTargetDepth(weights);
var targetEffects = allEffects.Where(x =>
x.TargetDepth == selectedRandomTargetDepth).ToList();
var targetEffects = allEffects
.Where(x => x.TargetDepth == selectedRandomTargetDepth)
.Where(x => (x.Whitelist?.IsValid(artifact, EntityManager) ?? true) && (!x.Blacklist?.IsValid(artifact, EntityManager) ?? true)).ToList();
return _random.Pick(targetEffects);
}
@@ -164,11 +168,22 @@ public sealed partial class ArtifactSystem
foreach (var (name, entry) in allComponents)
{
var reg = _componentFactory.GetRegistration(name);
if (EntityManager.HasComponent(uid, reg.Type))
{
// Don't re-add permanent components
if (node.Effect.PermanentComponents.ContainsKey(name))
continue;
EntityManager.RemoveComponent(uid, reg.Type);
}
var comp = (Component) _componentFactory.GetComponent(reg);
comp.Owner = uid;
var temp = (object) comp;
_serialization.Copy(entry.Component, ref temp);
EntityManager.AddComponent(uid, (Component) temp!, true);
}

View File

@@ -22,6 +22,8 @@ public sealed partial class ArtifactSystem : EntitySystem
SubscribeLocalEvent<ArtifactComponent, MapInitEvent>(OnInit);
SubscribeLocalEvent<ArtifactComponent, PriceCalculationEvent>(GetPrice);
InitializeCommands();
}
private void OnInit(EntityUid uid, ArtifactComponent component, MapInitEvent args)
@@ -105,7 +107,7 @@ public sealed partial class ArtifactSystem : EntitySystem
component.NodeTree = new ArtifactTree();
GenerateArtifactNodeTree(ref component.NodeTree, nodeAmount);
GenerateArtifactNodeTree(component.Owner, ref component.NodeTree, nodeAmount);
EnterNode(component.Owner, ref component.NodeTree.StartNode, component);
}

View File

@@ -44,7 +44,7 @@ public sealed class SpawnArtifactSystem : EntitySystem
toSpawn = _random.Pick(component.PossiblePrototypes);
// select spawn position near artifact
var artifactCord = Transform(uid).Coordinates;
var artifactCord = Transform(uid).MapPosition;
var dx = _random.NextFloat(-component.Range, component.Range);
var dy = _random.NextFloat(-component.Range, component.Range);
var spawnCord = artifactCord.Offset(new Vector2(dx, dy));

View File

@@ -1,16 +0,0 @@
namespace Content.Server.Xenoarchaeology.XenoArtifacts;
[RegisterComponent]
public sealed class RandomArtifactSpriteComponent : Component
{
[DataField("minSprite")]
public int MinSprite = 1;
[DataField("maxSprite")]
public int MaxSprite = 14;
[DataField("activationTime")]
public double ActivationTime = 2.0;
public TimeSpan? ActivationStart;
}

View File

@@ -0,0 +1,9 @@
namespace Content.Server.Xenoarchaeology.XenoArtifacts.Triggers.Components;
/// <summary>
/// Triggers when the artifact lands after being thrown.
/// </summary>
[RegisterComponent]
public sealed class ArtifactLandTriggerComponent : Component
{
}

View File

@@ -0,0 +1,9 @@
namespace Content.Server.Xenoarchaeology.XenoArtifacts.Triggers.Components;
/// <summary>
/// Triggers when an item artifact is microwaved.
/// </summary>
[RegisterComponent]
public sealed class ArtifactMicrowaveTriggerComponent : Component
{
}

View File

@@ -0,0 +1,21 @@
using Content.Server.Xenoarchaeology.XenoArtifacts.Triggers.Components;
using Content.Shared.Throwing;
namespace Content.Server.Xenoarchaeology.XenoArtifacts.Triggers.Systems;
public sealed class ArtifactLandSystem : EntitySystem
{
[Dependency] private readonly ArtifactSystem _artifact = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<ArtifactLandTriggerComponent, LandEvent>(OnLand);
}
private void OnLand(EntityUid uid, ArtifactLandTriggerComponent component, LandEvent args)
{
_artifact.TryActivateArtifact(uid, args.User);
}
}

View File

@@ -0,0 +1,20 @@
using Content.Server.Kitchen.Components;
using Content.Server.Xenoarchaeology.XenoArtifacts.Triggers.Components;
namespace Content.Server.Xenoarchaeology.XenoArtifacts.Triggers.Systems;
public sealed class ArtifactMicrowaveTriggerSystem : EntitySystem
{
[Dependency] private readonly ArtifactSystem _artifact = default!;
/// <inheritdoc/>
public override void Initialize()
{
SubscribeLocalEvent<ArtifactMicrowaveTriggerComponent, BeingMicrowavedEvent>(OnMicrowaved);
}
private void OnMicrowaved(EntityUid uid, ArtifactMicrowaveTriggerComponent component, BeingMicrowavedEvent args)
{
_artifact.TryActivateArtifact(uid);
}
}