Merge branch 'master' into offmed-staging

This commit is contained in:
Janet Blackquill
2025-10-03 15:40:07 -04:00
20 changed files with 411 additions and 144 deletions

View File

@@ -27,6 +27,16 @@ public sealed partial class TestPair : RobustIntegrationTest.TestPair
protected override async Task Initialize() protected override async Task Initialize()
{ {
await base.Initialize();
// Prevent info log spam in some tests (particularly SpawnAndDeleteAllEntitiesOnDifferentMaps)
Server.System<SharedMapSystem>().Log.Level = LogLevel.Warning;
Client.EntMan.EntitySysManager.SystemLoaded += (_, e) =>
{
if (e.System is SharedMapSystem map)
map.Log.Level = LogLevel.Warning;
};
var settings = (PoolSettings)Settings; var settings = (PoolSettings)Settings;
if (!settings.DummyTicker) if (!settings.DummyTicker)
{ {

View File

@@ -132,7 +132,7 @@ public sealed class EmbedTest : InteractionTest
"Target has unexpected EmbeddedObjects count."); "Target has unexpected EmbeddedObjects count.");
// Wait for the cooldown between throws // Wait for the cooldown between throws
await RunSeconds(Hands.ThrowCooldown.Seconds); await RunSeconds(Hands!.ThrowCooldown.Seconds);
// Throw the second projectile // Throw the second projectile
await ThrowItem(); await ThrowItem();

View File

@@ -169,6 +169,12 @@ public abstract partial class InteractionTest
/// <param name="enableToggleable">Whether or not to automatically enable any toggleable items</param> /// <param name="enableToggleable">Whether or not to automatically enable any toggleable items</param>
protected async Task<NetEntity> PlaceInHands(EntitySpecifier entity, bool enableToggleable = true) protected async Task<NetEntity> PlaceInHands(EntitySpecifier entity, bool enableToggleable = true)
{ {
if (Hands == null)
{
Assert.Fail("No HandsComponent");
return default;
}
if (Hands.ActiveHandId == null) if (Hands.ActiveHandId == null)
{ {
Assert.Fail("No active hand"); Assert.Fail("No active hand");
@@ -210,6 +216,12 @@ public abstract partial class InteractionTest
{ {
entity ??= Target; entity ??= Target;
if (Hands == null)
{
Assert.Fail("No HandsComponent");
return;
}
if (Hands.ActiveHandId == null) if (Hands.ActiveHandId == null)
{ {
Assert.Fail("No active hand"); Assert.Fail("No active hand");
@@ -860,7 +872,7 @@ public abstract partial class InteractionTest
/// List of currently active DoAfters on the player. /// List of currently active DoAfters on the player.
/// </summary> /// </summary>
protected IEnumerable<Shared.DoAfter.DoAfter> ActiveDoAfters protected IEnumerable<Shared.DoAfter.DoAfter> ActiveDoAfters
=> DoAfters.DoAfters.Values.Where(x => !x.Cancelled && !x.Completed); => DoAfters?.DoAfters.Values.Where(x => !x.Cancelled && !x.Completed) ?? [];
#region Component #region Component

View File

@@ -125,8 +125,8 @@ public abstract partial class InteractionTest
protected SharedUserInterfaceSystem CUiSys = default!; protected SharedUserInterfaceSystem CUiSys = default!;
// player components // player components
protected HandsComponent Hands = default!; protected HandsComponent? Hands;
protected DoAfterComponent DoAfters = default!; protected DoAfterComponent? DoAfters;
public float TickPeriod => (float)STiming.TickPeriod.TotalSeconds; public float TickPeriod => (float)STiming.TickPeriod.TotalSeconds;
@@ -222,8 +222,8 @@ public abstract partial class InteractionTest
SPlayer = SEntMan.SpawnEntity(PlayerPrototype, SEntMan.GetCoordinates(PlayerCoords)); SPlayer = SEntMan.SpawnEntity(PlayerPrototype, SEntMan.GetCoordinates(PlayerCoords));
Player = SEntMan.GetNetEntity(SPlayer); Player = SEntMan.GetNetEntity(SPlayer);
Server.PlayerMan.SetAttachedEntity(ServerSession, SPlayer); Server.PlayerMan.SetAttachedEntity(ServerSession, SPlayer);
Hands = SEntMan.GetComponent<HandsComponent>(SPlayer); Hands = SEntMan.GetComponentOrNull<HandsComponent>(SPlayer);
DoAfters = SEntMan.GetComponent<DoAfterComponent>(SPlayer); DoAfters = SEntMan.GetComponentOrNull<DoAfterComponent>(SPlayer);
}); });
// Check player got attached. // Check player got attached.

View File

@@ -0,0 +1,154 @@
using Content.IntegrationTests.Tests.Movement;
using Content.Server.NPC.HTN;
using Content.Shared.Damage;
using Content.Shared.FixedPoint;
using Content.Shared.Item.ItemToggle;
using Content.Shared.Item.ItemToggle.Components;
using Content.Shared.Mobs;
using Content.Shared.Mobs.Components;
using Content.Shared.Mousetrap;
using Robust.Shared.Maths;
using Robust.Shared.Prototypes;
namespace Content.IntegrationTests.Tests.Mousetrap;
/// <summary>
/// Spawns a mouse and a mousetrap.
/// Makes the mouse cross the inactive mousetrap, then activates the trap and
/// makes the mouse try to cross back over it.
/// </summary>
/// <remarks>
/// Yep, every time the tests run, a virtual mouse dies. Sorry.
/// </remarks>
public sealed class MousetrapMouseMoveOverTest : MovementTest
{
private static readonly EntProtoId MousetrapProtoId = "Mousetrap";
private static readonly EntProtoId MouseProtoId = "MobMouse";
protected override string PlayerPrototype => MouseProtoId.Id; // use a mouse as the player entity
[Test]
public async Task MouseMoveOverTest()
{
// Make sure the mouse doesn't have any AI active
await Server.WaitPost(() => SEntMan.RemoveComponent<HTNComponent>(SPlayer));
// Spawn a mouse trap
await SpawnTarget(MousetrapProtoId);
Assert.That(Delta(), Is.GreaterThan(0.5), "Mouse and mousetrap not in expected positions.");
Assert.That(HasComp<MousetrapComponent>(),
$"{MousetrapProtoId} does not have a MousetrapComponent. If you're refactoring, please update this test!");
Assert.That(TryComp<ItemToggleComponent>(out var itemToggleComp),
$"{MousetrapProtoId} does not have a ItemToggleComponent. If you're refactoring, please update this test!");
Assert.That(itemToggleComp.Activated, Is.False, "Mousetrap started active.");
// The mouse is spawned by the test before the atmosphere is added, so it has some barotrauma damage already
// TODO: fix this since it can have an impact on integration tests
Assert.That(SEntMan.TryGetComponent<DamageableComponent>(SPlayer, out var damageComp),
$"Player does not have a DamageableComponent.");
var startingDamage = damageComp.TotalDamage;
Assert.That(SEntMan.TryGetComponent<MobStateComponent>(SPlayer, out var mouseMobStateComp),
$"{MouseProtoId} does not have a MobStateComponent.");
Assert.That(mouseMobStateComp.CurrentState, Is.EqualTo(MobState.Alive), "Mouse was not alive when spawned.");
// Move mouse over the trap
await Move(DirectionFlag.East, 1f);
Assert.That(Delta(), Is.LessThan(0.5), "Mouse did not move over mousetrap.");
// Walking over an inactive trap does not trigger it
Assert.That(damageComp.TotalDamage, Is.LessThanOrEqualTo(startingDamage), "Mouse took damage from inactive trap!");
Assert.That(itemToggleComp.Activated, Is.False, "Mousetrap was activated.");
// Activate the trap
var itemToggleSystem = Server.System<ItemToggleSystem>();
await Server.WaitAssertion(() =>
{
Assert.That(itemToggleSystem.TrySetActive(STarget.Value, true), "Could not activate the mouse trap.");
});
await Move(DirectionFlag.West, 1f);
Assert.That(Delta(), Is.LessThan(0.1), "Mouse moved past active mousetrap.");
// Walking over an active trap triggers it
Assert.That(damageComp.TotalDamage, Is.GreaterThan(startingDamage), "Mouse did not take damage from active trap!");
Assert.That(itemToggleComp.Activated, Is.False, "Mousetrap was not deactivated after triggering.");
Assert.That(mouseMobStateComp.CurrentState, Is.EqualTo(MobState.Dead), "Mouse was not killed by trap.");
}
}
/// <summary>
/// Spawns a mousetrap and makes the player walk over it without shoes.
/// Gives the player some shoes and makes them walk back over the trap.
/// </summary>
public sealed class MousetrapHumanMoveOverTest : MovementTest
{
private static readonly EntProtoId MousetrapProtoId = "Mousetrap";
private const string ShoesProtoId = "InteractionTestShoes";
[TestPrototypes]
private static readonly string TestPrototypes = $@"
- type: entity
parent: ClothingShoesBase
id: {ShoesProtoId}
components:
- type: Sprite
sprite: Clothing/Shoes/Boots/workboots.rsi
";
[Test]
public async Task HumanMoveOverTest()
{
await SpawnTarget(MousetrapProtoId);
Assert.That(Delta(), Is.GreaterThan(0.5), "Player and mousetrap not in expected positions.");
Assert.That(HasComp<MousetrapComponent>(),
$"{MousetrapProtoId} does not have a MousetrapComponent. If you're refactoring, please update this test!");
Assert.That(TryComp<ItemToggleComponent>(out var itemToggleComp),
$"{MousetrapProtoId} does not have a ItemToggleComponent. If you're refactoring, please update this test!");
// Activate the trap
var itemToggleSystem = Server.System<ItemToggleSystem>();
await Server.WaitAssertion(() =>
{
Assert.That(itemToggleSystem.TrySetActive(STarget.Value, true), "Could not activate the mouse trap.");
});
Assert.That(SEntMan.TryGetComponent<DamageableComponent>(SPlayer, out var damageComp),
$"Player does not have a DamageableComponent.");
var startingDamage = damageComp.TotalDamage;
// Move player over the trap
await Move(DirectionFlag.East, 0.5f);
Assert.That(Delta(), Is.LessThan(0.5), "Player did not move over mousetrap.");
// Walking over the trap without shoes activates it
Assert.That(damageComp.TotalDamage, Is.GreaterThan(startingDamage), "Player did not take damage.");
Assert.That(itemToggleComp.Activated, Is.False, "Mousetrap was not deactivated after triggering.");
// Reactivate the trap
await Server.WaitAssertion(() =>
{
Assert.That(itemToggleSystem.TrySetActive(STarget.Value, true), "Could not activate the mouse trap.");
});
var afterStepDamage = damageComp.TotalDamage;
// Give the player some shoes
await PlaceInHands(ShoesProtoId);
// Thanks to quick-equip, using the shoes will wear them
await UseInHand();
// Move back over the trap
await Move(DirectionFlag.West, 1f);
Assert.That(Delta(), Is.GreaterThan(0.5), "Player did not move back over mousetrap.");
// Walking over the trap with shoes on does not activate it
Assert.That(damageComp.TotalDamage, Is.LessThanOrEqualTo(afterStepDamage), "Player took damage from trap!");
Assert.That(itemToggleComp.Activated, "Mousetrap was deactivated despite the player being protected by shoes.");
}
}

View File

@@ -19,9 +19,6 @@ public static class ServerPackaging
new PlatformReg("osx-x64", "MacOS", true), new PlatformReg("osx-x64", "MacOS", true),
new PlatformReg("osx-arm64", "MacOS", true), new PlatformReg("osx-arm64", "MacOS", true),
// Non-default platforms (i.e. for Watchdog Git) // Non-default platforms (i.e. for Watchdog Git)
new PlatformReg("win-x86", "Windows", false),
new PlatformReg("linux-x86", "Linux", false),
new PlatformReg("linux-arm", "Linux", false),
new PlatformReg("freebsd-x64", "FreeBSD", false), new PlatformReg("freebsd-x64", "FreeBSD", false),
}; };

View File

@@ -1,4 +1,5 @@
using Content.Shared.Arcade; using Content.Shared.Arcade;
using Content.Shared.Dataset;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
@@ -23,85 +24,73 @@ public sealed partial class SpaceVillainArcadeComponent : SharedSpaceVillainArca
/// <summary> /// <summary>
/// The sound played when a new session of the SpaceVillain game is begun. /// The sound played when a new session of the SpaceVillain game is begun.
/// </summary> /// </summary>
[DataField("newGameSound")] [DataField]
public SoundSpecifier NewGameSound = new SoundPathSpecifier("/Audio/Effects/Arcade/newgame.ogg"); public SoundSpecifier NewGameSound = new SoundPathSpecifier("/Audio/Effects/Arcade/newgame.ogg");
/// <summary> /// <summary>
/// The sound played when the player chooses to attack. /// The sound played when the player chooses to attack.
/// </summary> /// </summary>
[DataField("playerAttackSound")] [DataField]
public SoundSpecifier PlayerAttackSound = new SoundPathSpecifier("/Audio/Effects/Arcade/player_attack.ogg"); public SoundSpecifier PlayerAttackSound = new SoundPathSpecifier("/Audio/Effects/Arcade/player_attack.ogg");
/// <summary> /// <summary>
/// The sound played when the player chooses to heal. /// The sound played when the player chooses to heal.
/// </summary> /// </summary>
[DataField("playerHealSound")] [DataField]
public SoundSpecifier PlayerHealSound = new SoundPathSpecifier("/Audio/Effects/Arcade/player_heal.ogg"); public SoundSpecifier PlayerHealSound = new SoundPathSpecifier("/Audio/Effects/Arcade/player_heal.ogg");
/// <summary> /// <summary>
/// The sound played when the player chooses to regain mana. /// The sound played when the player chooses to regain mana.
/// </summary> /// </summary>
[DataField("playerChargeSound")] [DataField]
public SoundSpecifier PlayerChargeSound = new SoundPathSpecifier("/Audio/Effects/Arcade/player_charge.ogg"); public SoundSpecifier PlayerChargeSound = new SoundPathSpecifier("/Audio/Effects/Arcade/player_charge.ogg");
/// <summary> /// <summary>
/// The sound played when the player wins. /// The sound played when the player wins.
/// </summary> /// </summary>
[DataField("winSound")] [DataField]
public SoundSpecifier WinSound = new SoundPathSpecifier("/Audio/Effects/Arcade/win.ogg"); public SoundSpecifier WinSound = new SoundPathSpecifier("/Audio/Effects/Arcade/win.ogg");
/// <summary> /// <summary>
/// The sound played when the player loses. /// The sound played when the player loses.
/// </summary> /// </summary>
[DataField("gameOverSound")] [DataField]
public SoundSpecifier GameOverSound = new SoundPathSpecifier("/Audio/Effects/Arcade/gameover.ogg"); public SoundSpecifier GameOverSound = new SoundPathSpecifier("/Audio/Effects/Arcade/gameover.ogg");
/// <summary> /// <summary>
/// The prefixes that can be used to create the game name. /// The prefixes that can be used to create the game name.
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite)] [DataField]
[DataField("possibleFightVerbs")] public ProtoId<LocalizedDatasetPrototype> PossibleFightVerbs = "SpaceVillainVerbsFight";
public List<string> PossibleFightVerbs = new()
{"Defeat", "Annihilate", "Save", "Strike", "Stop", "Destroy", "Robust", "Romance", "Pwn", "Own"};
/// <summary> /// <summary>
/// The first names/titles that can be used to construct the name of the villain. /// The first names/titles that can be used to construct the name of the villain.
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite)] [DataField]
[DataField("possibleFirstEnemyNames")] public ProtoId<LocalizedDatasetPrototype> PossibleFirstEnemyNames = "SpaceVillainNamesEnemyFirst";
public List<string> PossibleFirstEnemyNames = new(){
"the Automatic", "Farmer", "Lord", "Professor", "the Cuban", "the Evil", "the Dread King",
"the Space", "Lord", "the Great", "Duke", "General"
};
/// <summary> /// <summary>
/// The last names that can be used to construct the name of the villain. /// The last names that can be used to construct the name of the villain.
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite)] [DataField]
[DataField("possibleLastEnemyNames")] public ProtoId<LocalizedDatasetPrototype> PossibleLastEnemyNames = "SpaceVillainNamesEnemyLast";
public List<string> PossibleLastEnemyNames = new()
{
"Melonoid", "Murdertron", "Sorcerer", "Ruin", "Jeff", "Ectoplasm", "Crushulon", "Uhangoid",
"Vhakoid", "Peteoid", "slime", "Griefer", "ERPer", "Lizard Man", "Unicorn"
};
/// <summary> /// <summary>
/// The prototypes that can be dispensed as a reward for winning the game. /// The prototypes that can be dispensed as a reward for winning the game.
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite)]
[DataField] [DataField]
public List<EntProtoId> PossibleRewards = new(); public List<EntProtoId> PossibleRewards = new();
/// <summary> /// <summary>
/// The minimum number of prizes the arcade machine can have. /// The minimum number of prizes the arcade machine can have.
/// </summary> /// </summary>
[DataField("rewardMinAmount")] [DataField]
public int RewardMinAmount; public int RewardMinAmount;
/// <summary> /// <summary>
/// The maximum number of prizes the arcade machine can have. /// The maximum number of prizes the arcade machine can have.
/// </summary> /// </summary>
[DataField("rewardMaxAmount")] [DataField]
public int RewardMaxAmount; public int RewardMaxAmount;
/// <summary> /// <summary>

View File

@@ -4,15 +4,18 @@ using Content.Server.Advertise.EntitySystems;
using Content.Shared.Advertise.Components; using Content.Shared.Advertise.Components;
using Content.Shared.Arcade; using Content.Shared.Arcade;
using Content.Shared.Power; using Content.Shared.Power;
using Content.Shared.Random.Helpers;
using Robust.Server.GameObjects; using Robust.Server.GameObjects;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems; using Robust.Shared.Audio.Systems;
using Robust.Shared.Prototypes;
using Robust.Shared.Random; using Robust.Shared.Random;
namespace Content.Server.Arcade.SpaceVillain; namespace Content.Server.Arcade.SpaceVillain;
public sealed partial class SpaceVillainArcadeSystem : EntitySystem public sealed partial class SpaceVillainArcadeSystem : EntitySystem
{ {
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly SharedAudioSystem _audioSystem = default!; [Dependency] private readonly SharedAudioSystem _audioSystem = default!;
[Dependency] private readonly UserInterfaceSystem _uiSystem = default!; [Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
@@ -52,7 +55,7 @@ public sealed partial class SpaceVillainArcadeSystem : EntitySystem
/// <returns>A fight-verb.</returns> /// <returns>A fight-verb.</returns>
public string GenerateFightVerb(SpaceVillainArcadeComponent arcade) public string GenerateFightVerb(SpaceVillainArcadeComponent arcade)
{ {
return _random.Pick(arcade.PossibleFightVerbs); return _random.Pick(_prototypeManager.Index(arcade.PossibleFightVerbs));
} }
/// <summary> /// <summary>
@@ -61,7 +64,10 @@ public sealed partial class SpaceVillainArcadeSystem : EntitySystem
/// <returns>An enemy-name.</returns> /// <returns>An enemy-name.</returns>
public string GenerateEnemyName(SpaceVillainArcadeComponent arcade) public string GenerateEnemyName(SpaceVillainArcadeComponent arcade)
{ {
return $"{_random.Pick(arcade.PossibleFirstEnemyNames)} {_random.Pick(arcade.PossibleLastEnemyNames)}"; var possibleFirstEnemyNames = _prototypeManager.Index(arcade.PossibleFirstEnemyNames);
var possibleLastEnemyNames = _prototypeManager.Index(arcade.PossibleLastEnemyNames);
return $"{_random.Pick(possibleFirstEnemyNames)} {_random.Pick(possibleLastEnemyNames)}";
} }
private void OnComponentInit(EntityUid uid, SpaceVillainArcadeComponent component, ComponentInit args) private void OnComponentInit(EntityUid uid, SpaceVillainArcadeComponent component, ComponentInit args)

View File

@@ -7,6 +7,7 @@ using Content.Shared.DoAfter;
using Content.Shared.DragDrop; using Content.Shared.DragDrop;
using Content.Shared.Examine; using Content.Shared.Examine;
using Content.Shared.Hands; using Content.Shared.Hands;
using Content.Shared.Humanoid;
using Content.Shared.IdentityManagement; using Content.Shared.IdentityManagement;
using Content.Shared.Interaction; using Content.Shared.Interaction;
using Content.Shared.Interaction.Events; using Content.Shared.Interaction.Events;
@@ -238,8 +239,11 @@ public sealed class SharedKitchenSpikeSystem : EntitySystem
args.Target.Value, args.Target.Value,
ent); ent);
// normally medium severity, but for humanoids high severity, so new players get relay'd to admin alerts.
var logSeverity = HasComp<HumanoidAppearanceComponent>(args.Target) ? LogImpact.High : LogImpact.Medium;
_logger.Add(LogType.Action, _logger.Add(LogType.Action,
LogImpact.High, logSeverity,
$"{ToPrettyString(args.User):user} put {ToPrettyString(args.Target):target} on the {ToPrettyString(ent):spike}"); $"{ToPrettyString(args.User):user} put {ToPrettyString(args.Target):target} on the {ToPrettyString(ent):spike}");
_audioSystem.PlayPredicted(ent.Comp.SpikeSound, ent, args.User); _audioSystem.PlayPredicted(ent.Comp.SpikeSound, ent, args.User);
@@ -316,8 +320,10 @@ public sealed class SharedKitchenSpikeSystem : EntitySystem
{ {
_bodySystem.GibBody(args.Target.Value, true); _bodySystem.GibBody(args.Target.Value, true);
var logSeverity = HasComp<HumanoidAppearanceComponent>(args.Target) ? LogImpact.Extreme : LogImpact.High;
_logger.Add(LogType.Gib, _logger.Add(LogType.Gib,
LogImpact.Extreme, logSeverity,
$"{ToPrettyString(args.User):user} finished butchering {ToPrettyString(args.Target):target} on the {ToPrettyString(ent):spike}"); $"{ToPrettyString(args.User):user} finished butchering {ToPrettyString(args.Target):target} on the {ToPrettyString(ent):spike}");
} }
else else
@@ -325,8 +331,10 @@ public sealed class SharedKitchenSpikeSystem : EntitySystem
EnsureComp<KitchenSpikeVictimComponent>(args.Target.Value); EnsureComp<KitchenSpikeVictimComponent>(args.Target.Value);
_damageableSystem.TryChangeDamage(args.Target, ent.Comp.ButcherDamage, true); _damageableSystem.TryChangeDamage(args.Target, ent.Comp.ButcherDamage, true);
// Log severity for damaging other entities is normally medium.
_logger.Add(LogType.Action, _logger.Add(LogType.Action,
LogImpact.Extreme, LogImpact.Medium,
$"{ToPrettyString(args.User):user} butchered {ToPrettyString(args.Target):target} on the {ToPrettyString(ent):spike}"); $"{ToPrettyString(args.User):user} butchered {ToPrettyString(args.Target):target} on the {ToPrettyString(ent):spike}");
} }

View File

@@ -0,0 +1,40 @@
# Verbs
arcade-villain-verbs-fight-1 = Annihilate
arcade-villain-verbs-fight-2 = Defeat
arcade-villain-verbs-fight-3 = Destroy
arcade-villain-verbs-fight-4 = Own
arcade-villain-verbs-fight-5 = Pwn
arcade-villain-verbs-fight-6 = Robust
arcade-villain-verbs-fight-7 = Romance
arcade-villain-verbs-fight-8 = Save
arcade-villain-verbs-fight-9 = Stop
arcade-villain-verbs-fight-10 = Strike
# Enemy names
arcade-villain-names-enemy-first-1 = Duke
arcade-villain-names-enemy-first-2 = Farmer
arcade-villain-names-enemy-first-3 = General
arcade-villain-names-enemy-first-4 = Lord
arcade-villain-names-enemy-first-5 = Professor
arcade-villain-names-enemy-first-6 = the Automatic
arcade-villain-names-enemy-first-7 = the Cuban
arcade-villain-names-enemy-first-8 = the Dread King
arcade-villain-names-enemy-first-9 = the Evil
arcade-villain-names-enemy-first-10 = the Great
arcade-villain-names-enemy-first-11 = the Space
arcade-villain-names-enemy-last-1 = Crushulon
arcade-villain-names-enemy-last-2 = ERPer
arcade-villain-names-enemy-last-3 = Ectoplasm
arcade-villain-names-enemy-last-4 = Griefer
arcade-villain-names-enemy-last-5 = Jeff
arcade-villain-names-enemy-last-6 = Lizard Man
arcade-villain-names-enemy-last-7 = Melonoid
arcade-villain-names-enemy-last-8 = Murdertron
arcade-villain-names-enemy-last-9 = Peteoid
arcade-villain-names-enemy-last-10 = Ruin
arcade-villain-names-enemy-last-11 = Sorcerer
arcade-villain-names-enemy-last-12 = Uhangoid
arcade-villain-names-enemy-last-13 = Unicorn
arcade-villain-names-enemy-last-14 = Vhakoid
arcade-villain-names-enemy-last-15 = slime

View File

@@ -0,0 +1,17 @@
- type: localizedDataset
id: SpaceVillainVerbsFight
values:
prefix: arcade-villain-verbs-fight-
count: 10
- type: localizedDataset
id: SpaceVillainNamesEnemyFirst
values:
prefix: arcade-villain-names-enemy-first-
count: 11
- type: localizedDataset
id: SpaceVillainNamesEnemyLast
values:
prefix: arcade-villain-names-enemy-last-
count: 15

View File

@@ -241,14 +241,14 @@
id: RandomSatchelTable3 id: RandomSatchelTable3
table: !type:AllSelector table: !type:AllSelector
children: children:
- !type:NestedSelector
tableId: RandomSatchelBurgerTable #2x medium
- !type:NestedSelector - !type:NestedSelector
tableId: RandomSatchelPresentsOrToysTable #3x small tableId: RandomSatchelPresentsOrToysTable #3x small
- !type:NestedSelector - !type:NestedSelector
tableId: RandomSatchelCashTable #1x small tableId: RandomSatchelCashTable #1x small
- !type:NestedSelector - !type:NestedSelector
tableId: RandomSatchelWeaponTable #5x small tableId: RandomSatchelWeaponTable #5x small
- !type:NestedSelector
tableId: RandomSatchelBurgerTable #5x small
- !type:NestedSelector - !type:NestedSelector
tableId: RandomSatchelGenericTableSmall #1x small tableId: RandomSatchelGenericTableSmall #1x small
- !type:NestedSelector - !type:NestedSelector
@@ -309,24 +309,18 @@
amount: !type:RangeNumberSelector amount: !type:RangeNumberSelector
range: 1, 5 range: 1, 5
- type: entityTable #5x small - type: entityTable #2x medium
id: RandomSatchelBurgerTable id: RandomSatchelBurgerTable
table: !type:GroupSelector table: !type:GroupSelector
rolls: !type:RangeNumberSelector
range: 1, 2
children: children:
- id: SpaceCash100 - id: SpaceCash100
weight: 10 weight: 10
- id: FoodBurgerAppendix - id: FoodBurgerAppendix
amount: !type:RangeNumberSelector
range: 1, 5
- id: FoodBurgerEmpowered - id: FoodBurgerEmpowered
amount: !type:RangeNumberSelector
range: 1, 5
- id: FoodBurgerClown - id: FoodBurgerClown
amount: !type:RangeNumberSelector
range: 1, 5
- id: FoodBurgerGhost - id: FoodBurgerGhost
amount: !type:RangeNumberSelector
range: 1, 5
- type: entityTable #1x small - type: entityTable #1x small
id: RandomSatchelGenericTableSmall id: RandomSatchelGenericTableSmall

View File

@@ -12,5 +12,3 @@
- type: Tag - type: Tag
tags: tags:
- StationMapElectronics - StationMapElectronics
- type: StaticPrice
price: 30

View File

@@ -10,8 +10,6 @@
- type: Sprite - type: Sprite
sprite: Objects/Misc/module.rsi sprite: Objects/Misc/module.rsi
state: generic state: generic
- type: StaticPrice
price: 100
- type: PhysicalComposition - type: PhysicalComposition
materialComposition: materialComposition:
Glass: 200 Glass: 200

View File

@@ -10,5 +10,3 @@
- type: Tag - type: Tag
tags: tags:
- MailingUnitElectronics - MailingUnitElectronics
- type: StaticPrice
price: 55

View File

@@ -11,8 +11,6 @@
tags: tags:
- DoorElectronics - DoorElectronics
- type: DoorElectronics - type: DoorElectronics
- type: StaticPrice
price: 55
- type: AccessReader - type: AccessReader
- type: ActivatableUI - type: ActivatableUI
key: enum.DoorElectronicsConfigurationUiKey.Key key: enum.DoorElectronicsConfigurationUiKey.Key

View File

@@ -11,5 +11,3 @@
tags: tags:
- FreezerElectronics - FreezerElectronics
- type: DoorElectronics - type: DoorElectronics
- type: StaticPrice
price: 55

View File

@@ -11,10 +11,8 @@
blacklist: blacklist:
components: components:
- SecretStash # Prevents being able to insert plushies inside each other (infinite plush)! - SecretStash # Prevents being able to insert plushies inside each other (infinite plush)!
- NukeDisk # Could confuse the Nukies if they don't know that plushies have a stash.
tags: tags:
- QuantumSpinInverter # It will cause issues with the grinder... - QuantumSpinInverter # It will cause issues with the grinder...
- FakeNukeDisk # So you can't tell if the nuke disk is real or fake depending on if it can be inserted or not.
- type: ToolOpenable - type: ToolOpenable
openToolQualityNeeded: Slicing openToolQualityNeeded: Slicing
closeToolQualityNeeded: Slicing # Should probably be stitching or something if that gets added closeToolQualityNeeded: Slicing # Should probably be stitching or something if that gets added

View File

@@ -19,7 +19,7 @@
slots: slots:
- neck - neck
- type: StaticPrice - type: StaticPrice
price: 100 price: 12
- type: Tag - type: Tag
tags: tags:
- Bedsheet - Bedsheet

View File

@@ -1,208 +1,215 @@
# PUT YOUR TAGS IN ALPHABETICAL ORDER # PUT YOUR TAGS IN ALPHABETICAL ORDER
# ALSO DOCUMENT WHAT THE HELL THEY DO
## A ##
- type: Tag - type: Tag
id: AccessBreakerImmune id: AccessBreakerImmune # This tag marks an entity as immune to emagging.
- type: Tag - type: Tag
id: AirAlarm id: AirAlarm # Used by AtmosAlarmableComponent for syncing devices
- type: Tag - type: Tag
id: AirAlarmElectronics id: AirAlarmElectronics # ConstructionGraph: AirAlarm
- type: Tag - type: Tag
id: Airlock id: Airlock # Used in ConstructionGraph "Airlock" to navigate between regular, glass, and highsec airlocks
- type: Tag - type: Tag
id: AirSensor id: AirSensor # Used by AtmosAlarmableComponent for syncing devices
- type: Tag - type: Tag
id: AllowBiomeLoading # Entities with this tag will load terrain, even if a ghost. id: AllowBiomeLoading # Entities with this tag will load terrain, even if a ghost.
- type: Tag - type: Tag
id: AllowGhostShownByEvent id: AllowGhostShownByEvent # Used by GhostSystem to show ghosts (usually at round end)
- type: Tag - type: Tag
id: Ambrosia id: Ambrosia # ConstructionGraph: flowerwreath
- type: Tag - type: Tag
id: AnomalyHost id: AnomalyHost # Targeting whitelist: BaseAnomalyInjector
- type: Tag - type: Tag
id: AppraisalTool id: AppraisalTool # Storage whitelist: ClothingBeltUtility
- type: Tag - type: Tag
id: Apron id: Apron # ConstructionGraph: scraparmor
- type: Tag - type: Tag
id: Arrow id: Arrow # Storage whitelist: ClothingBeltQuiver
- type: Tag - type: Tag
id: ArtifactFragment id: ArtifactFragment # Storage whitelist: OreBag, CargoBounty: BountyArtifactFragment, ConstructionGraph: Artifact
- type: Tag - type: Tag
id: ATVKeys id: ATVKeys # Unused
## B ##
- type: Tag - type: Tag
id: Backpack id: Backpack # ConstructionGraph: ClothingBagPet
- type: Tag - type: Tag
id: Balloon id: Balloon # Used by BalloonPopperComponent/System to viciously maim helpless balloons
- type: Tag - type: Tag
id: Banana id: Banana # CargoBounty: BountyBanana
- type: Tag - type: Tag
id: BananaPeel id: BananaPeel # SpecialDigestible by OrganAnimalRuminantStomach, and several BananaClown ConstructionGraphs
- type: Tag - type: Tag
id: Bandana id: Bandana # CargoBounty: BountyBandana
- type: Tag - type: Tag
id: BaseballBat id: BaseballBat # CargoBounty: BountyBaseballBat
- type: Tag - type: Tag
id: BBQsauce id: BBQsauce # Storage whitelist: ClothingBeltChef and FoodCartHot, ItemMapper: ClothingBeltChef and FoodCartHot
- type: Tag - type: Tag
id: Bedsheet id: Bedsheet # CargoBounty: BountyBedsheet
- type: Tag - type: Tag
id: Bee id: Bee # Mode switch whitelisting for BuzzochloricBees (only damages non-bees)
- type: Tag - type: Tag
id: Beer id: Beer # CargoBounty: BountyBeer
- type: Tag - type: Tag
id: BikeHorn id: BikeHorn # ConstructionGraph: HonkBot, BananiumHorn
- type: Tag - type: Tag
id: Bloodpack id: Bloodpack # Storage whitelist: ClothingBeltMedical
- type: Tag - type: Tag
id: BlueprintAutolathe id: BlueprintAutolathe # Whitelist on BlueprintReceiverComponent on the autolate for linking this entity's BlueprintComponent
- type: Tag - type: Tag
id: BodyBag id: BodyBag # Storage whitelist: BoxBodyBag # TODO cardboard boxes shouldn't have whitelisting
- type: Tag - type: Tag
id: Boll id: Boll # MaterialStorage whitelist: Sheetifier
- type: Tag - type: Tag
id: Book id: Book # Storage whitelist: BorgModuleService, BooksBag, Bookshelf. Blacklisting on various entities whitelisting PaperComponent
- type: Tag - type: Tag
id: BorgArm id: BorgArm # ConstructionGraphs for various bots
- type: Tag - type: Tag
id: BorgHead id: BorgHead # Used by PartAssemblyComponent on CyborgEndoskeleton. Also in ConstructionGraphs for various bots
- type: Tag - type: Tag
id: BorgLArm id: BorgLArm # Used by PartAssemblyComponent on CyborgEndoskeleton
- type: Tag - type: Tag
id: BorgLLeg id: BorgLLeg # Used by PartAssemblyComponent on CyborgEndoskeleton
- type: Tag - type: Tag
id: BorgRArm id: BorgRArm # Used by PartAssemblyComponent on CyborgEndoskeleton
- type: Tag - type: Tag
id: BorgRLeg id: BorgRLeg # Used by PartAssemblyComponent on CyborgEndoskeleton
- type: Tag - type: Tag
id: BorgTorso id: BorgTorso # Used by PartAssemblyComponent on CyborgEndoskeleton
- type: Tag - type: Tag
id: BorgLeg id: BorgLeg # Used by PartAssemblyComponent on VimHarness
- type: Tag - type: Tag
id: BorgModuleCargo id: BorgModuleCargo # Cyborg module category for salvage and cargo
- type: Tag - type: Tag
id: BorgModuleEngineering id: BorgModuleEngineering # Cyborg module category for engineers and saboteurs
- type: Tag - type: Tag
id: BorgModuleGeneric id: BorgModuleGeneric # Cyborg module category for general purpose
- type: Tag - type: Tag
id: BorgModuleJanitor id: BorgModuleJanitor # Cyborg module category for janitors
- type: Tag - type: Tag
id: BorgModuleMedical id: BorgModuleMedical # Cyborg module category for doctors
- type: Tag - type: Tag
id: BorgModuleScience id: BorgModuleScience # Cyborg module category for scientists
- type: Tag - type: Tag
id: BorgModuleService id: BorgModuleService # Cyborg module category for bartenders, botanists, and more
- type: Tag - type: Tag
id: BorgModuleSyndicate id: BorgModuleSyndicate # Cyborg module category for evil red robots
- type: Tag - type: Tag
id: BorgModuleSyndicateAssault id: BorgModuleSyndicateAssault # Cyborg module category for extra evil red robots (nukies)
- type: Tag - type: Tag
id: Bot id: Bot # Unused
- type: Tag - type: Tag
id: BotanyHatchet id: BotanyHatchet # Storage whitelist: ClothingBeltPlant, ItemMapper: ClothingBeltPlant
- type: Tag - type: Tag
id: BotanyHoe id: BotanyHoe # Storage whitelist: ClothingBeltPlant, ItemMapper: ClothingBeltPlant
- type: Tag - type: Tag
id: BotanyShovel id: BotanyShovel # Storage whitelist: ClothingBeltPlant, ItemMapper: ClothingBeltPlant
- type: Tag # Used for specifically chemistry bottles
id: Bottle # Storage whitelist: ChemMaster, ChemBag, SmartFridge, ClothingBeltJanitor, ClothingBeltMedical, ClothingBeltPlant
- type: Tag - type: Tag
id: Bottle id: BoxCardboard # CargoBounty: BountyCardboardBox
- type: Tag - type: Tag
id: BoxCardboard id: BoxHug # Unused
- type: Tag - type: Tag
id: BoxHug id: Brain # Storage whitelist: MMI. CargoBounty: BountyBrain. FoodSequenceElement: Brain
- type: Tag - type: Tag
id: Brain id: BrassInstrument # MachineBoard construction: DawInstrumentMachineCircuitboard
- type: Tag - type: Tag
id: BrassInstrument id: Bread # CargoBounty: BountyBread. Blacklisted in BountyFruit and BountyVegetable
- type: Tag - type: Tag
id: Bread id: Briefcase # Unused
- type: Tag - type: Tag
id: Briefcase id: BrimFlatcapBrown # ConstructionGraph: BladedFlatcapBrown
- type: Tag - type: Tag
id: BrimFlatcapBrown id: BrimFlatcapGrey # ConstructionGraph: BladedFlatcapGrey
- type: Tag - type: Tag
id: BrimFlatcapGrey id: Brutepack # Storage whitelist: ClothingBeltMedical
- type: Tag - type: Tag
id: Brutepack id: Bucket # Storage whitelist: JanitorialTrolley. ItemMapper: JanitorialTrolley. ConstructionGraph: CleanBot, scraphelmet
- type: Tag - type: Tag
id: Bucket id: Burger # Unused x2 (this is the only place burger tag exists)
- type: Tag - type: Tag
id: Burger id: BulletFoam # BallisticAmmoProviderComponent whitelist for WeaponRifleFoam, FoamCrossbow, MagazineFoamBox, BoxDonkSoftBox
- type: Tag - type: Tag
id: BulletFoam id: Burnt # Storage whitelist: ashtray. Seemingly redundant
- type: Tag - type: Tag
id: Burnt id: Bun # FoodSequenceElement: BunTopBurger, CottonBunTopBurger
- type: Tag - type: Tag
id: Bun id: BypassDropChecks # Entities with this tag don't care about drop distance or walls (Aghost)
- type: Tag - type: Tag
id: BypassDropChecks id: BypassInteractionRangeChecks # Entities with this tag don't care about distance or walls when touching things (Aghost)
- type: Tag ## C ##
id: BypassInteractionRangeChecks
- type: Tag - type: Tag
id: CableCoil id: CableCoil
@@ -440,6 +447,8 @@
- type: Tag - type: Tag
id: CubanCarp id: CubanCarp
## D ##
- type: Tag - type: Tag
id: DeathAcidifier id: DeathAcidifier
@@ -509,6 +518,8 @@
- type: Tag - type: Tag
id: Duck id: Duck
## E ##
- type: Tag - type: Tag
id: Ectoplasm id: Ectoplasm
@@ -557,6 +568,14 @@
- type: Tag - type: Tag
id: ExplosivePassable id: ExplosivePassable
## F ##
- type: Tag
id: FakeMindShieldImplant
- type: Tag
id: FakeNukeDisk
- type: Tag - type: Tag
id: Figurine id: Figurine
@@ -614,6 +633,8 @@
- type: Tag - type: Tag
id: Fruit id: Fruit
## G ##
- type: Tag - type: Tag
id: Galaxythistle id: Galaxythistle
@@ -669,12 +690,6 @@
- type: Tag - type: Tag
id: GrenadeFlashBang id: GrenadeFlashBang
- type: Tag
id: HudMedical
- type: Tag
id: HudSecurity
- type: Tag - type: Tag
id: GuideEmbeded id: GuideEmbeded
@@ -687,6 +702,8 @@
- type: Tag - type: Tag
id: GunUpgradeReloadSpeed id: GunUpgradeReloadSpeed
## H ##
- type: Tag - type: Tag
id: Hamster id: Hamster
@@ -792,6 +809,14 @@
- type: Tag - type: Tag
id: Hotsauce id: Hotsauce
- type: Tag
id: HudMedical
- type: Tag
id: HudSecurity
## I ##
- type: Tag - type: Tag
id: Ice id: Ice
@@ -822,9 +847,13 @@
- type: Tag - type: Tag
id: InvalidForSurvivorAntag id: InvalidForSurvivorAntag
## J ##
- type: Tag - type: Tag
id: JawsOfLife id: JawsOfLife
## K ##
- type: Tag - type: Tag
id: Kangaroo id: Kangaroo
@@ -846,6 +875,8 @@
- type: Tag - type: Tag
id: KnockdownImmune id: KnockdownImmune
## L ##
- type: Tag - type: Tag
id: LavaBrig id: LavaBrig
@@ -858,6 +889,8 @@
- type: Tag - type: Tag
id: Lime id: Lime
## M ##
- type: Tag - type: Tag
id: Machete id: Machete
@@ -955,9 +988,6 @@
- type: Tag - type: Tag
id: MimeHappyHonk id: MimeHappyHonk
- type: Tag
id: FakeMindShieldImplant
- type: Tag - type: Tag
id: MindTransferTarget id: MindTransferTarget
@@ -991,6 +1021,8 @@
- type: Tag - type: Tag
id: Mushroom id: Mushroom
## N ##
- type: Tag - type: Tag
id: NoBlockAnchoring id: NoBlockAnchoring
@@ -1003,12 +1035,11 @@
- type: Tag - type: Tag
id: Nugget # for chicken nuggets id: Nugget # for chicken nuggets
- type: Tag
id: FakeNukeDisk
- type: Tag - type: Tag
id: NukeOpsUplink id: NukeOpsUplink
## O ##
- type: Tag - type: Tag
id: Ointment id: Ointment
@@ -1030,6 +1061,8 @@
- type: Tag - type: Tag
id: OreUranium id: OreUranium
## P ##
- type: Tag - type: Tag
id: Packet id: Packet
@@ -1159,9 +1192,13 @@
- type: Tag - type: Tag
id: ProximitySensor id: ProximitySensor
## Q ##
- type: Tag - type: Tag
id: QuantumSpinInverter id: QuantumSpinInverter
## R ##
- type: Tag - type: Tag
id: Radio id: Radio
@@ -1217,6 +1254,8 @@
- type: Tag - type: Tag
id: Ruminant id: Ruminant
## S ##
- type: Tag - type: Tag
id: SaltShaker id: SaltShaker
@@ -1391,6 +1430,8 @@
- type: Tag - type: Tag
id: Spellbook id: Spellbook
## T ##
- type: Tag - type: Tag
id: TabletopBoard id: TabletopBoard
@@ -1448,6 +1489,8 @@
- type: Tag - type: Tag
id: TurretControlElectronics # Used in the construction of sentry turret control panels id: TurretControlElectronics # Used in the construction of sentry turret control panels
## U ##
- type: Tag - type: Tag
id: Unimplantable id: Unimplantable
@@ -1463,6 +1506,8 @@
- type: Tag - type: Tag
id: UtilityKnife id: UtilityKnife
## V ##
- type: Tag - type: Tag
id: Vegetable id: Vegetable
@@ -1475,6 +1520,8 @@
- type: Tag - type: Tag
id: VoiceTrigger id: VoiceTrigger
## W ##
- type: Tag - type: Tag
id: Wall id: Wall
@@ -1550,6 +1597,8 @@
- type: Tag - type: Tag
id: WriteIgnoreStamps id: WriteIgnoreStamps
## X ##
- type: Tag - type: Tag
id: XenoborgModuleEngi id: XenoborgModuleEngi
@@ -1564,4 +1613,7 @@
- type: Tag - type: Tag
id: XenoborgModuleStealth id: XenoborgModuleStealth
## Y ##
## Z ##
# ALPHABETICAL # ALPHABETICAL