Item artifacts (#12652)
@@ -0,0 +1,46 @@
|
|||||||
|
using Content.Shared.Xenoarchaeology.XenoArtifacts;
|
||||||
|
using Robust.Client.GameObjects;
|
||||||
|
|
||||||
|
namespace Content.Client.Xenoarchaeology.XenoArtifacts;
|
||||||
|
|
||||||
|
public sealed class RandomArtifactSpriteSystem : VisualizerSystem<RandomArtifactSpriteComponent>
|
||||||
|
{
|
||||||
|
protected override void OnAppearanceChange(EntityUid uid, RandomArtifactSpriteComponent component, ref AppearanceChangeEvent args)
|
||||||
|
{
|
||||||
|
if (args.Sprite == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!AppearanceSystem.TryGetData(uid, SharedArtifactsVisuals.SpriteIndex, out var ind, args.Component)
|
||||||
|
|| ind is not int spriteIndex)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!AppearanceSystem.TryGetData(uid, SharedArtifactsVisuals.IsActivated, out var act, args.Component)
|
||||||
|
|| act is not bool isActivated)
|
||||||
|
isActivated = false;
|
||||||
|
|
||||||
|
var spriteIndexStr = spriteIndex.ToString("D2");
|
||||||
|
var spritePrefix = isActivated ? "_on" : "";
|
||||||
|
|
||||||
|
// layered artifact sprite
|
||||||
|
if (args.Sprite.LayerMapTryGet(ArtifactsVisualLayers.Effect, out var layer))
|
||||||
|
{
|
||||||
|
var spriteState = "ano" + spriteIndexStr;
|
||||||
|
args.Sprite.LayerSetState(ArtifactsVisualLayers.Base, spriteState);
|
||||||
|
args.Sprite.LayerSetState(layer, spriteState + "_on");
|
||||||
|
args.Sprite.LayerSetVisible(layer, isActivated);
|
||||||
|
}
|
||||||
|
// non-layered
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var spriteState = "ano" + spriteIndexStr + spritePrefix;
|
||||||
|
args.Sprite.LayerSetState(ArtifactsVisualLayers.Base, spriteState);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ArtifactsVisualLayers : byte
|
||||||
|
{
|
||||||
|
Base,
|
||||||
|
Effect // doesn't have to use this
|
||||||
|
}
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
using Content.Shared.Xenoarchaeology.XenoArtifacts;
|
|
||||||
using Robust.Client.GameObjects;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.IoC;
|
|
||||||
|
|
||||||
namespace Content.Client.Xenoarchaeology.XenoArtifacts;
|
|
||||||
|
|
||||||
public sealed class RandomArtifactVisualizer : AppearanceVisualizer
|
|
||||||
{
|
|
||||||
[Obsolete("Subscribe to AppearanceChangeEvent instead.")]
|
|
||||||
public override void OnChangeData(AppearanceComponent component)
|
|
||||||
{
|
|
||||||
base.OnChangeData(component);
|
|
||||||
|
|
||||||
var entities = IoCManager.Resolve<IEntityManager>();
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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 System.Linq;
|
||||||
using Content.Server.Xenoarchaeology.XenoArtifacts.Events;
|
using Content.Server.Xenoarchaeology.XenoArtifacts.Events;
|
||||||
|
using Content.Shared.Item;
|
||||||
using Content.Shared.Xenoarchaeology.XenoArtifacts;
|
using Content.Shared.Xenoarchaeology.XenoArtifacts;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
@@ -20,7 +21,7 @@ public sealed partial class ArtifactSystem
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="tree">The tree being generated.</param>
|
/// <param name="tree">The tree being generated.</param>
|
||||||
/// <param name="nodeAmount">The amount of nodes it has.</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)
|
if (nodeAmount < 1)
|
||||||
{
|
{
|
||||||
@@ -33,14 +34,14 @@ public sealed partial class ArtifactSystem
|
|||||||
|
|
||||||
while (uninitializedNodes.Any())
|
while (uninitializedNodes.Any())
|
||||||
{
|
{
|
||||||
GenerateNode(ref uninitializedNodes, ref tree, nodeAmount);
|
GenerateNode(artifact, ref uninitializedNodes, ref tree, nodeAmount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generate an individual node on the tree.
|
/// Generate an individual node on the tree.
|
||||||
/// </summary>
|
/// </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())
|
if (!uninitializedNodes.Any())
|
||||||
return;
|
return;
|
||||||
@@ -69,8 +70,8 @@ public sealed partial class ArtifactSystem
|
|||||||
uninitializedNodes.Add(neighbor);
|
uninitializedNodes.Add(neighbor);
|
||||||
}
|
}
|
||||||
|
|
||||||
node.Trigger = GetRandomTrigger(ref node);
|
node.Trigger = GetRandomTrigger(artifact, ref node);
|
||||||
node.Effect = GetRandomEffect(ref node);
|
node.Effect = GetRandomEffect(artifact, ref node);
|
||||||
|
|
||||||
tree.AllNodes.Add(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
|
//yeah these two functions are near duplicates but i don't
|
||||||
//want to implement an interface or abstract parent
|
//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 allTriggers = _prototype.EnumeratePrototypes<ArtifactTriggerPrototype>().ToList();
|
||||||
var validDepth = allTriggers.Select(x => x.TargetDepth).Distinct().ToList();
|
var validDepth = allTriggers.Select(x => x.TargetDepth).Distinct().ToList();
|
||||||
|
|
||||||
var weights = GetDepthWeights(validDepth, node.Depth);
|
var weights = GetDepthWeights(validDepth, node.Depth);
|
||||||
var selectedRandomTargetDepth = GetRandomTargetDepth(weights);
|
var selectedRandomTargetDepth = GetRandomTargetDepth(weights);
|
||||||
var targetTriggers = allTriggers.Where(x =>
|
var targetTriggers = allTriggers
|
||||||
x.TargetDepth == selectedRandomTargetDepth).ToList();
|
.Where(x => x.TargetDepth == selectedRandomTargetDepth)
|
||||||
|
.Where(x => (x.Whitelist?.IsValid(artifact, EntityManager) ?? true) && (!x.Blacklist?.IsValid(artifact, EntityManager) ?? true)).ToList();
|
||||||
|
|
||||||
|
|
||||||
return _random.Pick(targetTriggers);
|
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 allEffects = _prototype.EnumeratePrototypes<ArtifactEffectPrototype>().ToList();
|
||||||
var validDepth = allEffects.Select(x => x.TargetDepth).Distinct().ToList();
|
var validDepth = allEffects.Select(x => x.TargetDepth).Distinct().ToList();
|
||||||
|
|
||||||
var weights = GetDepthWeights(validDepth, node.Depth);
|
var weights = GetDepthWeights(validDepth, node.Depth);
|
||||||
var selectedRandomTargetDepth = GetRandomTargetDepth(weights);
|
var selectedRandomTargetDepth = GetRandomTargetDepth(weights);
|
||||||
var targetEffects = allEffects.Where(x =>
|
var targetEffects = allEffects
|
||||||
x.TargetDepth == selectedRandomTargetDepth).ToList();
|
.Where(x => x.TargetDepth == selectedRandomTargetDepth)
|
||||||
|
.Where(x => (x.Whitelist?.IsValid(artifact, EntityManager) ?? true) && (!x.Blacklist?.IsValid(artifact, EntityManager) ?? true)).ToList();
|
||||||
|
|
||||||
return _random.Pick(targetEffects);
|
return _random.Pick(targetEffects);
|
||||||
}
|
}
|
||||||
@@ -164,11 +168,22 @@ public sealed partial class ArtifactSystem
|
|||||||
foreach (var (name, entry) in allComponents)
|
foreach (var (name, entry) in allComponents)
|
||||||
{
|
{
|
||||||
var reg = _componentFactory.GetRegistration(name);
|
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);
|
var comp = (Component) _componentFactory.GetComponent(reg);
|
||||||
comp.Owner = uid;
|
comp.Owner = uid;
|
||||||
|
|
||||||
var temp = (object) comp;
|
var temp = (object) comp;
|
||||||
_serialization.Copy(entry.Component, ref temp);
|
_serialization.Copy(entry.Component, ref temp);
|
||||||
|
|
||||||
EntityManager.AddComponent(uid, (Component) temp!, true);
|
EntityManager.AddComponent(uid, (Component) temp!, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ public sealed partial class ArtifactSystem : EntitySystem
|
|||||||
|
|
||||||
SubscribeLocalEvent<ArtifactComponent, MapInitEvent>(OnInit);
|
SubscribeLocalEvent<ArtifactComponent, MapInitEvent>(OnInit);
|
||||||
SubscribeLocalEvent<ArtifactComponent, PriceCalculationEvent>(GetPrice);
|
SubscribeLocalEvent<ArtifactComponent, PriceCalculationEvent>(GetPrice);
|
||||||
|
|
||||||
|
InitializeCommands();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnInit(EntityUid uid, ArtifactComponent component, MapInitEvent args)
|
private void OnInit(EntityUid uid, ArtifactComponent component, MapInitEvent args)
|
||||||
@@ -105,7 +107,7 @@ public sealed partial class ArtifactSystem : EntitySystem
|
|||||||
|
|
||||||
component.NodeTree = new ArtifactTree();
|
component.NodeTree = new ArtifactTree();
|
||||||
|
|
||||||
GenerateArtifactNodeTree(ref component.NodeTree, nodeAmount);
|
GenerateArtifactNodeTree(component.Owner, ref component.NodeTree, nodeAmount);
|
||||||
EnterNode(component.Owner, ref component.NodeTree.StartNode, component);
|
EnterNode(component.Owner, ref component.NodeTree.StartNode, component);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public sealed class SpawnArtifactSystem : EntitySystem
|
|||||||
toSpawn = _random.Pick(component.PossiblePrototypes);
|
toSpawn = _random.Pick(component.PossiblePrototypes);
|
||||||
|
|
||||||
// select spawn position near artifact
|
// select spawn position near artifact
|
||||||
var artifactCord = Transform(uid).Coordinates;
|
var artifactCord = Transform(uid).MapPosition;
|
||||||
var dx = _random.NextFloat(-component.Range, component.Range);
|
var dx = _random.NextFloat(-component.Range, component.Range);
|
||||||
var dy = _random.NextFloat(-component.Range, component.Range);
|
var dy = _random.NextFloat(-component.Range, component.Range);
|
||||||
var spawnCord = artifactCord.Offset(new Vector2(dx, dy));
|
var spawnCord = artifactCord.Offset(new Vector2(dx, dy));
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
using Robust.Shared.Prototypes;
|
using Content.Shared.Item;
|
||||||
|
using Content.Shared.Whitelist;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
namespace Content.Shared.Xenoarchaeology.XenoArtifacts;
|
namespace Content.Shared.Xenoarchaeology.XenoArtifacts;
|
||||||
@@ -33,4 +35,10 @@ public sealed class ArtifactEffectPrototype : IPrototype
|
|||||||
|
|
||||||
[DataField("effectHint")]
|
[DataField("effectHint")]
|
||||||
public string? EffectHint;
|
public string? EffectHint;
|
||||||
|
|
||||||
|
[DataField("whitelist")]
|
||||||
|
public EntityWhitelist? Whitelist;
|
||||||
|
|
||||||
|
[DataField("blacklist")]
|
||||||
|
public EntityWhitelist? Blacklist;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
using Robust.Shared.Prototypes;
|
using Content.Shared.Item;
|
||||||
|
using Content.Shared.Whitelist;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
namespace Content.Shared.Xenoarchaeology.XenoArtifacts;
|
namespace Content.Shared.Xenoarchaeology.XenoArtifacts;
|
||||||
@@ -22,4 +24,10 @@ public sealed class ArtifactTriggerPrototype : IPrototype
|
|||||||
|
|
||||||
[DataField("triggerHint")]
|
[DataField("triggerHint")]
|
||||||
public string? TriggerHint;
|
public string? TriggerHint;
|
||||||
|
|
||||||
|
[DataField("whitelist")]
|
||||||
|
public EntityWhitelist? Whitelist;
|
||||||
|
|
||||||
|
[DataField("blacklist")]
|
||||||
|
public EntityWhitelist? Blacklist;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace Content.Server.Xenoarchaeology.XenoArtifacts;
|
namespace Content.Shared.Xenoarchaeology.XenoArtifacts;
|
||||||
|
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public sealed class RandomArtifactSpriteComponent : Component
|
public sealed class RandomArtifactSpriteComponent : Component
|
||||||
@@ -10,6 +10,10 @@ artifact-effect-hint-consumption = Energy consumption
|
|||||||
artifact-effect-hint-release = Energy release
|
artifact-effect-hint-release = Energy release
|
||||||
artifact-effect-hint-biochemical = Biochemical disruption
|
artifact-effect-hint-biochemical = Biochemical disruption
|
||||||
artifact-effect-hint-destruction = Station-wide destruction
|
artifact-effect-hint-destruction = Station-wide destruction
|
||||||
|
artifact-effect-hint-gun = Small entity accelerator
|
||||||
|
artifact-effect-hint-multitool = Utility conglomerate
|
||||||
|
artifact-effect-hint-storage = Internal chamber
|
||||||
|
artifact-effect-hint-drill = Serrated rotator
|
||||||
|
|
||||||
# the triggers should be more obvious than the effects
|
# the triggers should be more obvious than the effects
|
||||||
# gives people an idea of what to do: don't be too specific (i.e. no "welders")
|
# gives people an idea of what to do: don't be too specific (i.e. no "welders")
|
||||||
@@ -25,3 +29,4 @@ artifact-trigger-hint-death = Life essence
|
|||||||
artifact-trigger-hint-radiation = Radiation
|
artifact-trigger-hint-radiation = Radiation
|
||||||
artifact-trigger-hint-pressure = Extreme pressure
|
artifact-trigger-hint-pressure = Extreme pressure
|
||||||
artifact-trigger-hint-gas = Gas
|
artifact-trigger-hint-gas = Gas
|
||||||
|
artifact-trigger-hint-land = Active deceleration
|
||||||
|
|||||||
@@ -13,8 +13,13 @@
|
|||||||
- MediumXenoArtifact
|
- MediumXenoArtifact
|
||||||
- MediumXenoArtifact
|
- MediumXenoArtifact
|
||||||
- MediumXenoArtifact
|
- MediumXenoArtifact
|
||||||
|
- MediumXenoArtifact
|
||||||
- ComplexXenoArtifact
|
- ComplexXenoArtifact
|
||||||
- ComplexXenoArtifact
|
- ComplexXenoArtifact
|
||||||
|
- ComplexXenoArtifact
|
||||||
|
- SimpleXenoArtifactItem
|
||||||
|
- MediumXenoArtifactItem
|
||||||
|
- ComplexXenoArtifactItem
|
||||||
chance: 1
|
chance: 1
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
- type: entity
|
||||||
|
parent: BaseItem
|
||||||
|
id: BaseXenoArtifactItem
|
||||||
|
name: alien artifact
|
||||||
|
description: A strange handheld alien device.
|
||||||
|
abstract: true
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Specific/Xenoarchaeology/item_artifacts.rsi
|
||||||
|
netsync: false
|
||||||
|
layers:
|
||||||
|
- state: ano01
|
||||||
|
map: [ "enum.ArtifactsVisualLayers.Base" ]
|
||||||
|
- state: ano01_on
|
||||||
|
map: [ "enum.ArtifactsVisualLayers.Effect" ]
|
||||||
|
visible: false
|
||||||
|
- type: Damageable
|
||||||
|
- type: Physics
|
||||||
|
bodyType: Dynamic
|
||||||
|
- type: InteractionOutline
|
||||||
|
- type: Artifact
|
||||||
|
- type: RandomArtifactSprite
|
||||||
|
maxSprite: 11
|
||||||
|
activationTime: 2.4
|
||||||
|
- type: RandomSprite
|
||||||
|
available:
|
||||||
|
- enum.ArtifactsVisualLayers.Effect:
|
||||||
|
ano01_on: Rainbow
|
||||||
|
- type: Appearance
|
||||||
|
- type: StaticPrice
|
||||||
|
price: 500
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: BaseXenoArtifactItem
|
||||||
|
id: SimpleXenoArtifactItem
|
||||||
|
suffix: Simple
|
||||||
|
components:
|
||||||
|
- type: Artifact
|
||||||
|
nodesMin: 2
|
||||||
|
nodesMax: 5
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: BaseXenoArtifactItem
|
||||||
|
id: MediumXenoArtifactItem
|
||||||
|
suffix: Medium
|
||||||
|
components:
|
||||||
|
- type: Artifact
|
||||||
|
nodesMin: 5
|
||||||
|
nodesMax: 9
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: BaseXenoArtifactItem
|
||||||
|
id: ComplexXenoArtifactItem
|
||||||
|
suffix: Complex
|
||||||
|
components:
|
||||||
|
- type: Artifact
|
||||||
|
nodesMin: 9
|
||||||
|
nodesMax: 13
|
||||||
|
|
||||||
@@ -9,6 +9,9 @@
|
|||||||
drawdepth: SmallObjects
|
drawdepth: SmallObjects
|
||||||
sprite: Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi
|
sprite: Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi
|
||||||
netsync: false
|
netsync: false
|
||||||
|
layers:
|
||||||
|
- state: ano01
|
||||||
|
map: [ "enum.ArtifactsVisualLayers.Base" ]
|
||||||
state: ano01
|
state: ano01
|
||||||
noRot: true
|
noRot: true
|
||||||
- type: Damageable
|
- type: Damageable
|
||||||
@@ -31,9 +34,6 @@
|
|||||||
- type: Artifact
|
- type: Artifact
|
||||||
- type: RandomArtifactSprite
|
- type: RandomArtifactSprite
|
||||||
- type: Appearance
|
- type: Appearance
|
||||||
visuals:
|
|
||||||
- type: RandomArtifactVisualizer
|
|
||||||
|
|
||||||
- type: StaticPrice
|
- type: StaticPrice
|
||||||
price: 500
|
price: 500
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
- type: artifactEffect
|
- type: artifactEffect
|
||||||
id: EffectBadFeeling
|
id: EffectBadFeeling
|
||||||
targetDepth: 0
|
targetDepth: 0
|
||||||
effectHint: artifact-effect-hint-mental
|
effectHint: artifact-effect-hint-mental
|
||||||
@@ -241,7 +241,6 @@
|
|||||||
- UltraHighPowerMicroLaserStockPart
|
- UltraHighPowerMicroLaserStockPart
|
||||||
- SuperMatterBinStockPart
|
- SuperMatterBinStockPart
|
||||||
|
|
||||||
|
|
||||||
- type: artifactEffect
|
- type: artifactEffect
|
||||||
id: EffectDisease
|
id: EffectDisease
|
||||||
targetDepth: 3
|
targetDepth: 3
|
||||||
@@ -271,14 +270,6 @@
|
|||||||
- GoldOre1
|
- GoldOre1
|
||||||
- UraniumOre1
|
- UraniumOre1
|
||||||
|
|
||||||
- type: artifactEffect
|
|
||||||
id: EffectPowerGen20K
|
|
||||||
targetDepth: 3
|
|
||||||
effectHint: artifact-effect-hint-release
|
|
||||||
components:
|
|
||||||
- type: PowerSupplier
|
|
||||||
supplyRate: 20000
|
|
||||||
|
|
||||||
- type: artifactEffect
|
- type: artifactEffect
|
||||||
id: EffectHeat
|
id: EffectHeat
|
||||||
targetDepth: 3
|
targetDepth: 3
|
||||||
163
Resources/Prototypes/XenoArch/Effects/utility_effects.yml
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
# Utility effects permanently modify the entity in some way when triggered, and they generally make it 'useful' for some purpose,
|
||||||
|
# like turning the artifact into a tool, or gun, or whatever.
|
||||||
|
|
||||||
|
- type: artifactEffect
|
||||||
|
id: EffectStorage
|
||||||
|
targetDepth: 2
|
||||||
|
effectHint: artifact-effect-hint-storage
|
||||||
|
whitelist:
|
||||||
|
components:
|
||||||
|
- Item # it doesnt necessarily have to be restricted from structures, but i think it'll be better that way
|
||||||
|
permanentComponents:
|
||||||
|
- type: UserInterface
|
||||||
|
interfaces:
|
||||||
|
- key: enum.StorageUiKey.Key
|
||||||
|
type: StorageBoundUserInterface
|
||||||
|
- type: ContainerContainer
|
||||||
|
containers:
|
||||||
|
storagebase: !type:Container
|
||||||
|
ents: [ ]
|
||||||
|
- type: Storage
|
||||||
|
capacity: 50
|
||||||
|
|
||||||
|
- type: artifactEffect
|
||||||
|
id: EffectSolutionStorage
|
||||||
|
targetDepth: 2
|
||||||
|
effectHint: artifact-effect-hint-storage
|
||||||
|
whitelist:
|
||||||
|
components:
|
||||||
|
- Item
|
||||||
|
permanentComponents:
|
||||||
|
- type: UserInterface
|
||||||
|
interfaces:
|
||||||
|
- key: enum.TransferAmountUiKey.Key
|
||||||
|
type: TransferAmountBoundUserInterface
|
||||||
|
- type: SolutionContainerManager
|
||||||
|
solutions:
|
||||||
|
beaker:
|
||||||
|
maxVol: 150
|
||||||
|
- type: FitsInDispenser
|
||||||
|
solution: beaker
|
||||||
|
- type: RefillableSolution
|
||||||
|
solution: beaker
|
||||||
|
- type: DrainableSolution
|
||||||
|
solution: beaker
|
||||||
|
- type: ExaminableSolution
|
||||||
|
solution: beaker
|
||||||
|
- type: DrawableSolution
|
||||||
|
solution: beaker
|
||||||
|
- type: InjectableSolution
|
||||||
|
solution: beaker
|
||||||
|
- type: SolutionTransfer
|
||||||
|
canChangeTransferAmount: true
|
||||||
|
- type: Drink
|
||||||
|
isOpen: true
|
||||||
|
solution: beaker
|
||||||
|
|
||||||
|
- type: artifactEffect
|
||||||
|
id: EffectDrill
|
||||||
|
targetDepth: 3
|
||||||
|
effectHint: artifact-effect-hint-drill
|
||||||
|
permanentComponents:
|
||||||
|
- type: GatheringTool
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Structural: 125
|
||||||
|
gatheringTime: 0.50
|
||||||
|
MaxGatheringEntities: 3
|
||||||
|
- type: ItemCooldown
|
||||||
|
- type: MeleeWeapon
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Piercing: 18
|
||||||
|
Blunt: 4
|
||||||
|
soundHit:
|
||||||
|
path: /Audio/Weapons/bladeslice.ogg
|
||||||
|
- type: Sharp
|
||||||
|
|
||||||
|
|
||||||
|
- type: artifactEffect
|
||||||
|
id: EffectPowerGen20K
|
||||||
|
targetDepth: 3
|
||||||
|
effectHint: artifact-effect-hint-release
|
||||||
|
blacklist:
|
||||||
|
components:
|
||||||
|
- Item
|
||||||
|
permanentComponents:
|
||||||
|
- type: PowerSupplier
|
||||||
|
supplyRate: 20000
|
||||||
|
|
||||||
|
- type: artifactEffect
|
||||||
|
id: EffectBigIron
|
||||||
|
targetDepth: 3
|
||||||
|
effectHint: artifact-effect-hint-gun
|
||||||
|
whitelist:
|
||||||
|
components:
|
||||||
|
- Item
|
||||||
|
permanentComponents:
|
||||||
|
- type: ContainerContainer
|
||||||
|
containers:
|
||||||
|
revolver-ammo: !type:Container
|
||||||
|
- type: RevolverAmmoProvider
|
||||||
|
whitelist:
|
||||||
|
tags:
|
||||||
|
- CartridgeMagnumHC
|
||||||
|
- SpeedLoaderMagnumHC
|
||||||
|
proto: CartridgeMagnumHC
|
||||||
|
capacity: 7
|
||||||
|
chambers: [ True, True, True, True, True, True, True ]
|
||||||
|
ammoSlots: [ null, null, null, null, null, null, null ]
|
||||||
|
soundEject:
|
||||||
|
path: /Audio/Weapons/Guns/MagOut/revolver_magout.ogg
|
||||||
|
soundInsert:
|
||||||
|
path: /Audio/Weapons/Guns/MagIn/revolver_magin.ogg
|
||||||
|
- type: Gun
|
||||||
|
selectedMode: SemiAuto
|
||||||
|
fireRate: 2
|
||||||
|
availableModes:
|
||||||
|
- SemiAuto
|
||||||
|
- FullAuto # no alien revolver in buildings
|
||||||
|
soundGunshot:
|
||||||
|
path: /Audio/Weapons/Guns/Gunshots/revolver.ogg
|
||||||
|
|
||||||
|
- type: artifactEffect
|
||||||
|
id: EffectMultitool
|
||||||
|
targetDepth: 3
|
||||||
|
effectHint: artifact-effect-hint-multitool
|
||||||
|
whitelist:
|
||||||
|
components:
|
||||||
|
- Item
|
||||||
|
permanentComponents:
|
||||||
|
- type: TilePrying
|
||||||
|
- type: SignalLinker
|
||||||
|
- type: Tool
|
||||||
|
qualities:
|
||||||
|
- Screwing
|
||||||
|
speed: 2 # Very powerful multitool to balance out the desire to sell or scrap for points
|
||||||
|
useSound: /Audio/Items/drill_use.ogg
|
||||||
|
- type: MultipleTool
|
||||||
|
statusShowBehavior: true
|
||||||
|
entries:
|
||||||
|
- behavior: Screwing
|
||||||
|
useSound:
|
||||||
|
path: /Audio/Items/drill_use.ogg
|
||||||
|
changeSound:
|
||||||
|
path: /Audio/Items/change_drill.ogg
|
||||||
|
- behavior: Prying
|
||||||
|
useSound:
|
||||||
|
path: /Audio/Items/jaws_pry.ogg
|
||||||
|
changeSound:
|
||||||
|
path: /Audio/Items/change_drill.ogg
|
||||||
|
- behavior: Anchoring
|
||||||
|
useSound:
|
||||||
|
path: /Audio/Items/ratchet.ogg
|
||||||
|
changeSound:
|
||||||
|
path: /Audio/Items/change_drill.ogg
|
||||||
|
- behavior: Cutting
|
||||||
|
useSound:
|
||||||
|
path: /Audio/Items/jaws_cut.ogg
|
||||||
|
changeSound:
|
||||||
|
path: /Audio/Items/change_drill.ogg
|
||||||
|
- behavior: Pulsing
|
||||||
|
changeSound:
|
||||||
|
path: /Audio/Items/change_drill.ogg
|
||||||
@@ -21,6 +21,9 @@
|
|||||||
id: TriggerAnchor
|
id: TriggerAnchor
|
||||||
targetDepth: 0
|
targetDepth: 0
|
||||||
triggerHint: artifact-trigger-hint-tool
|
triggerHint: artifact-trigger-hint-tool
|
||||||
|
blacklist:
|
||||||
|
components:
|
||||||
|
- Item
|
||||||
components:
|
components:
|
||||||
- type: ArtifactAnchorTrigger
|
- type: ArtifactAnchorTrigger
|
||||||
|
|
||||||
@@ -28,6 +31,9 @@
|
|||||||
id: TriggerElectricity
|
id: TriggerElectricity
|
||||||
targetDepth: 0
|
targetDepth: 0
|
||||||
triggerHint: artifact-trigger-hint-electricity
|
triggerHint: artifact-trigger-hint-electricity
|
||||||
|
blacklist:
|
||||||
|
components:
|
||||||
|
- Item
|
||||||
components:
|
components:
|
||||||
- type: ArtifactElectricityTrigger
|
- type: ArtifactElectricityTrigger
|
||||||
- type: PowerConsumer
|
- type: PowerConsumer
|
||||||
@@ -65,6 +71,16 @@
|
|||||||
- Piercing
|
- Piercing
|
||||||
damageThreshold: 50
|
damageThreshold: 50
|
||||||
|
|
||||||
|
- type: artifactTrigger
|
||||||
|
id: TriggerItemLanded
|
||||||
|
targetDepth: 1
|
||||||
|
triggerHint: artifact-trigger-hint-land
|
||||||
|
whitelist:
|
||||||
|
components:
|
||||||
|
- Item
|
||||||
|
components:
|
||||||
|
- type: ArtifactLandTrigger
|
||||||
|
|
||||||
- type: artifactTrigger
|
- type: artifactTrigger
|
||||||
id: TriggerHeat
|
id: TriggerHeat
|
||||||
targetDepth: 1
|
targetDepth: 1
|
||||||
@@ -98,6 +114,16 @@
|
|||||||
components:
|
components:
|
||||||
- type: ArtifactMagnetTrigger
|
- type: ArtifactMagnetTrigger
|
||||||
|
|
||||||
|
- type: artifactTrigger
|
||||||
|
id: TriggerMicrowave
|
||||||
|
targetDepth: 2
|
||||||
|
triggerHint: artifact-trigger-hint-radiation
|
||||||
|
whitelist:
|
||||||
|
components:
|
||||||
|
- Item
|
||||||
|
components:
|
||||||
|
- type: ArtifactMicrowaveTrigger
|
||||||
|
|
||||||
- type: artifactTrigger
|
- type: artifactTrigger
|
||||||
id: TriggerLowPressure
|
id: TriggerLowPressure
|
||||||
targetDepth: 2
|
targetDepth: 2
|
||||||
|
|||||||
|
After Width: | Height: | Size: 303 B |
|
After Width: | Height: | Size: 817 B |
|
After Width: | Height: | Size: 399 B |
|
After Width: | Height: | Size: 774 B |
|
After Width: | Height: | Size: 494 B |
|
After Width: | Height: | Size: 720 B |
|
After Width: | Height: | Size: 523 B |
|
After Width: | Height: | Size: 863 B |
|
After Width: | Height: | Size: 372 B |
|
After Width: | Height: | Size: 889 B |
|
After Width: | Height: | Size: 446 B |
|
After Width: | Height: | Size: 1021 B |
|
After Width: | Height: | Size: 500 B |
|
After Width: | Height: | Size: 749 B |
|
After Width: | Height: | Size: 386 B |
|
After Width: | Height: | Size: 547 B |
|
After Width: | Height: | Size: 359 B |
|
After Width: | Height: | Size: 619 B |
|
After Width: | Height: | Size: 359 B |
|
After Width: | Height: | Size: 676 B |
|
After Width: | Height: | Size: 739 B |
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1,178 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"license": "CC-BY-NC-SA 3.0",
|
||||||
|
"copyright": "goonstation at 4059e4be90832b02b1228b1bee3db342094e4f1e. ano11/ano11_on by brainfood#7460",
|
||||||
|
"size": {
|
||||||
|
"x": 32,
|
||||||
|
"y": 32
|
||||||
|
},
|
||||||
|
"states": [
|
||||||
|
{
|
||||||
|
"name": "ano01"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ano01_on",
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.2
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ano02"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ano02_on",
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.17,
|
||||||
|
0.17,
|
||||||
|
0.17,
|
||||||
|
0.17,
|
||||||
|
0.17,
|
||||||
|
0.17,
|
||||||
|
0.17
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ano03"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ano03_on",
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.24,
|
||||||
|
0.24,
|
||||||
|
0.24,
|
||||||
|
0.24,
|
||||||
|
0.24
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ano04"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ano04_on",
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.24,
|
||||||
|
0.24,
|
||||||
|
0.24,
|
||||||
|
0.24,
|
||||||
|
0.24
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ano05"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ano05_on",
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.24,
|
||||||
|
0.24,
|
||||||
|
0.24,
|
||||||
|
0.24,
|
||||||
|
0.24
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ano06"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ano06_on",
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.24,
|
||||||
|
0.24,
|
||||||
|
0.24,
|
||||||
|
0.24,
|
||||||
|
0.24
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ano07"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ano07_on",
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.3,
|
||||||
|
0.3,
|
||||||
|
0.3,
|
||||||
|
0.3
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ano08"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ano08_on",
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.3,
|
||||||
|
0.3,
|
||||||
|
0.3,
|
||||||
|
0.3
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ano09"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ano09_on",
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.24,
|
||||||
|
0.24,
|
||||||
|
0.24,
|
||||||
|
0.24,
|
||||||
|
0.24
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ano10"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ano10_on",
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.24,
|
||||||
|
0.24,
|
||||||
|
0.24,
|
||||||
|
0.24,
|
||||||
|
0.24
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ano11"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ano11_on",
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.2,
|
||||||
|
0.2
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||