Item artifacts (#12652)
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user