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()
{
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;
if (!settings.DummyTicker)
{

View File

@@ -132,7 +132,7 @@ public sealed class EmbedTest : InteractionTest
"Target has unexpected EmbeddedObjects count.");
// Wait for the cooldown between throws
await RunSeconds(Hands.ThrowCooldown.Seconds);
await RunSeconds(Hands!.ThrowCooldown.Seconds);
// Throw the second projectile
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>
protected async Task<NetEntity> PlaceInHands(EntitySpecifier entity, bool enableToggleable = true)
{
if (Hands == null)
{
Assert.Fail("No HandsComponent");
return default;
}
if (Hands.ActiveHandId == null)
{
Assert.Fail("No active hand");
@@ -210,6 +216,12 @@ public abstract partial class InteractionTest
{
entity ??= Target;
if (Hands == null)
{
Assert.Fail("No HandsComponent");
return;
}
if (Hands.ActiveHandId == null)
{
Assert.Fail("No active hand");
@@ -860,7 +872,7 @@ public abstract partial class InteractionTest
/// List of currently active DoAfters on the player.
/// </summary>
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

View File

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

View File

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

View File

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

View File

@@ -7,6 +7,7 @@ using Content.Shared.DoAfter;
using Content.Shared.DragDrop;
using Content.Shared.Examine;
using Content.Shared.Hands;
using Content.Shared.Humanoid;
using Content.Shared.IdentityManagement;
using Content.Shared.Interaction;
using Content.Shared.Interaction.Events;
@@ -238,8 +239,11 @@ public sealed class SharedKitchenSpikeSystem : EntitySystem
args.Target.Value,
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,
LogImpact.High,
logSeverity,
$"{ToPrettyString(args.User):user} put {ToPrettyString(args.Target):target} on the {ToPrettyString(ent):spike}");
_audioSystem.PlayPredicted(ent.Comp.SpikeSound, ent, args.User);
@@ -316,8 +320,10 @@ public sealed class SharedKitchenSpikeSystem : EntitySystem
{
_bodySystem.GibBody(args.Target.Value, true);
var logSeverity = HasComp<HumanoidAppearanceComponent>(args.Target) ? LogImpact.Extreme : LogImpact.High;
_logger.Add(LogType.Gib,
LogImpact.Extreme,
logSeverity,
$"{ToPrettyString(args.User):user} finished butchering {ToPrettyString(args.Target):target} on the {ToPrettyString(ent):spike}");
}
else
@@ -325,8 +331,10 @@ public sealed class SharedKitchenSpikeSystem : EntitySystem
EnsureComp<KitchenSpikeVictimComponent>(args.Target.Value);
_damageableSystem.TryChangeDamage(args.Target, ent.Comp.ButcherDamage, true);
// Log severity for damaging other entities is normally medium.
_logger.Add(LogType.Action,
LogImpact.Extreme,
LogImpact.Medium,
$"{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
table: !type:AllSelector
children:
- !type:NestedSelector
tableId: RandomSatchelBurgerTable #2x medium
- !type:NestedSelector
tableId: RandomSatchelPresentsOrToysTable #3x small
- !type:NestedSelector
tableId: RandomSatchelCashTable #1x small
- !type:NestedSelector
tableId: RandomSatchelWeaponTable #5x small
- !type:NestedSelector
tableId: RandomSatchelBurgerTable #5x small
- !type:NestedSelector
tableId: RandomSatchelGenericTableSmall #1x small
- !type:NestedSelector
@@ -309,24 +309,18 @@
amount: !type:RangeNumberSelector
range: 1, 5
- type: entityTable #5x small
- type: entityTable #2x medium
id: RandomSatchelBurgerTable
table: !type:GroupSelector
rolls: !type:RangeNumberSelector
range: 1, 2
children:
- id: SpaceCash100
weight: 10
- id: FoodBurgerAppendix
amount: !type:RangeNumberSelector
range: 1, 5
- id: FoodBurgerEmpowered
amount: !type:RangeNumberSelector
range: 1, 5
- id: FoodBurgerClown
amount: !type:RangeNumberSelector
range: 1, 5
- id: FoodBurgerGhost
amount: !type:RangeNumberSelector
range: 1, 5
- type: entityTable #1x small
id: RandomSatchelGenericTableSmall

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -11,10 +11,8 @@
blacklist:
components:
- 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:
- 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
openToolQualityNeeded: Slicing
closeToolQualityNeeded: Slicing # Should probably be stitching or something if that gets added

View File

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

View File

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