Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3mo xeno archeology (first phase) #33370

Open
wants to merge 96 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
eba8da7
DAG Adjacency Matrix & Tests
EmoGarbage404 Jun 17, 2024
152d8d5
Merge branch 'master' of https://github.com/space-wizards/space-stati…
EmoGarbage404 Jun 17, 2024
c7e209a
Fix sandbox type errors
EmoGarbage404 Jun 17, 2024
d2e8d72
First pass on procgen
EmoGarbage404 Jun 18, 2024
5aa453b
Procgen adjustments
EmoGarbage404 Jun 19, 2024
2befbd0
Networking
EmoGarbage404 Jun 19, 2024
33c5775
Cruft and god and beauty and analysis console
EmoGarbage404 Jun 19, 2024
ad6e686
convert to data types that dont make me want to kill myself
EmoGarbage404 Jun 20, 2024
d6d9965
starting work on console UI
EmoGarbage404 Jun 21, 2024
1371613
drawing nodes n shit
EmoGarbage404 Jun 22, 2024
5dae996
damn that ui FUCKS
EmoGarbage404 Jun 23, 2024
e3cea19
XAT
EmoGarbage404 Jun 23, 2024
e833ba9
Add a bunch of basic triggers
EmoGarbage404 Jun 28, 2024
95de7f5
Fix trigger gen
EmoGarbage404 Jun 28, 2024
99b97c0
Add node info into the analysis console UI
EmoGarbage404 Jun 29, 2024
0dce0b0
Merge branch 'master' of https://github.com/space-wizards/space-stati…
EmoGarbage404 Jun 30, 2024
dd52fbe
Add node unlocking
EmoGarbage404 Jun 30, 2024
3c01fdb
more trigger cuz thats pretty cool
EmoGarbage404 Jul 5, 2024
34a703c
final triggers + incorporate gnostic faith
EmoGarbage404 Jul 6, 2024
c42a2b2
some ui changes, mostly
EmoGarbage404 Jul 6, 2024
2392c51
Fix orphaned procgen segments
EmoGarbage404 Jul 8, 2024
05e7918
its not random dipshit
EmoGarbage404 Jul 8, 2024
dbc3f70
yeah... this one will make pjb happy....
EmoGarbage404 Jul 9, 2024
e22daae
we call it a day for the UI
EmoGarbage404 Jul 12, 2024
c908214
imagine... shared power code...
EmoGarbage404 Jul 12, 2024
13fd4fb
Merge branch 'master' of https://github.com/space-wizards/space-stati…
EmoGarbage404 Jul 12, 2024
cd297d0
extraction WIP but we gotta sidequest momentarily
EmoGarbage404 Jul 13, 2024
2a97270
oh hey would you look at that its the actual functionality
EmoGarbage404 Jul 14, 2024
b0bc961
distrotrased
EmoGarbage404 Jul 15, 2024
5ad649d
Small departure for randomness.
EmoGarbage404 Jul 16, 2024
4c7c6fd
ok yep yep indeed that is an effect very cool.
EmoGarbage404 Jul 17, 2024
7c0ba34
thanos snap oldcode
EmoGarbage404 Jul 17, 2024
51d9c4c
fuck it we ball
EmoGarbage404 Jul 20, 2024
c315765
merge with master
Oct 29, 2024
6960349
Merge remote-tracking branch 'origin/master' into 3moArch
Nov 7, 2024
c390f61
feat: node scanner now displays triggered nodes. Removed unused old a…
Nov 13, 2024
49dc97a
refactor: most of preparations, cleanup and groundwork. also segment-…
Nov 16, 2024
4066b1d
feature: all basic effects returning
Nov 16, 2024
34b6c4e
feat: finished effects lits, created weight lists for struct and hand…
Nov 17, 2024
f9fca67
feat: prevent non-first-time-predicted calls in shared artifact effec…
Nov 17, 2024
e44dac6
fix: remove gun effect from artifact effects - as it interferes with …
Nov 17, 2024
6b39a61
Merge remote-tracking branch 'origin/master' into 3moArch
Nov 17, 2024
0784cb4
fix: foam reagent selection, neat ApplyComponents art effect scenario…
Nov 17, 2024
0842483
fix: moved spawn/ pry&throw effect systems back to server part of cod…
Nov 18, 2024
4ea9d3b
refactor: fix protos
Nov 18, 2024
32ce0f1
refactor: fix linter
Nov 18, 2024
41be02b
fix: fix old artifact component names in yml
Nov 19, 2024
38b318e
fix: no more throwing error on artifact spawn with empty XAEFoamCompo…
Nov 19, 2024
ff8fc26
fix: removed old component usage in maps
Nov 19, 2024
1f14968
fix: remove more deleted components from map
Nov 19, 2024
e2ac3db
fix: ContainerContainer is now part of initial artifact entity, it wo…
Nov 19, 2024
01134bb
refactor: fix tests, add loc description to toolshed commands
Nov 19, 2024
5cbfff3
Changed node scanner to tell the whole story about current artifact s…
Nov 24, 2024
e8f3a39
refactor: remove excessive get of EntityCoordinates in XAE systems, r…
Nov 24, 2024
45b0e1c
fix: turned off TriggerInteraction, removed XAESpawn usage and system…
Nov 25, 2024
d5aed90
fix: moved SharedXenoArtifactSystem.CancelUnlockingOnGraphStructureCh…
Nov 25, 2024
6c19b74
fix: XenoArtifactEffectJunkSpawn moved invalid rolls declaration
Nov 25, 2024
cbb88a7
refactor: set default value for XenoArtifactComponent.EffectsTable fo…
Nov 26, 2024
5087745
fix: now explosions XAE can be activated for effect
Nov 28, 2024
c358542
refactor: added some usedelay so artifactuse would'nt be spammed
Nov 28, 2024
922ef41
refactor: artifact-related hints improvements
Nov 28, 2024
9b4ad1c
merge with master
Nov 29, 2024
c1deec1
fix: artifact no longer spawns fauna into itself
Nov 30, 2024
47284c7
merge with master
Dec 1, 2024
f0a80de
Merge branch 'master' into 3moArch
Dec 2, 2024
74f447d
refactor: xml-doc and minor refactoring
Dec 10, 2024
692037a
refactor: xml-doc for Xeno Artifact systems, renaming of questionable…
Dec 14, 2024
0b818e2
map for playtest, TODO REVERT THIS
Dec 14, 2024
5114279
fix: magboots trigger art from a mile
Dec 19, 2024
5f6b3bf
refactor: bind artifact animation to unlocking state
Dec 19, 2024
cd3a798
feat: radiation dmg now have reference to source (and artifacts won't…
Dec 19, 2024
058c0e6
fix: random artifact node durability now is rolled for max and not cu…
Dec 19, 2024
4b4b276
refactor: gas effects are more rare, hand-held artifact effects are f…
Dec 19, 2024
2f83500
merge master
Dec 19, 2024
e551dc9
feat: animations and sound effects for artifact force-use and failed …
Dec 20, 2024
ca6891f
use only 1 file with art use animation
Dec 21, 2024
f509ed2
refactor: minor artifact dmg triggers tuning
Dec 21, 2024
65727ad
feat: now nodes that CAN be unlocked are displayed with specific colo…
Dec 21, 2024
ec338d4
feat: now unlocking stage time is dynamic and it depends on amount of…
Dec 21, 2024
eb4a02d
feat: now non-active unlocked nodes return more points if durability …
Dec 22, 2024
aed1d51
feat: now puddle/foam effects change description of node
Dec 24, 2024
24a4aae
fix: fix test failure
Dec 25, 2024
2426348
merge
Jan 4, 2025
917d66a
refactor: renamed phasing effect, fixed failing test for elkridge
Jan 4, 2025
3ccbc72
merge with master, transfer change to sentient art effect
Jan 12, 2025
e2fbb61
minor balance changes
Jan 12, 2025
3c88e69
refactor: split rare materials into separate effects
Jan 12, 2025
db0de70
feat: unlocked nodes without successor wont listen to unlocks, node u…
Jan 13, 2025
6d51b75
Merge branch 'master' into 3moArch
Jan 13, 2025
ff618f7
merge with master
Jan 19, 2025
378f67f
fix: removed OnIrradiatedEvent duplicate c-tor
Jan 19, 2025
368ed9f
revert changes of reach for playtest
Jan 19, 2025
b1a0dcf
revert last row empty line removal on reach.yml
Jan 19, 2025
d9a5827
fix: fix PVS bug, born from attempt to relay event to art nodes that …
Feb 2, 2025
de51d05
merge: merge with master
Feb 25, 2025
2e33b68
fix: fix elkridge for tests (again)
Feb 25, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
DAG Adjacency Matrix & Tests
  • Loading branch information
EmoGarbage404 committed Jun 17, 2024
commit eba8da7fc69cc10f56eabd38299ed760328521f9
312 changes: 312 additions & 0 deletions Content.IntegrationTests/Tests/XenoArtifactTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,312 @@
using System.Linq;
using Content.Shared.Xenoarchaeology.Artifact;
using Content.Shared.Xenoarchaeology.Artifact.Components;
using Robust.Shared.GameObjects;

namespace Content.IntegrationTests.Tests;

[TestFixture]
public sealed class XenoArtifactTest
{
[TestPrototypes]
private const string Prototypes = @"
- type: entity
id: TestArtifact
name: artifact
components:
- type: XenoArtifact

- type: entity
id: TestArtifactNode
name: artifact node
components:
- type: XenoArtifactNode
maxDurability: 3
";

/// <summary>
/// Checks that adding nodes and edges properly adds them into the adjacency matrix
/// </summary>
[Test]
public async Task XenoArtifactAddNodeTest()
{
await using var pair = await PoolManager.GetServerClient();
var server = pair.Server;

var entManager = server.ResolveDependency<IEntityManager>();
var artifactSystem = entManager.System<SharedXenoArtifactSystem>();

await server.WaitPost(() =>
{
var artifactUid = entManager.Spawn("TestArtifact");
var artifactEnt = (artifactUid, entManager.GetComponent<XenoArtifactComponent>(artifactUid));

// Create 3 nodes
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node1));
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node2));
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node3));

Assert.That(artifactSystem.GetAllNodeIndices(artifactEnt).Count(), Is.EqualTo(3));

// Add connection from 1 -> 2 and 2-> 3
artifactSystem.AddEdge(artifactEnt, node1!.Value, node2!.Value);
artifactSystem.AddEdge(artifactEnt, node2!.Value, node3!.Value);

// Assert that successors and direct successors are counted correctly for node 1.
Assert.That(artifactSystem.GetDirectSuccessorNodes(artifactEnt, node1!.Value).Count, Is.EqualTo(1));
Assert.That(artifactSystem.GetSuccessorNodes(artifactEnt, node1!.Value).Count, Is.EqualTo(2));
// Assert that we didn't somehow get predecessors on node 1.
Assert.That(artifactSystem.GetDirectPredecessorNodes(artifactEnt, node1!.Value), Is.Empty);
Assert.That(artifactSystem.GetPredecessorNodes(artifactEnt, node1!.Value), Is.Empty);

// Assert that successors and direct successors are counted correctly for node 2.
Assert.That(artifactSystem.GetDirectSuccessorNodes(artifactEnt, node2!.Value), Has.Count.EqualTo(1));
Assert.That(artifactSystem.GetSuccessorNodes(artifactEnt, node2!.Value), Has.Count.EqualTo(1));
// Assert that predecessors and direct predecessors are counted correctly for node 2.
Assert.That(artifactSystem.GetDirectPredecessorNodes(artifactEnt, node2!.Value), Has.Count.EqualTo(1));
Assert.That(artifactSystem.GetPredecessorNodes(artifactEnt, node2!.Value), Has.Count.EqualTo(1));

// Assert that successors and direct successors are counted correctly for node 3.
Assert.That(artifactSystem.GetDirectSuccessorNodes(artifactEnt, node3!.Value), Is.Empty);
Assert.That(artifactSystem.GetSuccessorNodes(artifactEnt, node3!.Value), Is.Empty);
// Assert that predecessors and direct predecessors are counted correctly for node 3.
Assert.That(artifactSystem.GetDirectPredecessorNodes(artifactEnt, node3!.Value), Has.Count.EqualTo(1));
Assert.That(artifactSystem.GetPredecessorNodes(artifactEnt, node3!.Value), Has.Count.EqualTo(2));
});
await server.WaitRunTicks(1);

await pair.CleanReturnAsync();
}

/// <summary>
/// Checks to make sure that removing nodes properly cleans up all connections.
/// </summary>
[Test]
public async Task XenoArtifactRemoveNodeTest()
{
await using var pair = await PoolManager.GetServerClient();
var server = pair.Server;

var entManager = server.ResolveDependency<IEntityManager>();
var artifactSystem = entManager.System<SharedXenoArtifactSystem>();

await server.WaitPost(() =>
{
var artifactUid = entManager.Spawn("TestArtifact");
var artifactEnt = (artifactUid, entManager.GetComponent<XenoArtifactComponent>(artifactUid));

// Create 3 nodes
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node1));
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node2));
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node3));
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node4));
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node5));

Assert.That(artifactSystem.GetAllNodeIndices(artifactEnt).Count(), Is.EqualTo(5));

// Add connection: 1 -> 2 -> 3 -> 4 -> 5
artifactSystem.AddEdge(artifactEnt, node1!.Value, node2!.Value);
artifactSystem.AddEdge(artifactEnt, node2!.Value, node3!.Value);
artifactSystem.AddEdge(artifactEnt, node3!.Value, node4!.Value);
artifactSystem.AddEdge(artifactEnt, node4!.Value, node5!.Value);

// Make sure we have a continuous connection between the two ends of the graph.
Assert.That(artifactSystem.GetSuccessorNodes(artifactEnt, node1.Value), Has.Count.EqualTo(4));
Assert.That(artifactSystem.GetPredecessorNodes(artifactEnt, node5.Value), Has.Count.EqualTo(4));

// Remove the node and make sure it's no longer in the artifact.
Assert.That(artifactSystem.RemoveNode(artifactEnt, node3!.Value));
Assert.That(artifactSystem.TryGetIndex(artifactEnt, node3!.Value, out _), Is.False, "Node 3 still present in artifact.");

// Check to make sure that we got rid of all the connections.
Assert.That(artifactSystem.GetSuccessorNodes(artifactEnt, node2!.Value), Is.Empty);
Assert.That(artifactSystem.GetPredecessorNodes(artifactEnt, node4!.Value), Is.Empty);
});
await server.WaitRunTicks(1);

await pair.CleanReturnAsync();
}

/// <summary>
/// Sets up series of linked nodes and ensures that resizing the adjacency matrix doesn't disturb the connections
/// </summary>
[Test]
public async Task XenoArtifactResizeTest()
{
await using var pair = await PoolManager.GetServerClient();
var server = pair.Server;

var entManager = server.ResolveDependency<IEntityManager>();
var artifactSystem = entManager.System<SharedXenoArtifactSystem>();

await server.WaitPost(() =>
{
var artifactUid = entManager.Spawn("TestArtifact");
var artifactEnt = (artifactUid, entManager.GetComponent<XenoArtifactComponent>(artifactUid));

// Create 3 nodes
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node1));
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node2));
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node3));

// Add connection: 1 -> 2 -> 3
artifactSystem.AddEdge(artifactEnt, node1!.Value, node2!.Value);
artifactSystem.AddEdge(artifactEnt, node2!.Value, node3!.Value);

// Make sure our connection is set up
Assert.That(artifactSystem.NodeHasEdge(artifactEnt, node1.Value, node2.Value));
Assert.That(artifactSystem.NodeHasEdge(artifactEnt, node2.Value, node3.Value));
Assert.That(artifactSystem.NodeHasEdge(artifactEnt, node2.Value, node1.Value), Is.False);
Assert.That(artifactSystem.NodeHasEdge(artifactEnt, node3.Value, node2.Value), Is.False);
Assert.That(artifactSystem.NodeHasEdge(artifactEnt, node1.Value, node3.Value), Is.False);
Assert.That(artifactSystem.NodeHasEdge(artifactEnt, node3.Value, node1.Value), Is.False);

Assert.That(artifactSystem.GetIndex(artifactEnt, node1!.Value), Is.EqualTo(0));
Assert.That(artifactSystem.GetIndex(artifactEnt, node2!.Value), Is.EqualTo(1));
Assert.That(artifactSystem.GetIndex(artifactEnt, node3!.Value), Is.EqualTo(2));

// Add a new node, resizing the original adjacency matrix and array.
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node4));

// Check that our connections haven't changed.
Assert.That(artifactSystem.NodeHasEdge(artifactEnt, node1.Value, node2.Value));
Assert.That(artifactSystem.NodeHasEdge(artifactEnt, node2.Value, node3.Value));
Assert.That(artifactSystem.NodeHasEdge(artifactEnt, node2.Value, node1.Value), Is.False);
Assert.That(artifactSystem.NodeHasEdge(artifactEnt, node3.Value, node2.Value), Is.False);
Assert.That(artifactSystem.NodeHasEdge(artifactEnt, node1.Value, node3.Value), Is.False);
Assert.That(artifactSystem.NodeHasEdge(artifactEnt, node3.Value, node1.Value), Is.False);

// Has our array shifted any when we resized?
Assert.That(artifactSystem.GetIndex(artifactEnt, node1!.Value), Is.EqualTo(0));
Assert.That(artifactSystem.GetIndex(artifactEnt, node2!.Value), Is.EqualTo(1));
Assert.That(artifactSystem.GetIndex(artifactEnt, node3!.Value), Is.EqualTo(2));

// Check that 4 didn't somehow end up with connections
Assert.That(artifactSystem.GetPredecessorNodes(artifactEnt, node4!.Value), Is.Empty);
Assert.That(artifactSystem.GetSuccessorNodes(artifactEnt, node4!.Value), Is.Empty);
});
await server.WaitRunTicks(1);

await pair.CleanReturnAsync();
}

/// <summary>
/// Checks if removing a node and adding a new node into its place in the adjacency matrix doesn't accidentally retain extra data.
/// </summary>
[Test]
public async Task XenoArtifactReplaceTest()
{
await using var pair = await PoolManager.GetServerClient();
var server = pair.Server;

var entManager = server.ResolveDependency<IEntityManager>();
var artifactSystem = entManager.System<SharedXenoArtifactSystem>();

await server.WaitPost(() =>
{
var artifactUid = entManager.Spawn("TestArtifact");
var artifactEnt = (artifactUid, entManager.GetComponent<XenoArtifactComponent>(artifactUid));

// Create 3 nodes
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node1));
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node2));
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node3));

// Add connection: 1 -> 2 -> 3
artifactSystem.AddEdge(artifactEnt, node1!.Value, node2!.Value);
artifactSystem.AddEdge(artifactEnt, node2!.Value, node3!.Value);

// Make sure our connection is set up
Assert.That(artifactSystem.NodeHasEdge(artifactEnt, node1.Value, node2.Value));
Assert.That(artifactSystem.NodeHasEdge(artifactEnt, node2.Value, node3.Value));

// Remove middle node, severing connections
artifactSystem.RemoveNode(artifactEnt, node2!.Value);

// Make sure our connection are properly severed.
Assert.That(artifactSystem.GetSuccessorNodes(artifactEnt, node1.Value), Is.Empty);
Assert.That(artifactSystem.GetPredecessorNodes(artifactEnt, node3.Value), Is.Empty);

// Make sure our matrix is 3x3
Assert.That(artifactEnt.Item2.NodeAdjacencyMatrixRows, Is.EqualTo(3));
Assert.That(artifactEnt.Item2.NodeAdjacencyMatrixColumns, Is.EqualTo(3));

Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node4));

// Make sure that adding in a new node didn't add a new slot but instead re-used the middle slot.
Assert.That(artifactEnt.Item2.NodeAdjacencyMatrixRows, Is.EqualTo(3));
Assert.That(artifactEnt.Item2.NodeAdjacencyMatrixColumns, Is.EqualTo(3));

// Ensure that all connections are still severed
Assert.That(artifactSystem.GetSuccessorNodes(artifactEnt, node1.Value), Is.Empty);
Assert.That(artifactSystem.GetPredecessorNodes(artifactEnt, node3.Value), Is.Empty);
Assert.That(artifactSystem.GetSuccessorNodes(artifactEnt, node4!.Value), Is.Empty);
Assert.That(artifactSystem.GetPredecessorNodes(artifactEnt, node4!.Value), Is.Empty);

});
await server.WaitRunTicks(1);

await pair.CleanReturnAsync();
}

/// <summary>
/// Checks if the active nodes are properly detected.
/// </summary>
[Test]
public async Task XenoArtifactBuildActiveNodesTest()
{
await using var pair = await PoolManager.GetServerClient();
var server = pair.Server;

var entManager = server.ResolveDependency<IEntityManager>();
var artifactSystem = entManager.System<SharedXenoArtifactSystem>();

await server.WaitPost(() =>
{
var artifactUid = entManager.Spawn("TestArtifact");
var artifactEnt = (artifactUid, entManager.GetComponent<XenoArtifactComponent>(artifactUid));

Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node1));
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node2));
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node3));
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node4));
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node5));
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node6));
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node7));
Assert.That(artifactSystem.AddNode(artifactEnt, "TestArtifactNode", out var node8));

// /----( 6 )
// /----[*3 ]-/----( 7 )----( 8 )
// /
// / /----[*5 ]
// [ 1 ]--/----[ 2 ]--/----( 4 )
// Diagram of the example generation. Nodes in [brackets] are unlocked, nodes in (braces) are locked
// and nodes with an *asterisk are supposed to be active.
artifactSystem.AddEdge(artifactEnt, node1!.Value, node2!.Value);
artifactSystem.AddEdge(artifactEnt, node1!.Value, node3!.Value);

artifactSystem.AddEdge(artifactEnt, node2!.Value, node4!.Value);
artifactSystem.AddEdge(artifactEnt, node2!.Value, node5!.Value);

artifactSystem.AddEdge(artifactEnt, node3!.Value, node6!.Value);
artifactSystem.AddEdge(artifactEnt, node3!.Value, node7!.Value);

artifactSystem.AddEdge(artifactEnt, node7!.Value, node8!.Value);

artifactSystem.SetNodeUnlocked(node1!.Value);
artifactSystem.SetNodeUnlocked(node2!.Value);
artifactSystem.SetNodeUnlocked(node3!.Value);
artifactSystem.SetNodeUnlocked(node5!.Value);

artifactSystem.RebuildCachedActiveNodes(artifactEnt);

var activeNodes = new[] { node3!.Value.Owner, node5!.Value.Owner };
Assert.That(artifactEnt.Item2.CachedActiveNodes, Is.SupersetOf(activeNodes));
Assert.That(artifactEnt.Item2.CachedActiveNodes, Has.Count.EqualTo(activeNodes.Length));

});
await server.WaitRunTicks(1);

await pair.CleanReturnAsync();
}
}
10 changes: 10 additions & 0 deletions Content.Server/Xenoarchaeology/Artifact/XenoArtifactSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Content.Server.Xenoarchaeology.Artifact;

public sealed partial class XenoArtifactSystem : EntitySystem
{
/// <inheritdoc/>
public override void Initialize()
{
base.Initialize();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using Robust.Shared.Containers;
using Robust.Shared.GameStates;

namespace Content.Shared.Xenoarchaeology.Artifact.Components;

/// <summary>
/// This is used for handling interactions with artifacts as well as
/// storing data about artifact node graphs.
/// </summary>
[RegisterComponent, NetworkedComponent, Access(typeof(SharedXenoArtifactSystem)), AutoGenerateComponentState]
public sealed partial class XenoArtifactComponent : Component
{
public static string NodeContainerId = "node-container";

[ViewVariables]
public Container NodeContainer = default!;

/// <summary>
/// The nodes in this artifact that are currently "active."
/// This is cached and updated when nodes are removed, added, or unlocked.
/// </summary>
[DataField, AutoNetworkedField]
public List<EntityUid> CachedActiveNodes = new();

//TODO: can't serialize entityuid arrays. Well fuck.

// NOTE: you should not be accessing any of these values directly. Use the methods in SharedXenoArtifactSystem.Graph
#region Graph
/// <summary>
/// List of all of the nodes currently on this artifact.
/// Indexes are used as a lookup table for <see cref="NodeAdjacencyMatrix"/>.
/// </summary>
[DataField] //AutoNetworkedField
public EntityUid?[] NodeVertices = [];

/// <summary>
/// Adjacency matrix that stores connections between this artifact's nodes.
/// A value of "true" denotes an directed edge from node1 to node2, where the location of the vertex is (node1, node2)
/// A value of "false" denotes no edge.
/// </summary>
//[DataField, AutoNetworkedField]
public bool[,] NodeAdjacencyMatrix = { };

public int NodeAdjacencyMatrixRows => NodeAdjacencyMatrix.GetLength(0);
public int NodeAdjacencyMatrixColumns => NodeAdjacencyMatrix.GetLength(1);
#endregion
}
Loading