Merge remote-tracking branch 'space-wizards/master'
# Conflicts: # Content.Shared/Access/Components/AccessReaderComponent.cs # Resources/Locale/en-US/_strings/commands/melee-spread-command.ftl # Resources/Locale/en-US/_strings/commands/persistence-save-command.ftl # Resources/Locale/en-US/_strings/commands/show-access-readers-command.ftl # Resources/Locale/en-US/_strings/commands/show-emergency-shuttle-command.ftl # Resources/Locale/en-US/_strings/persistence/command.ftl # Resources/Prototypes/Catalog/Fills/Crates/armory.yml # Resources/Prototypes/Catalog/Fills/Items/toolboxes.yml # Resources/Prototypes/Entities/Clothing/Belt/belts.yml # Resources/Prototypes/Entities/Clothing/Head/scraphelmet.yml # Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml # Resources/Prototypes/Entities/Clothing/OuterClothing/misc.yml # Resources/Prototypes/Entities/Clothing/OuterClothing/scraparmor.yml # Resources/Prototypes/Entities/Objects/Fun/pai.yml # Resources/Prototypes/Entities/Objects/Weapons/Guns/LMGs/lmgs.yml # Resources/Prototypes/Recipes/Crafting/improvised.yml
This commit is contained in:
commit
0cbccf6f0e
283 changed files with 2727 additions and 732 deletions
|
|
@ -4,39 +4,20 @@ using Robust.Shared.Console;
|
|||
|
||||
namespace Content.Client.Access.Commands;
|
||||
|
||||
public sealed class ShowAccessReadersCommand : IConsoleCommand
|
||||
public sealed class ShowAccessReadersCommand : LocalizedEntityCommands
|
||||
{
|
||||
public string Command => "showaccessreaders";
|
||||
[Dependency] private readonly IOverlayManager _overlay = default!;
|
||||
[Dependency] private readonly IResourceCache _cache = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _xform = default!;
|
||||
|
||||
public string Description => "Toggles showing access reader permissions on the map";
|
||||
public string Help => """
|
||||
Overlay Info:
|
||||
-Disabled | The access reader is disabled
|
||||
+Unrestricted | The access reader has no restrictions
|
||||
+Set [Index]: [Tag Name]| A tag in an access set (accessor needs all tags in the set to be allowed by the set)
|
||||
+Key [StationUid]: [StationRecordKeyId] | A StationRecordKey that is allowed
|
||||
-Tag [Tag Name] | A tag that is not allowed (takes priority over other allows)
|
||||
""";
|
||||
public void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||
public override string Command => "showaccessreaders";
|
||||
|
||||
public override void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||
{
|
||||
var collection = IoCManager.Instance;
|
||||
var existing = _overlay.RemoveOverlay<AccessOverlay>();
|
||||
if (!existing)
|
||||
_overlay.AddOverlay(new AccessOverlay(EntityManager, _cache, _xform));
|
||||
|
||||
if (collection == null)
|
||||
return;
|
||||
|
||||
var overlay = collection.Resolve<IOverlayManager>();
|
||||
|
||||
if (overlay.RemoveOverlay<AccessOverlay>())
|
||||
{
|
||||
shell.WriteLine($"Set access reader debug overlay to false");
|
||||
return;
|
||||
}
|
||||
|
||||
var entManager = collection.Resolve<IEntityManager>();
|
||||
var cache = collection.Resolve<IResourceCache>();
|
||||
var xform = entManager.System<SharedTransformSystem>();
|
||||
|
||||
overlay.AddOverlay(new AccessOverlay(entManager, cache, xform));
|
||||
shell.WriteLine($"Set access reader debug overlay to true");
|
||||
shell.WriteLine(Loc.GetString($"cmd-showaccessreaders-status", ("status", !existing)));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ namespace Content.Client.Actions
|
|||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
[Dependency] private readonly IResourceManager _resources = default!;
|
||||
[Dependency] private readonly ISerializationManager _serialization = default!;
|
||||
[Dependency] private readonly MetaDataSystem _metaData = default!;
|
||||
|
||||
public event Action<EntityUid>? OnActionAdded;
|
||||
|
|
|
|||
|
|
@ -11,8 +11,6 @@ namespace Content.Client.Clothing.Systems;
|
|||
// All valid items for chameleon are calculated on client startup and stored in dictionary.
|
||||
public sealed class ChameleonClothingSystem : SharedChameleonClothingSystem
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
|
|
|||
|
|
@ -136,6 +136,8 @@ namespace Content.Client.Entry
|
|||
_prototypeManager.RegisterIgnore("sponsorLoadout"); // Sunrise-Sponsors
|
||||
_prototypeManager.RegisterIgnore("holidayGiveawayItem"); // Sunrise-Edit
|
||||
_prototypeManager.RegisterIgnore("ghostRoleRaffleDecider");
|
||||
_prototypeManager.RegisterIgnore("codewordGenerator");
|
||||
_prototypeManager.RegisterIgnore("codewordFaction");
|
||||
|
||||
_componentFactory.GenerateNetIds();
|
||||
_adminManager.Initialize();
|
||||
|
|
|
|||
|
|
@ -50,6 +50,18 @@ namespace Content.Client.Inventory
|
|||
[ViewVariables]
|
||||
private readonly EntityUid _virtualHiddenEntity;
|
||||
|
||||
/// <summary>
|
||||
/// The current amount of added hand buttons.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
private int _handCount;
|
||||
|
||||
/// <summary>
|
||||
/// The current shape of the inventory, needed to calculate the window size.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
private Vector2i _inventoryDimensions;
|
||||
|
||||
public StrippableBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
|
||||
{
|
||||
_examine = EntMan.System<ExamineSystem>();
|
||||
|
|
@ -93,6 +105,8 @@ namespace Content.Client.Inventory
|
|||
return;
|
||||
|
||||
_strippingMenu.ClearButtons();
|
||||
_handCount = 0;
|
||||
_inventoryDimensions = Vector2i.Zero;
|
||||
|
||||
if (EntMan.TryGetComponent<InventoryComponent>(Owner, out var inv))
|
||||
{
|
||||
|
|
@ -152,9 +166,15 @@ namespace Content.Client.Inventory
|
|||
// TODO allow windows to resize based on content's desired size
|
||||
|
||||
// for now: shit-code
|
||||
// this breaks for drones (too many hands, lots of empty vertical space), and looks shit for monkeys and the like.
|
||||
// but the window is realizable, so eh.
|
||||
_strippingMenu.SetSize = new Vector2(220, snare?.IsEnsnared == true ? 550 : 530);
|
||||
// calculate the window size manually
|
||||
// +20 horizontally and vertically from the ContentsContainer margin
|
||||
// +16 vertically from the BoxContainer margin
|
||||
// +27 vertically from the window header
|
||||
var horizontalMenuSize = Math.Max(200, Math.Max(_handCount, _inventoryDimensions.X + 1) * (SlotControl.DefaultButtonSize + ButtonSeparation) + 20);
|
||||
var verticalMenuSize = Math.Max(200, (_inventoryDimensions.Y + (_handCount > 0 ? 2 : 1)) * (SlotControl.DefaultButtonSize + ButtonSeparation) + 53);
|
||||
if (snare?.IsEnsnared == true)
|
||||
verticalMenuSize += 20;
|
||||
_strippingMenu.SetSize = new Vector2(horizontalMenuSize, verticalMenuSize);
|
||||
}
|
||||
|
||||
private void AddHandButton(Hand hand)
|
||||
|
|
@ -172,6 +192,8 @@ namespace Content.Client.Inventory
|
|||
|
||||
UpdateEntityIcon(button, hand.HeldEntity);
|
||||
_strippingMenu!.HandsContainer.AddChild(button);
|
||||
LayoutContainer.SetPosition(button, new Vector2i(_handCount, 0) * (SlotControl.DefaultButtonSize + ButtonSeparation));
|
||||
_handCount++;
|
||||
}
|
||||
|
||||
private void SlotPressed(GUIBoundKeyEventArgs ev, SlotControl slot)
|
||||
|
|
@ -220,6 +242,10 @@ namespace Content.Client.Inventory
|
|||
UpdateEntityIcon(button, entity);
|
||||
|
||||
LayoutContainer.SetPosition(button, slotDef.StrippingWindowPos * (SlotControl.DefaultButtonSize + ButtonSeparation));
|
||||
if (slotDef.StrippingWindowPos.X > _inventoryDimensions.X)
|
||||
_inventoryDimensions = new Vector2i(slotDef.StrippingWindowPos.X, _inventoryDimensions.Y);
|
||||
if (slotDef.StrippingWindowPos.Y > _inventoryDimensions.Y)
|
||||
_inventoryDimensions = new Vector2i(_inventoryDimensions.X, slotDef.StrippingWindowPos.Y);
|
||||
}
|
||||
|
||||
private void UpdateEntityIcon(SlotControl button, EntityUid? entity)
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ public sealed class JetpackSystem : SharedJetpackSystem
|
|||
[Dependency] private readonly ClothingSystem _clothing = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
[Dependency] private readonly SharedMapSystem _mapSystem = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,15 +3,15 @@ using Robust.Shared.Console;
|
|||
|
||||
namespace Content.Client.Shuttles.Commands;
|
||||
|
||||
public sealed class ShowEmergencyShuttleCommand : IConsoleCommand
|
||||
public sealed class ShowEmergencyShuttleCommand : LocalizedEntityCommands
|
||||
{
|
||||
public string Command => "showemergencyshuttle";
|
||||
public string Description => "Shows the expected position of the emergency shuttle";
|
||||
public string Help => $"{Command}";
|
||||
public void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||
[Dependency] private readonly ShuttleSystem _shuttle = default!;
|
||||
|
||||
public override string Command => "showemergencyshuttle";
|
||||
|
||||
public override void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||
{
|
||||
var tstalker = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<ShuttleSystem>();
|
||||
tstalker.EnableShuttlePosition ^= true;
|
||||
shell.WriteLine($"Set emergency shuttle debug to {tstalker.EnableShuttlePosition}");
|
||||
_shuttle.EnableShuttlePosition ^= true;
|
||||
shell.WriteLine(Loc.GetString($"cmd-showemergencyshuttle-status", ("status", _shuttle.EnableShuttlePosition)));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ namespace Content.Client.Strip
|
|||
public sealed class StrippingMenu : DefaultWindow
|
||||
{
|
||||
public LayoutContainer InventoryContainer = new();
|
||||
public BoxContainer HandsContainer = new() { Orientation = LayoutOrientation.Horizontal };
|
||||
public LayoutContainer HandsContainer = new();
|
||||
public BoxContainer SnareContainer = new();
|
||||
public bool Dirty = true;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,39 +3,33 @@ using Robust.Client.Graphics;
|
|||
using Robust.Client.Input;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.Map;
|
||||
|
||||
namespace Content.Client.Weapons.Melee;
|
||||
|
||||
|
||||
public sealed class MeleeSpreadCommand : IConsoleCommand
|
||||
public sealed class MeleeSpreadCommand : LocalizedEntityCommands
|
||||
{
|
||||
public string Command => "showmeleespread";
|
||||
public string Description => "Shows the current weapon's range and arc for debugging";
|
||||
public string Help => $"{Command}";
|
||||
public void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||
[Dependency] private readonly IEyeManager _eyeManager = default!;
|
||||
[Dependency] private readonly IInputManager _inputManager = default!;
|
||||
[Dependency] private readonly IOverlayManager _overlay = default!;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
[Dependency] private readonly MeleeWeaponSystem _meleeSystem = default!;
|
||||
[Dependency] private readonly SharedCombatModeSystem _combatSystem = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
|
||||
|
||||
public override string Command => "showmeleespread";
|
||||
|
||||
public override void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||
{
|
||||
var collection = IoCManager.Instance;
|
||||
|
||||
if (collection == null)
|
||||
if (_overlay.RemoveOverlay<MeleeArcOverlay>())
|
||||
return;
|
||||
|
||||
var overlayManager = collection.Resolve<IOverlayManager>();
|
||||
|
||||
if (overlayManager.RemoveOverlay<MeleeArcOverlay>())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var sysManager = collection.Resolve<IEntitySystemManager>();
|
||||
|
||||
overlayManager.AddOverlay(new MeleeArcOverlay(
|
||||
collection.Resolve<IEntityManager>(),
|
||||
collection.Resolve<IEyeManager>(),
|
||||
collection.Resolve<IInputManager>(),
|
||||
collection.Resolve<IPlayerManager>(),
|
||||
sysManager.GetEntitySystem<MeleeWeaponSystem>(),
|
||||
sysManager.GetEntitySystem<SharedCombatModeSystem>(),
|
||||
sysManager.GetEntitySystem<SharedTransformSystem>()));
|
||||
_overlay.AddOverlay(new MeleeArcOverlay(
|
||||
EntityManager,
|
||||
_eyeManager,
|
||||
_inputManager,
|
||||
_playerManager,
|
||||
_meleeSystem,
|
||||
_combatSystem,
|
||||
_transformSystem));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Content.Shared.Access;
|
||||
using Content.Shared.Access.Components;
|
||||
using Content.Shared.Access.Systems;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.IntegrationTests.Tests.Access
|
||||
|
|
@ -12,6 +12,15 @@ namespace Content.IntegrationTests.Tests.Access
|
|||
[TestOf(typeof(AccessReaderComponent))]
|
||||
public sealed class AccessReaderTest
|
||||
{
|
||||
[TestPrototypes]
|
||||
private const string Prototypes = @"
|
||||
- type: entity
|
||||
id: TestAccessReader
|
||||
name: access reader
|
||||
components:
|
||||
- type: AccessReader
|
||||
";
|
||||
|
||||
[Test]
|
||||
public async Task TestTags()
|
||||
{
|
||||
|
|
@ -19,13 +28,13 @@ namespace Content.IntegrationTests.Tests.Access
|
|||
var server = pair.Server;
|
||||
var entityManager = server.ResolveDependency<IEntityManager>();
|
||||
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
var system = entityManager.System<AccessReaderSystem>();
|
||||
var ent = entityManager.SpawnEntity("TestAccessReader", MapCoordinates.Nullspace);
|
||||
var reader = new Entity<AccessReaderComponent>(ent, entityManager.GetComponent<AccessReaderComponent>(ent));
|
||||
|
||||
// test empty
|
||||
var reader = new AccessReaderComponent();
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "Foo" }, reader), Is.True);
|
||||
|
|
@ -34,8 +43,7 @@ namespace Content.IntegrationTests.Tests.Access
|
|||
});
|
||||
|
||||
// test deny
|
||||
reader = new AccessReaderComponent();
|
||||
reader.DenyTags.Add("A");
|
||||
system.AddDenyTag(reader, "A");
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "Foo" }, reader), Is.True);
|
||||
|
|
@ -43,10 +51,10 @@ namespace Content.IntegrationTests.Tests.Access
|
|||
Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A", "Foo" }, reader), Is.False);
|
||||
Assert.That(system.AreAccessTagsAllowed(Array.Empty<ProtoId<AccessLevelPrototype>>(), reader), Is.True);
|
||||
});
|
||||
system.ClearDenyTags(reader);
|
||||
|
||||
// test one list
|
||||
reader = new AccessReaderComponent();
|
||||
reader.AccessLists.Add(new HashSet<ProtoId<AccessLevelPrototype>> { "A" });
|
||||
system.AddAccess(reader, "A");
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A" }, reader), Is.True);
|
||||
|
|
@ -54,10 +62,10 @@ namespace Content.IntegrationTests.Tests.Access
|
|||
Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A", "B" }, reader), Is.True);
|
||||
Assert.That(system.AreAccessTagsAllowed(Array.Empty<ProtoId<AccessLevelPrototype>>(), reader), Is.False);
|
||||
});
|
||||
system.ClearAccesses(reader);
|
||||
|
||||
// test one list - two items
|
||||
reader = new AccessReaderComponent();
|
||||
reader.AccessLists.Add(new HashSet<ProtoId<AccessLevelPrototype>> { "A", "B" });
|
||||
system.AddAccess(reader, new HashSet<ProtoId<AccessLevelPrototype>> { "A", "B" });
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A" }, reader), Is.False);
|
||||
|
|
@ -65,11 +73,14 @@ namespace Content.IntegrationTests.Tests.Access
|
|||
Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A", "B" }, reader), Is.True);
|
||||
Assert.That(system.AreAccessTagsAllowed(Array.Empty<ProtoId<AccessLevelPrototype>>(), reader), Is.False);
|
||||
});
|
||||
system.ClearAccesses(reader);
|
||||
|
||||
// test two list
|
||||
reader = new AccessReaderComponent();
|
||||
reader.AccessLists.Add(new HashSet<ProtoId<AccessLevelPrototype>> { "A" });
|
||||
reader.AccessLists.Add(new HashSet<ProtoId<AccessLevelPrototype>> { "B", "C" });
|
||||
var accesses = new List<HashSet<ProtoId<AccessLevelPrototype>>>() {
|
||||
new HashSet<ProtoId<AccessLevelPrototype>> () { "A" },
|
||||
new HashSet<ProtoId<AccessLevelPrototype>> () { "B", "C" }
|
||||
};
|
||||
system.AddAccesses(reader, accesses);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A" }, reader), Is.True);
|
||||
|
|
@ -79,11 +90,11 @@ namespace Content.IntegrationTests.Tests.Access
|
|||
Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "C", "B", "A" }, reader), Is.True);
|
||||
Assert.That(system.AreAccessTagsAllowed(Array.Empty<ProtoId<AccessLevelPrototype>>(), reader), Is.False);
|
||||
});
|
||||
system.ClearAccesses(reader);
|
||||
|
||||
// test deny list
|
||||
reader = new AccessReaderComponent();
|
||||
reader.AccessLists.Add(new HashSet<ProtoId<AccessLevelPrototype>> { "A" });
|
||||
reader.DenyTags.Add("B");
|
||||
system.AddAccess(reader, new HashSet<ProtoId<AccessLevelPrototype>> { "A" });
|
||||
system.AddDenyTag(reader, "B");
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A" }, reader), Is.True);
|
||||
|
|
@ -91,6 +102,8 @@ namespace Content.IntegrationTests.Tests.Access
|
|||
Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A", "B" }, reader), Is.False);
|
||||
Assert.That(system.AreAccessTagsAllowed(Array.Empty<ProtoId<AccessLevelPrototype>>(), reader), Is.False);
|
||||
});
|
||||
system.ClearAccesses(reader);
|
||||
system.ClearDenyTags(reader);
|
||||
});
|
||||
await pair.CleanReturnAsync();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ using Content.Shared.FixedPoint;
|
|||
using Content.Shared.GameTicking;
|
||||
using Content.Shared.Hands.Components;
|
||||
using Content.Shared.Inventory;
|
||||
using Content.Shared.NPC.Prototypes;
|
||||
using Content.Shared.NPC.Systems;
|
||||
using Content.Shared.NukeOps;
|
||||
using Content.Shared.Pinpointer;
|
||||
|
|
@ -25,12 +26,16 @@ using Content.Shared.Station.Components;
|
|||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.IntegrationTests.Tests.GameRules;
|
||||
|
||||
[TestFixture]
|
||||
public sealed class NukeOpsTest
|
||||
{
|
||||
private static readonly ProtoId<NpcFactionPrototype> SyndicateFaction = "Syndicate";
|
||||
private static readonly ProtoId<NpcFactionPrototype> NanotrasenFaction = "NanoTrasen";
|
||||
|
||||
/// <summary>
|
||||
/// Check that a nuke ops game mode can start without issue. I.e., that the nuke station and such all get loaded.
|
||||
/// </summary>
|
||||
|
|
@ -121,8 +126,8 @@ public sealed class NukeOpsTest
|
|||
Assert.That(entMan.HasComponent<NukeOperativeComponent>(player));
|
||||
Assert.That(roleSys.MindIsAntagonist(mind));
|
||||
Assert.That(roleSys.MindHasRole<NukeopsRoleComponent>(mind));
|
||||
Assert.That(factionSys.IsMember(player, "Syndicate"), Is.True);
|
||||
Assert.That(factionSys.IsMember(player, "NanoTrasen"), Is.False);
|
||||
Assert.That(factionSys.IsMember(player, SyndicateFaction), Is.True);
|
||||
Assert.That(factionSys.IsMember(player, NanotrasenFaction), Is.False);
|
||||
var roles = roleSys.MindGetAllRoleInfo(mind);
|
||||
var cmdRoles = roles.Where(x => x.Prototype == "NukeopsCommander");
|
||||
Assert.That(cmdRoles.Count(), Is.EqualTo(1));
|
||||
|
|
@ -132,8 +137,8 @@ public sealed class NukeOpsTest
|
|||
Assert.That(entMan.HasComponent<NukeOperativeComponent>(dummyEnts[1]));
|
||||
Assert.That(roleSys.MindIsAntagonist(dummyMind));
|
||||
Assert.That(roleSys.MindHasRole<NukeopsRoleComponent>(dummyMind));
|
||||
Assert.That(factionSys.IsMember(dummyEnts[1], "Syndicate"), Is.True);
|
||||
Assert.That(factionSys.IsMember(dummyEnts[1], "NanoTrasen"), Is.False);
|
||||
Assert.That(factionSys.IsMember(dummyEnts[1], SyndicateFaction), Is.True);
|
||||
Assert.That(factionSys.IsMember(dummyEnts[1], NanotrasenFaction), Is.False);
|
||||
roles = roleSys.MindGetAllRoleInfo(dummyMind);
|
||||
cmdRoles = roles.Where(x => x.Prototype == "NukeopsMedic");
|
||||
Assert.That(cmdRoles.Count(), Is.EqualTo(1));
|
||||
|
|
@ -148,8 +153,8 @@ public sealed class NukeOpsTest
|
|||
Assert.That(entMan.HasComponent<NukeOperativeComponent>(ent), Is.False);
|
||||
Assert.That(roleSys.MindIsAntagonist(mindCrew), Is.False);
|
||||
Assert.That(roleSys.MindHasRole<NukeopsRoleComponent>(mindCrew), Is.False);
|
||||
Assert.That(factionSys.IsMember(ent, "Syndicate"), Is.False);
|
||||
Assert.That(factionSys.IsMember(ent, "NanoTrasen"), Is.True);
|
||||
Assert.That(factionSys.IsMember(ent, SyndicateFaction), Is.False);
|
||||
Assert.That(factionSys.IsMember(ent, NanotrasenFaction), Is.True);
|
||||
var nukeroles = new List<string>() { "Nukeops", "NukeopsMedic", "NukeopsCommander" };
|
||||
Assert.That(roleSys.MindGetAllRoleInfo(mindCrew).Any(x => nukeroles.Contains(x.Prototype)), Is.False);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ using Content.Server.Roles;
|
|||
using Content.Shared.GameTicking;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Content.Shared.Mind;
|
||||
using Content.Shared.NPC.Prototypes;
|
||||
using Content.Shared.NPC.Systems;
|
||||
using Content.Shared.Objectives.Components;
|
||||
using Robust.Shared.GameObjects;
|
||||
|
|
@ -20,6 +21,8 @@ public sealed class TraitorRuleTest
|
|||
{
|
||||
private const string TraitorGameRuleProtoId = "Traitor";
|
||||
private const string TraitorAntagRoleName = "Traitor";
|
||||
private static readonly ProtoId<NpcFactionPrototype> SyndicateFaction = "Syndicate";
|
||||
private static readonly ProtoId<NpcFactionPrototype> NanotrasenFaction = "NanoTrasen";
|
||||
|
||||
[Test]
|
||||
public async Task TestTraitorObjectives()
|
||||
|
|
@ -108,8 +111,8 @@ public sealed class TraitorRuleTest
|
|||
// Make sure the player is a traitor.
|
||||
var mind = mindSys.GetMind(player)!.Value;
|
||||
Assert.That(roleSys.MindIsAntagonist(mind));
|
||||
Assert.That(factionSys.IsMember(player, "Syndicate"), Is.True);
|
||||
Assert.That(factionSys.IsMember(player, "NanoTrasen"), Is.False);
|
||||
Assert.That(factionSys.IsMember(player, SyndicateFaction), Is.True);
|
||||
Assert.That(factionSys.IsMember(player, NanotrasenFaction), Is.False);
|
||||
Assert.That(traitorRule.TotalTraitors, Is.EqualTo(1));
|
||||
Assert.That(traitorRule.TraitorMinds[0], Is.EqualTo(mind));
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using Content.Server.Wires;
|
||||
using Content.Shared.Access;
|
||||
using Content.Shared.Access.Components;
|
||||
using Content.Shared.Access.Systems;
|
||||
using Content.Shared.Wires;
|
||||
|
||||
namespace Content.Server.Access;
|
||||
|
|
@ -23,23 +24,21 @@ public sealed partial class AccessWireAction : ComponentWireAction<AccessReaderC
|
|||
public override bool Cut(EntityUid user, Wire wire, AccessReaderComponent comp)
|
||||
{
|
||||
WiresSystem.TryCancelWireAction(wire.Owner, PulseTimeoutKey.Key);
|
||||
comp.Enabled = false;
|
||||
EntityManager.Dirty(wire.Owner, comp);
|
||||
EntityManager.System<AccessReaderSystem>().SetActive((wire.Owner, comp), false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool Mend(EntityUid user, Wire wire, AccessReaderComponent comp)
|
||||
{
|
||||
comp.Enabled = true;
|
||||
EntityManager.Dirty(wire.Owner, comp);
|
||||
EntityManager.System<AccessReaderSystem>().SetActive((wire.Owner, comp), true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void Pulse(EntityUid user, Wire wire, AccessReaderComponent comp)
|
||||
{
|
||||
comp.Enabled = false;
|
||||
EntityManager.Dirty(wire.Owner, comp);
|
||||
EntityManager.System<AccessReaderSystem>().SetActive((wire.Owner, comp), false);
|
||||
WiresSystem.StartWireAction(wire.Owner, _pulseTimeout, PulseTimeoutKey.Key, new TimedWireEvent(AwaitPulseCancel, wire));
|
||||
}
|
||||
|
||||
|
|
@ -57,8 +56,7 @@ public sealed partial class AccessWireAction : ComponentWireAction<AccessReaderC
|
|||
{
|
||||
if (EntityManager.TryGetComponent<AccessReaderComponent>(wire.Owner, out var access))
|
||||
{
|
||||
access.Enabled = true;
|
||||
EntityManager.Dirty(wire.Owner, access);
|
||||
EntityManager.System<AccessReaderSystem>().SetActive((wire.Owner, access), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
using Content.Server.Administration;
|
||||
using Content.Shared.Access.Components;
|
||||
using Content.Shared.Access.Systems;
|
||||
using Content.Shared.Administration;
|
||||
using Robust.Shared.Toolshed;
|
||||
using Robust.Shared.Toolshed.Syntax;
|
||||
|
||||
namespace Content.Server.Access;
|
||||
|
||||
|
|
@ -19,7 +19,7 @@ public sealed class AddAccessLogCommand : ToolshedCommand
|
|||
ctx.WriteLine($"WARNING: Surpassing the limit of the log by {accessLogCount - accessReader.AccessLogLimit+1} entries!");
|
||||
|
||||
var accessTime = TimeSpan.FromSeconds(seconds);
|
||||
accessReader.AccessLog.Enqueue(new AccessRecord(accessTime, accessor));
|
||||
EntityManager.System<AccessReaderSystem>().LogAccess((input, accessReader), accessor, accessTime, true);
|
||||
ctx.WriteLine($"Successfully added access log to {input} with this information inside:\n " +
|
||||
$"Time of access: {accessTime}\n " +
|
||||
$"Accessed by: {accessor}");
|
||||
|
|
|
|||
|
|
@ -37,21 +37,21 @@ public sealed partial class LogWireAction : ComponentWireAction<AccessReaderComp
|
|||
public override bool Cut(EntityUid user, Wire wire, AccessReaderComponent comp)
|
||||
{
|
||||
WiresSystem.TryCancelWireAction(wire.Owner, PulseTimeoutKey.Key);
|
||||
comp.LoggingDisabled = true;
|
||||
EntityManager.Dirty(wire.Owner, comp);
|
||||
EntityManager.System<AccessReaderSystem>().SetLoggingActive((wire.Owner, comp), false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool Mend(EntityUid user, Wire wire, AccessReaderComponent comp)
|
||||
{
|
||||
comp.LoggingDisabled = false;
|
||||
EntityManager.System<AccessReaderSystem>().SetLoggingActive((wire.Owner, comp), true);
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void Pulse(EntityUid user, Wire wire, AccessReaderComponent comp)
|
||||
{
|
||||
_access.LogAccess((wire.Owner, comp), Loc.GetString(PulseLog));
|
||||
comp.LoggingDisabled = true;
|
||||
EntityManager.System<AccessReaderSystem>().SetLoggingActive((wire.Owner, comp), false);
|
||||
WiresSystem.StartWireAction(wire.Owner, PulseTimeout, PulseTimeoutKey.Key, new TimedWireEvent(AwaitPulseCancel, wire));
|
||||
}
|
||||
|
||||
|
|
@ -64,7 +64,7 @@ public sealed partial class LogWireAction : ComponentWireAction<AccessReaderComp
|
|||
private void AwaitPulseCancel(Wire wire)
|
||||
{
|
||||
if (!wire.IsCut && EntityManager.TryGetComponent<AccessReaderComponent>(wire.Owner, out var comp))
|
||||
comp.LoggingDisabled = false;
|
||||
EntityManager.System<AccessReaderSystem>().SetLoggingActive((wire.Owner, comp), true);
|
||||
}
|
||||
|
||||
private enum PulseTimeoutKey : byte
|
||||
|
|
|
|||
|
|
@ -168,21 +168,6 @@ public sealed class AccessOverriderSystem : SharedAccessOverriderSystem
|
|||
return accessList;
|
||||
}
|
||||
|
||||
private List<HashSet<ProtoId<AccessLevelPrototype>>> ConvertAccessListToHashSet(List<ProtoId<AccessLevelPrototype>> accessList)
|
||||
{
|
||||
List<HashSet<ProtoId<AccessLevelPrototype>>> accessHashsets = new List<HashSet<ProtoId<AccessLevelPrototype>>>();
|
||||
|
||||
if (accessList != null && accessList.Any())
|
||||
{
|
||||
foreach (ProtoId<AccessLevelPrototype> access in accessList)
|
||||
{
|
||||
accessHashsets.Add(new HashSet<ProtoId<AccessLevelPrototype>>() { access });
|
||||
}
|
||||
}
|
||||
|
||||
return accessHashsets;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called whenever an access button is pressed, adding or removing that access requirement from the target access reader.
|
||||
/// </summary>
|
||||
|
|
@ -244,12 +229,10 @@ public sealed class AccessOverriderSystem : SharedAccessOverriderSystem
|
|||
_adminLogger.Add(LogType.Action, LogImpact.High,
|
||||
$"{ToPrettyString(player):player} has modified {ToPrettyString(accessReaderEnt.Value):entity} with the following allowed access level holders: [{string.Join(", ", addedTags.Union(removedTags))}] [{string.Join(", ", newAccessList)}]");
|
||||
|
||||
accessReaderEnt.Value.Comp.AccessLists = ConvertAccessListToHashSet(newAccessList);
|
||||
_accessReader.SetAccesses(accessReaderEnt.Value, newAccessList);
|
||||
|
||||
var ev = new OnAccessOverriderAccessUpdatedEvent(player);
|
||||
RaiseLocalEvent(component.TargetAccessReaderId, ref ev);
|
||||
|
||||
Dirty(accessReaderEnt.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ namespace Content.Server.Actions;
|
|||
public sealed class ActionOnInteractSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly SharedActionsSystem _actions = default!;
|
||||
[Dependency] private readonly ActionContainerSystem _actionContainer = default!;
|
||||
[Dependency] private readonly SharedChargesSystem _charges = default!;
|
||||
|
|
|
|||
|
|
@ -12,12 +12,10 @@ namespace Content.Server.Administration.Commands;
|
|||
public sealed class PersistenceSave : LocalizedEntityCommands
|
||||
{
|
||||
[Dependency] private readonly IConfigurationManager _config = default!;
|
||||
[Dependency] private readonly IEntitySystemManager _system = default!;
|
||||
[Dependency] private readonly SharedMapSystem _map = default!;
|
||||
[Dependency] private readonly MapLoaderSystem _mapLoader = default!;
|
||||
|
||||
public override string Command => "persistencesave";
|
||||
public override string Description => "Saves server data to a persistence file to be loaded later.";
|
||||
public override string Help => "persistencesave [mapId] [filePath - default: game.map (CCVar) ]";
|
||||
|
||||
public override void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||
{
|
||||
|
|
@ -47,8 +45,7 @@ public sealed class PersistenceSave : LocalizedEntityCommands
|
|||
return;
|
||||
}
|
||||
|
||||
var mapLoader = _system.GetEntitySystem<MapLoaderSystem>();
|
||||
mapLoader.TrySaveMap(mapId, new ResPath(saveFilePath));
|
||||
_mapLoader.TrySaveMap(mapId, new ResPath(saveFilePath));
|
||||
shell.WriteLine(Loc.GetString("cmd-savemap-success"));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,18 +38,21 @@ public sealed class SolutionCommand : ToolshedCommand
|
|||
public SolutionRef AdjReagent(
|
||||
[PipedArgument] SolutionRef input,
|
||||
ProtoId<ReagentPrototype> proto,
|
||||
FixedPoint2 amount
|
||||
float amount
|
||||
)
|
||||
{
|
||||
_solutionContainer ??= GetSys<SharedSolutionContainerSystem>();
|
||||
|
||||
if (amount > 0)
|
||||
// Convert float to FixedPoint2
|
||||
var amountFixed = FixedPoint2.New(amount);
|
||||
|
||||
if (amountFixed > 0)
|
||||
{
|
||||
_solutionContainer.TryAddReagent(input.Solution, proto, amount, out _);
|
||||
_solutionContainer.TryAddReagent(input.Solution, proto, amountFixed, out _);
|
||||
}
|
||||
else if (amount < 0)
|
||||
else if (amountFixed < 0)
|
||||
{
|
||||
_solutionContainer.RemoveReagent(input.Solution, proto, -amount);
|
||||
_solutionContainer.RemoveReagent(input.Solution, proto, -amountFixed);
|
||||
}
|
||||
|
||||
return input;
|
||||
|
|
@ -59,7 +62,7 @@ public sealed class SolutionCommand : ToolshedCommand
|
|||
public IEnumerable<SolutionRef> AdjReagent(
|
||||
[PipedArgument] IEnumerable<SolutionRef> input,
|
||||
ProtoId<ReagentPrototype> name,
|
||||
FixedPoint2 amount
|
||||
float amount
|
||||
)
|
||||
=> input.Select(x => AdjReagent(x, name, amount));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using Content.Shared.Chat;
|
|||
using Content.Shared.Chat.Prototypes;
|
||||
using Content.Shared.Emoting;
|
||||
using Content.Shared.Speech;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
|
|
@ -146,16 +147,16 @@ public partial class ChatSystem
|
|||
/// Tries to find and play relevant emote sound in emote sounds collection.
|
||||
/// </summary>
|
||||
/// <returns>True if emote sound was played.</returns>
|
||||
public bool TryPlayEmoteSound(EntityUid uid, EmoteSoundsPrototype? proto, EmotePrototype emote)
|
||||
public bool TryPlayEmoteSound(EntityUid uid, EmoteSoundsPrototype? proto, EmotePrototype emote, AudioParams? audioParams = null)
|
||||
{
|
||||
return TryPlayEmoteSound(uid, proto, emote.ID);
|
||||
return TryPlayEmoteSound(uid, proto, emote.ID, audioParams);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to find and play relevant emote sound in emote sounds collection.
|
||||
/// </summary>
|
||||
/// <returns>True if emote sound was played.</returns>
|
||||
public bool TryPlayEmoteSound(EntityUid uid, EmoteSoundsPrototype? proto, string emoteId)
|
||||
public bool TryPlayEmoteSound(EntityUid uid, EmoteSoundsPrototype? proto, string emoteId, AudioParams? audioParams = null)
|
||||
{
|
||||
if (proto == null)
|
||||
return false;
|
||||
|
|
@ -169,8 +170,8 @@ public partial class ChatSystem
|
|||
return false;
|
||||
}
|
||||
|
||||
// if general params for all sounds set - use them
|
||||
var param = proto.GeneralParams ?? sound.Params;
|
||||
// optional override params > general params for all sounds in set > individual sound params
|
||||
var param = audioParams ?? proto.GeneralParams ?? sound.Params;
|
||||
_audio.PlayPvs(sound, uid, param);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ public sealed class ChameleonClothingSystem : SharedChameleonClothingSystem
|
|||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
[Dependency] private readonly IdentitySystem _identity = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
|
|
|
|||
14
Content.Server/Codewords/CodewordComponent.cs
Normal file
14
Content.Server/Codewords/CodewordComponent.cs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
namespace Content.Server.Codewords;
|
||||
|
||||
/// <summary>
|
||||
/// Container for generated codewords.
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CodewordSystem))]
|
||||
public sealed partial class CodewordComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The codewords that were generated.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public string[] Codewords = [];
|
||||
}
|
||||
20
Content.Server/Codewords/CodewordFactionPrototype.cs
Normal file
20
Content.Server/Codewords/CodewordFactionPrototype.cs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.Codewords;
|
||||
|
||||
/// <summary>
|
||||
/// This is a prototype for easy access to codewords using identifiers instead of magic strings.
|
||||
/// </summary>
|
||||
[Prototype]
|
||||
public sealed partial class CodewordFactionPrototype : IPrototype
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
[IdDataField]
|
||||
public string ID { get; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// The generator to use for this faction.
|
||||
/// </summary>
|
||||
[DataField(required:true)]
|
||||
public ProtoId<CodewordGeneratorPrototype> Generator { get; } = default!;
|
||||
}
|
||||
32
Content.Server/Codewords/CodewordGeneratorPrototype.cs
Normal file
32
Content.Server/Codewords/CodewordGeneratorPrototype.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
using Content.Shared.Dataset;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.Codewords;
|
||||
|
||||
/// <summary>
|
||||
/// This is a prototype for specifying codeword generation
|
||||
/// </summary>
|
||||
[Prototype]
|
||||
public sealed partial class CodewordGeneratorPrototype : IPrototype
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
[IdDataField]
|
||||
public string ID { get; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// List of datasets to use for word generation. All values will be concatenated into one list and then randomly chosen from
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public List<ProtoId<LocalizedDatasetPrototype>> Words { get; } =
|
||||
[
|
||||
"Adjectives",
|
||||
"Verbs",
|
||||
];
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// How many codewords should be generated?
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public int Amount = 3;
|
||||
}
|
||||
17
Content.Server/Codewords/CodewordManagerComponent.cs
Normal file
17
Content.Server/Codewords/CodewordManagerComponent.cs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.Codewords;
|
||||
|
||||
/// <summary>
|
||||
/// Component that defines <see cref="CodewordGeneratorPrototype"/> to use and keeps track of generated codewords.
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(CodewordSystem))]
|
||||
public sealed partial class CodewordManagerComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The generated codewords. The value contains the entity that has the <see cref="CodewordComponent"/>
|
||||
/// </summary>
|
||||
[DataField]
|
||||
[ViewVariables(VVAccess.ReadOnly)]
|
||||
public Dictionary<ProtoId<CodewordFactionPrototype>, EntityUid> Codewords = new();
|
||||
}
|
||||
90
Content.Server/Codewords/CodewordSystem.cs
Normal file
90
Content.Server/Codewords/CodewordSystem.cs
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
using System.Linq;
|
||||
using Content.Server.Administration.Logs;
|
||||
using Content.Server.GameTicking.Events;
|
||||
using Content.Shared.Database;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Server.Codewords;
|
||||
|
||||
/// <summary>
|
||||
/// Gamerule that provides codewords for other gamerules that rely on them.
|
||||
/// </summary>
|
||||
public sealed class CodewordSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<RoundStartingEvent>(OnRoundStart);
|
||||
}
|
||||
|
||||
private void OnRoundStart(RoundStartingEvent ev)
|
||||
{
|
||||
var manager = Spawn();
|
||||
AddComp<CodewordManagerComponent>(manager);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves codewords for the faction specified.
|
||||
/// </summary>
|
||||
public string[] GetCodewords(ProtoId<CodewordFactionPrototype> faction)
|
||||
{
|
||||
var query = EntityQueryEnumerator<CodewordManagerComponent>();
|
||||
while (query.MoveNext(out _, out var manager))
|
||||
{
|
||||
if (!manager.Codewords.TryGetValue(faction, out var codewordEntity))
|
||||
return GenerateForFaction(faction, ref manager);
|
||||
|
||||
return Comp<CodewordComponent>(codewordEntity).Codewords;
|
||||
}
|
||||
|
||||
Log.Warning("Codeword system not initialized. Returning empty array.");
|
||||
// While throwing in this situation would be cool, that causes a test fail (in SpawnAndDeleteEntityCountTest)
|
||||
// as the traitor codewords paper gets spawned in and calls this method,
|
||||
// but the "start round" event never gets called in this test case.
|
||||
return [];
|
||||
}
|
||||
|
||||
private string[] GenerateForFaction(ProtoId<CodewordFactionPrototype> faction, ref CodewordManagerComponent manager)
|
||||
{
|
||||
var factionProto = _prototypeManager.Index<CodewordFactionPrototype>(faction.Id);
|
||||
|
||||
var codewords = GenerateCodewords(factionProto.Generator);
|
||||
var codewordsContainer = EntityManager.Spawn(protoName:null, MapCoordinates.Nullspace);
|
||||
EnsureComp<CodewordComponent>(codewordsContainer)
|
||||
.Codewords = codewords;
|
||||
manager.Codewords[faction] = codewordsContainer;
|
||||
_adminLogger.Add(LogType.EventStarted, LogImpact.Low, $"Codewords generated for faction {faction}: {string.Join(", ", codewords)}");
|
||||
|
||||
return codewords;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates codewords as specified by the <see cref="CodewordGeneratorPrototype"/> codeword generator.
|
||||
/// </summary>
|
||||
public string[] GenerateCodewords(ProtoId<CodewordGeneratorPrototype> generatorId)
|
||||
{
|
||||
var generator = _prototypeManager.Index(generatorId);
|
||||
|
||||
var codewordPool = new List<string>();
|
||||
foreach (var dataset in generator.Words
|
||||
.Select(datasetPrototype => _prototypeManager.Index(datasetPrototype)))
|
||||
{
|
||||
codewordPool.AddRange(dataset.Values);
|
||||
}
|
||||
|
||||
var finalCodewordCount = Math.Min(generator.Amount, codewordPool.Count);
|
||||
var codewords = new string[finalCodewordCount];
|
||||
for (var i = 0; i < finalCodewordCount; i++)
|
||||
{
|
||||
codewords[i] = Loc.GetString(_random.PickAndTake(codewordPool));
|
||||
}
|
||||
return codewords;
|
||||
}
|
||||
}
|
||||
|
|
@ -48,7 +48,7 @@ public sealed class DoorElectronicsSystem : EntitySystem
|
|||
DoorElectronicsUpdateConfigurationMessage args)
|
||||
{
|
||||
var accessReader = EnsureComp<AccessReaderComponent>(uid);
|
||||
_accessReader.SetAccesses(uid, accessReader, args.AccessList);
|
||||
_accessReader.SetAccesses((uid, accessReader), args.AccessList);
|
||||
}
|
||||
|
||||
private void OnAccessReaderChanged(
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using Content.Server.Codewords;
|
||||
using Content.Shared.Dataset;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Content.Shared.NPC.Prototypes;
|
||||
using Content.Shared.NPC.Prototypes;
|
||||
using Content.Shared.Random;
|
||||
using Content.Shared.Roles;
|
||||
using Robust.Shared.Audio;
|
||||
|
|
@ -17,18 +18,15 @@ public sealed partial class TraitorRuleComponent : Component
|
|||
[DataField]
|
||||
public ProtoId<AntagPrototype> TraitorPrototypeId = "Traitor";
|
||||
|
||||
[DataField]
|
||||
public ProtoId<CodewordFactionPrototype> CodewordFactionPrototypeId = "Traitor";
|
||||
|
||||
[DataField]
|
||||
public ProtoId<NpcFactionPrototype> NanoTrasenFaction = "NanoTrasen";
|
||||
|
||||
[DataField]
|
||||
public ProtoId<NpcFactionPrototype> SyndicateFaction = "Syndicate";
|
||||
|
||||
[DataField]
|
||||
public ProtoId<LocalizedDatasetPrototype> CodewordAdjectives = "Adjectives";
|
||||
|
||||
[DataField]
|
||||
public ProtoId<LocalizedDatasetPrototype> CodewordVerbs = "Verbs";
|
||||
|
||||
[DataField]
|
||||
public ProtoId<LocalizedDatasetPrototype> ObjectiveIssuers = "TraitorCorporations";
|
||||
|
||||
|
|
@ -51,7 +49,6 @@ public sealed partial class TraitorRuleComponent : Component
|
|||
public bool GiveBriefing = true;
|
||||
|
||||
public int TotalTraitors => TraitorMinds.Count;
|
||||
public string[] Codewords = new string[3];
|
||||
|
||||
public enum SelectionState
|
||||
{
|
||||
|
|
@ -77,12 +74,6 @@ public sealed partial class TraitorRuleComponent : Component
|
|||
[DataField]
|
||||
public SoundSpecifier GreetSoundNotification = new SoundPathSpecifier("/Audio/Ambience/Antag/traitor_start.ogg");
|
||||
|
||||
/// <summary>
|
||||
/// The amount of codewords that are selected.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public int CodewordCount = 4;
|
||||
|
||||
/// <summary>
|
||||
/// The amount of TC traitors start with.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ using Robust.Shared.Prototypes;
|
|||
using Robust.Shared.Random;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Content.Server.Codewords;
|
||||
|
||||
namespace Content.Server.GameTicking.Rules;
|
||||
|
||||
|
|
@ -27,7 +28,6 @@ public sealed class TraitorRuleSystem : GameRuleSystem<TraitorRuleComponent>
|
|||
{
|
||||
private static readonly Color TraitorCodewordColor = Color.FromHex("#cc3b3b");
|
||||
|
||||
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
|
||||
[Dependency] private readonly AntagSelectionSystem _antag = default!;
|
||||
[Dependency] private readonly SharedJobSystem _jobs = default!;
|
||||
[Dependency] private readonly MindSystem _mindSystem = default!;
|
||||
|
|
@ -37,6 +37,7 @@ public sealed class TraitorRuleSystem : GameRuleSystem<TraitorRuleComponent>
|
|||
[Dependency] private readonly SharedRoleCodewordSystem _roleCodewordSystem = default!;
|
||||
[Dependency] private readonly SharedRoleSystem _roleSystem = default!;
|
||||
[Dependency] private readonly UplinkSystem _uplink = default!;
|
||||
[Dependency] private readonly CodewordSystem _codewordSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
|
|
@ -48,41 +49,16 @@ public sealed class TraitorRuleSystem : GameRuleSystem<TraitorRuleComponent>
|
|||
SubscribeLocalEvent<TraitorRuleComponent, ObjectivesTextPrependEvent>(OnObjectivesTextPrepend);
|
||||
}
|
||||
|
||||
protected override void Added(EntityUid uid, TraitorRuleComponent component, GameRuleComponent gameRule, GameRuleAddedEvent args)
|
||||
{
|
||||
base.Added(uid, component, gameRule, args);
|
||||
SetCodewords(component, args.RuleEntity);
|
||||
}
|
||||
|
||||
private void AfterEntitySelected(Entity<TraitorRuleComponent> ent, ref AfterAntagEntitySelectedEvent args)
|
||||
{
|
||||
Log.Debug($"AfterAntagEntitySelected {ToPrettyString(ent)}");
|
||||
MakeTraitor(args.EntityUid, ent);
|
||||
}
|
||||
|
||||
private void SetCodewords(TraitorRuleComponent component, EntityUid ruleEntity)
|
||||
{
|
||||
component.Codewords = GenerateTraitorCodewords(component);
|
||||
_adminLogger.Add(LogType.EventStarted, LogImpact.Low, $"Codewords generated for game rule {ToPrettyString(ruleEntity)}: {string.Join(", ", component.Codewords)}");
|
||||
}
|
||||
|
||||
public string[] GenerateTraitorCodewords(TraitorRuleComponent component)
|
||||
{
|
||||
var adjectives = _prototypeManager.Index(component.CodewordAdjectives).Values;
|
||||
var verbs = _prototypeManager.Index(component.CodewordVerbs).Values;
|
||||
var codewordPool = adjectives.Concat(verbs).ToList();
|
||||
var finalCodewordCount = Math.Min(component.CodewordCount, codewordPool.Count);
|
||||
string[] codewords = new string[finalCodewordCount];
|
||||
for (var i = 0; i < finalCodewordCount; i++)
|
||||
{
|
||||
codewords[i] = Loc.GetString(_random.PickAndTake(codewordPool));
|
||||
}
|
||||
return codewords;
|
||||
}
|
||||
|
||||
public bool MakeTraitor(EntityUid traitor, TraitorRuleComponent component)
|
||||
{
|
||||
Log.Debug($"MakeTraitor {ToPrettyString(traitor)} - start");
|
||||
var factionCodewords = _codewordSystem.GetCodewords(component.CodewordFactionPrototypeId);
|
||||
|
||||
//Grab the mind if it wasn't provided
|
||||
if (!_mindSystem.TryGetMind(traitor, out var mindId, out var mind))
|
||||
|
|
@ -96,7 +72,7 @@ public sealed class TraitorRuleSystem : GameRuleSystem<TraitorRuleComponent>
|
|||
if (component.GiveCodewords)
|
||||
{
|
||||
Log.Debug($"MakeTraitor {ToPrettyString(traitor)} - added codewords flufftext to briefing");
|
||||
briefing = Loc.GetString("traitor-role-codewords-short", ("codewords", string.Join(", ", component.Codewords)));
|
||||
briefing = Loc.GetString("traitor-role-codewords-short", ("codewords", string.Join(", ", factionCodewords)));
|
||||
}
|
||||
|
||||
var issuer = _random.Pick(_prototypeManager.Index(component.ObjectiveIssuers));
|
||||
|
|
@ -129,7 +105,7 @@ public sealed class TraitorRuleSystem : GameRuleSystem<TraitorRuleComponent>
|
|||
if (component.GiveCodewords)
|
||||
{
|
||||
Log.Debug($"MakeTraitor {ToPrettyString(traitor)} - set codewords from component");
|
||||
codewords = component.Codewords;
|
||||
codewords = factionCodewords;
|
||||
}
|
||||
|
||||
if (component.GiveBriefing)
|
||||
|
|
@ -161,7 +137,7 @@ public sealed class TraitorRuleSystem : GameRuleSystem<TraitorRuleComponent>
|
|||
var color = TraitorCodewordColor; // Fall back to a dark red Syndicate color if a prototype is not found
|
||||
|
||||
RoleCodewordComponent codewordComp = EnsureComp<RoleCodewordComponent>(mindId);
|
||||
_roleCodewordSystem.SetRoleCodewords(codewordComp, "traitor", component.Codewords.ToList(), color);
|
||||
_roleCodewordSystem.SetRoleCodewords(codewordComp, "traitor", factionCodewords.ToList(), color);
|
||||
|
||||
// Change the faction
|
||||
Log.Debug($"MakeTraitor {ToPrettyString(traitor)} - Change faction");
|
||||
|
|
@ -211,7 +187,7 @@ public sealed class TraitorRuleSystem : GameRuleSystem<TraitorRuleComponent>
|
|||
private void OnObjectivesTextPrepend(EntityUid uid, TraitorRuleComponent comp, ref ObjectivesTextPrependEvent args)
|
||||
{
|
||||
if(comp.GiveCodewords)
|
||||
args.Text += "\n" + Loc.GetString("traitor-round-end-codewords", ("codewords", string.Join(", ", comp.Codewords)));
|
||||
args.Text += "\n" + Loc.GetString("traitor-round-end-codewords", ("codewords", string.Join(", ", _codewordSystem.GetCodewords(comp.CodewordFactionPrototypeId))));
|
||||
}
|
||||
|
||||
// TODO: figure out how to handle this? add priority to briefing event?
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ public sealed class GatewayGeneratorSystem : EntitySystem
|
|||
{
|
||||
[Dependency] private readonly IConfigurationManager _cfgManager = default!;
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||
[Dependency] private readonly IPrototypeManager _protoManager = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly ITileDefinitionManager _tileDefManager = default!;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using Content.Server.Administration;
|
||||
using Content.Shared.Access.Components;
|
||||
using Content.Shared.Administration;
|
||||
using Content.Shared.CCVar;
|
||||
using Robust.Server.Player;
|
||||
|
|
@ -60,4 +59,12 @@ public sealed class RenameCommand : LocalizedEntityCommands
|
|||
entityUid = EntityUid.Invalid;
|
||||
return false;
|
||||
}
|
||||
|
||||
public override CompletionResult GetCompletion(IConsoleShell shell, string[] args)
|
||||
{
|
||||
if (args.Length == 1)
|
||||
return CompletionResult.FromOptions(CompletionHelper.SessionNames());
|
||||
|
||||
return CompletionResult.Empty;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ namespace Content.Server.NPC.Systems;
|
|||
|
||||
public sealed class NPCUseActionOnTargetSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly SharedActionsSystem _actions = default!;
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ using Content.Shared.Popups;
|
|||
using Robust.Server.Audio;
|
||||
using Robust.Server.Containers;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Utility;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ public sealed partial class DungeonSystem : SharedDungeonSystem
|
|||
{
|
||||
[Dependency] private readonly IConfigurationManager _configManager = default!;
|
||||
[Dependency] private readonly IConsoleHost _console = default!;
|
||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly ITileDefinitionManager _tileDefManager = default!;
|
||||
|
|
|
|||
|
|
@ -1,14 +1,24 @@
|
|||
using Content.Shared.Security.Components;
|
||||
using Content.Shared.Security.Systems;
|
||||
using Content.Shared.Wall;
|
||||
|
||||
namespace Content.Server.Security;
|
||||
|
||||
public sealed class GenpopSystem : SharedGenpopSystem
|
||||
{
|
||||
private const float GenpopIDEjectDistanceFromWall = 1f;
|
||||
protected override void CreateId(Entity<GenpopLockerComponent> ent, string name, float sentence, string crime)
|
||||
{
|
||||
// Default to prisoner locker coordinates for ID spawn
|
||||
var xform = Transform(ent);
|
||||
var uid = Spawn(ent.Comp.IdCardProto, xform.Coordinates);
|
||||
var spawnCoordinates = xform.Coordinates;
|
||||
// Offset prisoner wall locker coordinates in wallmount direction for ID spawn; avoids spawning ID inside wall
|
||||
if (TryComp<WallMountComponent>(ent, out var wallMountComponent))
|
||||
{
|
||||
var offset = (wallMountComponent.Direction + xform.LocalRotation - Math.PI / 2).ToVec() * GenpopIDEjectDistanceFromWall;
|
||||
spawnCoordinates = spawnCoordinates.Offset(offset);
|
||||
}
|
||||
var uid = Spawn(ent.Comp.IdCardProto, spawnCoordinates);
|
||||
ent.Comp.LinkedId = uid;
|
||||
IdCard.TryChangeFullName(uid, name);
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@ public sealed partial class ShuttleSystem : SharedShuttleSystem
|
|||
[Dependency] private readonly DockingSystem _dockSystem = default!;
|
||||
[Dependency] private readonly DungeonSystem _dungeon = default!;
|
||||
[Dependency] private readonly EntityLookupSystem _lookup = default!;
|
||||
[Dependency] private readonly FixtureSystem _fixtures = default!;
|
||||
[Dependency] private readonly MapLoaderSystem _loader = default!;
|
||||
[Dependency] private readonly MapSystem _mapSystem = default!;
|
||||
[Dependency] private readonly MetaDataSystem _metadata = default!;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,14 @@
|
|||
using Robust.Shared.Audio;
|
||||
|
||||
namespace Content.Server.Speech.Components;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class MumbleAccentComponent : Component
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// This modifies the audio parameters of emote sounds, screaming, laughing, etc.
|
||||
/// By default, it reduces the volume and distance of emote sounds.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public AudioParams EmoteAudioParams = AudioParams.Default.WithVolume(-8f).WithMaxDistance(5);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
using Content.Server.Chat.Systems;
|
||||
using Content.Server.Speech.Components;
|
||||
using Content.Shared.Chat.Prototypes;
|
||||
using Content.Shared.Speech.Components;
|
||||
|
||||
namespace Content.Server.Speech.EntitySystems;
|
||||
|
||||
public sealed class MumbleAccentSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly ChatSystem _chat = default!;
|
||||
[Dependency] private readonly ReplacementAccentSystem _replacement = default!;
|
||||
|
||||
public override void Initialize()
|
||||
|
|
@ -11,6 +15,19 @@ public sealed class MumbleAccentSystem : EntitySystem
|
|||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<MumbleAccentComponent, AccentGetEvent>(OnAccentGet);
|
||||
SubscribeLocalEvent<MumbleAccentComponent, EmoteEvent>(OnEmote, before: [typeof(VocalSystem)]);
|
||||
}
|
||||
|
||||
private void OnEmote(Entity<MumbleAccentComponent> ent, ref EmoteEvent args)
|
||||
{
|
||||
if (args.Handled || !args.Emote.Category.HasFlag(EmoteCategory.Vocal))
|
||||
return;
|
||||
|
||||
if (TryComp<VocalComponent>(ent.Owner, out var vocalComp))
|
||||
{
|
||||
// play a muffled version of the vocal emote
|
||||
args.Handled = _chat.TryPlayEmoteSound(ent.Owner, vocalComp.EmoteSounds, args.Emote, ent.Comp.EmoteAudioParams);
|
||||
}
|
||||
}
|
||||
|
||||
public string Accentuate(string message, MumbleAccentComponent component)
|
||||
|
|
@ -18,8 +35,8 @@ public sealed class MumbleAccentSystem : EntitySystem
|
|||
return _replacement.ApplyReplacements(message, "mumble");
|
||||
}
|
||||
|
||||
private void OnAccentGet(EntityUid uid, MumbleAccentComponent component, AccentGetEvent args)
|
||||
private void OnAccentGet(Entity<MumbleAccentComponent> ent, ref AccentGetEvent args)
|
||||
{
|
||||
args.Message = Accentuate(args.Message, component);
|
||||
args.Message = Accentuate(args.Message, ent.Comp);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ namespace Content.Server.Speech.Muting
|
|||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<MutedComponent, SpeakAttemptEvent>(OnSpeakAttempt);
|
||||
SubscribeLocalEvent<MutedComponent, EmoteEvent>(OnEmote, before: new[] { typeof(VocalSystem) });
|
||||
SubscribeLocalEvent<MutedComponent, EmoteEvent>(OnEmote, before: new[] { typeof(VocalSystem), typeof(MumbleAccentSystem) });
|
||||
SubscribeLocalEvent<MutedComponent, ScreamActionEvent>(OnScreamAction, before: new[] { typeof(VocalSystem) });
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
using Content.Server.Codewords;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.Traitor.Components;
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -6,6 +9,18 @@ namespace Content.Server.Traitor.Components;
|
|||
[RegisterComponent]
|
||||
public sealed partial class TraitorCodePaperComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The faction to get codewords for.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public ProtoId<CodewordFactionPrototype> CodewordFaction = "Traitor";
|
||||
|
||||
/// <summary>
|
||||
/// The generator to use for the fake words.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public ProtoId<CodewordGeneratorPrototype> CodewordGenerator = "TraitorCodewordGenerator";
|
||||
|
||||
/// <summary>
|
||||
/// The number of codewords that should be generated on this paper.
|
||||
/// Will not extend past the max number of available codewords.
|
||||
|
|
|
|||
|
|
@ -7,16 +7,16 @@ using Content.Server.Traitor.Components;
|
|||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Utility;
|
||||
using System.Linq;
|
||||
using Content.Server.Codewords;
|
||||
using Content.Shared.Paper;
|
||||
|
||||
namespace Content.Server.Traitor.Systems;
|
||||
|
||||
public sealed class TraitorCodePaperSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly GameTicker _gameTicker = default!;
|
||||
[Dependency] private readonly TraitorRuleSystem _traitorRuleSystem = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly PaperSystem _paper = default!;
|
||||
[Dependency] private readonly CodewordSystem _codewordSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
|
|
@ -48,23 +48,12 @@ public sealed class TraitorCodePaperSystem : EntitySystem
|
|||
traitorCode = null;
|
||||
|
||||
var codesMessage = new FormattedMessage();
|
||||
List<string> codeList = new();
|
||||
// Find the first nuke that matches the passed location.
|
||||
if (_gameTicker.IsGameRuleAdded<TraitorRuleComponent>())
|
||||
{
|
||||
var ruleEnts = _gameTicker.GetAddedGameRules();
|
||||
foreach (var ruleEnt in ruleEnts)
|
||||
{
|
||||
if (TryComp(ruleEnt, out TraitorRuleComponent? traitorComp))
|
||||
{
|
||||
codeList.AddRange(traitorComp.Codewords.ToList());
|
||||
}
|
||||
}
|
||||
}
|
||||
var codeList = _codewordSystem.GetCodewords(component.CodewordFaction).ToList();
|
||||
|
||||
if (codeList.Count == 0)
|
||||
{
|
||||
if (component.FakeCodewords)
|
||||
codeList = _traitorRuleSystem.GenerateTraitorCodewords(new TraitorRuleComponent()).ToList();
|
||||
codeList = _codewordSystem.GenerateCodewords(component.CodewordGenerator).ToList();
|
||||
else
|
||||
codeList = [Loc.GetString("traitor-codes-none")];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -227,14 +227,13 @@ namespace Content.Server.VendingMachines
|
|||
}
|
||||
|
||||
// Default spawn coordinates
|
||||
var spawnCoordinates = Transform(uid).Coordinates;
|
||||
var xform = Transform(uid);
|
||||
var spawnCoordinates = xform.Coordinates;
|
||||
|
||||
//Make sure the wallvends spawn outside of the wall.
|
||||
|
||||
if (TryComp<WallMountComponent>(uid, out var wallMountComponent))
|
||||
{
|
||||
|
||||
var offset = wallMountComponent.Direction.ToWorldVec() * WallVendEjectDistanceFromWall;
|
||||
var offset = (wallMountComponent.Direction + xform.LocalRotation - Math.PI / 2).ToVec() * WallVendEjectDistanceFromWall;
|
||||
spawnCoordinates = spawnCoordinates.Offset(offset);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ using Content.Shared.Ghost.Roles.Components;
|
|||
using Content.Shared.Tag;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Content.Shared.NPC.Prototypes;
|
||||
|
||||
namespace Content.Server.Zombies;
|
||||
|
||||
|
|
@ -73,6 +74,8 @@ public sealed partial class ZombieSystem
|
|||
|
||||
private static readonly ProtoId<TagPrototype> InvalidForGlobalSpawnSpellTag = "InvalidForGlobalSpawnSpell";
|
||||
private static readonly ProtoId<TagPrototype> CannotSuicideTag = "CannotSuicide";
|
||||
private static readonly ProtoId<NpcFactionPrototype> ZombieFaction = "Zombie";
|
||||
|
||||
/// <summary>
|
||||
/// Handles an entity turning into a zombie when they die or go into crit
|
||||
/// </summary>
|
||||
|
|
@ -243,7 +246,7 @@ public sealed partial class ZombieSystem
|
|||
_mobState.ChangeMobState(target, MobState.Alive);
|
||||
|
||||
_faction.ClearFactions(target, dirty: false);
|
||||
_faction.AddFaction(target, "Zombie");
|
||||
_faction.AddFaction(target, ZombieFaction);
|
||||
|
||||
//gives it the funny "Zombie ___" name.
|
||||
_nameMod.RefreshNameModifiers(target);
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
using Content.Shared.Access.Systems;
|
||||
using System.Text.RegularExpressions;
|
||||
using Content.Shared.StationRecords;
|
||||
using Content.Shared.Weapons.Melee;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Set;
|
||||
using Robust.Shared.Toolshed.Syntax;
|
||||
|
||||
namespace Content.Shared.Access.Components;
|
||||
|
|
@ -14,6 +14,7 @@ namespace Content.Shared.Access.Components;
|
|||
/// and allows checking if something or somebody is authorized with these access levels.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
[Access(typeof(AccessReaderSystem))]
|
||||
public sealed partial class AccessReaderComponent : Component
|
||||
{
|
||||
// Sunrise added start
|
||||
|
|
@ -32,7 +33,7 @@ public sealed partial class AccessReaderComponent : Component
|
|||
// Sunrise added end
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not the accessreader is enabled.
|
||||
/// Whether or not the access reader is enabled.
|
||||
/// If not, it will always let people through.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
|
|
@ -41,7 +42,6 @@ public sealed partial class AccessReaderComponent : Component
|
|||
/// <summary>
|
||||
/// The set of tags that will automatically deny an allowed check, if any of them are present.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField]
|
||||
public HashSet<ProtoId<AccessLevelPrototype>> DenyTags = new();
|
||||
|
||||
|
|
@ -49,12 +49,11 @@ public sealed partial class AccessReaderComponent : Component
|
|||
/// List of access groups that grant access to this reader. Only a single matching group is required to gain access.
|
||||
/// A group matches if it is a subset of the set being checked against.
|
||||
/// </summary>
|
||||
[DataField("access")] [ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("access")]
|
||||
public List<HashSet<ProtoId<AccessLevelPrototype>>> AccessLists = new();
|
||||
|
||||
/// <summary>
|
||||
/// A list of <see cref="StationRecordKey"/>s that grant access. Only a single matching key is required to gain
|
||||
/// access.
|
||||
/// A list of <see cref="StationRecordKey"/>s that grant access. Only a single matching key is required to gain access.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public HashSet<StationRecordKey> AccessKeys = new();
|
||||
|
|
@ -72,7 +71,7 @@ public sealed partial class AccessReaderComponent : Component
|
|||
public string? ContainerAccessProvider;
|
||||
|
||||
/// <summary>
|
||||
/// A list of past authentications
|
||||
/// A list of past authentications.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public Queue<AccessRecord> AccessLog = new();
|
||||
|
|
@ -80,7 +79,7 @@ public sealed partial class AccessReaderComponent : Component
|
|||
/// <summary>
|
||||
/// A limit on the max size of <see cref="AccessLog"/>
|
||||
/// </summary>
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField]
|
||||
public int AccessLogLimit = 20;
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -113,17 +112,13 @@ public readonly partial record struct AccessRecord(
|
|||
public sealed class AccessReaderComponentState : ComponentState
|
||||
{
|
||||
public bool Enabled;
|
||||
|
||||
public HashSet<ProtoId<AccessLevelPrototype>> DenyTags;
|
||||
|
||||
public List<HashSet<ProtoId<AccessLevelPrototype>>> AccessLists;
|
||||
|
||||
public ProtoId<AccessGroupPrototype>? Group; // Sunrise-alertAccesses, нужно для связывания клиента с сервером
|
||||
|
||||
public List<(NetEntity, uint)> AccessKeys;
|
||||
|
||||
public Queue<AccessRecord> AccessLog;
|
||||
|
||||
public int AccessLogLimit;
|
||||
|
||||
public AccessReaderComponentState(bool enabled, HashSet<ProtoId<AccessLevelPrototype>> denyTags,
|
||||
|
|
@ -143,9 +138,4 @@ public sealed class AccessReaderComponentState : ComponentState
|
|||
}
|
||||
}
|
||||
|
||||
public sealed class AccessReaderConfigurationChangedEvent : EntityEventArgs
|
||||
{
|
||||
public AccessReaderConfigurationChangedEvent()
|
||||
{
|
||||
}
|
||||
}
|
||||
public sealed class AccessReaderConfigurationChangedEvent : EntityEventArgs;
|
||||
|
|
|
|||
|
|
@ -3,17 +3,17 @@ using System.Linq;
|
|||
using Content.Shared.Access.Components;
|
||||
using Content.Shared.DeviceLinking.Events;
|
||||
using Content.Shared.Emag.Systems;
|
||||
using Content.Shared.GameTicking;
|
||||
using Content.Shared.Hands.EntitySystems;
|
||||
using Content.Shared.IdentityManagement;
|
||||
using Content.Shared.Inventory;
|
||||
using Content.Shared.NameIdentifier;
|
||||
using Content.Shared.PDA;
|
||||
using Content.Shared.StationRecords;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.GameStates;
|
||||
using Content.Shared.GameTicking;
|
||||
using Content.Shared.IdentityManagement;
|
||||
using Content.Shared.Tag;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.Collections;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
|
|
@ -129,6 +129,11 @@ public sealed class AccessReaderSystem : EntitySystem
|
|||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches an entity for an access reader. This is either the entity itself or an entity in its <see cref="AccessReaderComponent.ContainerAccessProvider"/>.
|
||||
/// </summary>
|
||||
/// <param name="uid">The entity being searched for an access reader.</param>
|
||||
/// <param name="ent">The returned access reader entity.</param>
|
||||
public bool GetMainAccessReader(EntityUid uid, [NotNullWhen(true)] out Entity<AccessReaderComponent>? ent)
|
||||
{
|
||||
ent = null;
|
||||
|
|
@ -158,6 +163,10 @@ public sealed class AccessReaderSystem : EntitySystem
|
|||
/// <summary>
|
||||
/// Check whether the given access permissions satisfy an access reader's requirements.
|
||||
/// </summary>
|
||||
/// <param name="access">A collection of access permissions being used on the access reader.</param>
|
||||
/// <param name="stationKeys">A collection of station record keys being used on the access reader.</param>
|
||||
/// <param name="target">The entity being checked.</param>
|
||||
/// <param name="reader">The access reader being checked.</param>
|
||||
public bool IsAllowed(
|
||||
ICollection<ProtoId<AccessLevelPrototype>> access,
|
||||
ICollection<StationRecordKey> stationKeys,
|
||||
|
|
@ -210,8 +219,8 @@ public sealed class AccessReaderSystem : EntitySystem
|
|||
/// <summary>
|
||||
/// Compares the given tags with the readers access list to see if it is allowed.
|
||||
/// </summary>
|
||||
/// <param name="accessTags">A list of access tags</param>
|
||||
/// <param name="reader">An access reader to check against</param>
|
||||
/// <param name="accessTags">A list of access tags.</param>
|
||||
/// <param name="reader">The access reader to check against.</param>
|
||||
public bool AreAccessTagsAllowed(ICollection<ProtoId<AccessLevelPrototype>> accessTags, AccessReaderComponent reader)
|
||||
{
|
||||
if (reader.DenyTags.Overlaps(accessTags))
|
||||
|
|
@ -258,6 +267,8 @@ public sealed class AccessReaderSystem : EntitySystem
|
|||
/// <summary>
|
||||
/// Compares the given stationrecordkeys with the accessreader to see if it is allowed.
|
||||
/// </summary>
|
||||
/// <param name="keys">The collection of station record keys being used against the access reader.</param>
|
||||
/// <param name="reader">The access reader that is being checked.</param>
|
||||
public bool AreStationRecordKeysAllowed(ICollection<StationRecordKey> keys, AccessReaderComponent reader)
|
||||
{
|
||||
foreach (var key in reader.AccessKeys)
|
||||
|
|
@ -270,8 +281,9 @@ public sealed class AccessReaderSystem : EntitySystem
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds all the items that could potentially give access to a given entity
|
||||
/// Finds all the items that could potentially give access to an entity.
|
||||
/// </summary>
|
||||
/// <param name="uid">The entity that is being searched.</param>
|
||||
public HashSet<EntityUid> FindPotentialAccessItems(EntityUid uid)
|
||||
{
|
||||
FindAccessItemsInventory(uid, out var items);
|
||||
|
|
@ -291,7 +303,7 @@ public sealed class AccessReaderSystem : EntitySystem
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the access tags on the given entity
|
||||
/// Finds the access tags on an entity.
|
||||
/// </summary>
|
||||
/// <param name="uid">The entity that is being searched.</param>
|
||||
/// <param name="items">All of the items to search for access. If none are passed in, <see cref="FindPotentialAccessItems"/> will be used.</param>
|
||||
|
|
@ -307,14 +319,14 @@ public sealed class AccessReaderSystem : EntitySystem
|
|||
FindAccessTagsItem(ent, ref tags, ref owned);
|
||||
}
|
||||
|
||||
return (ICollection<ProtoId<AccessLevelPrototype>>?) tags ?? Array.Empty<ProtoId<AccessLevelPrototype>>();
|
||||
return (ICollection<ProtoId<AccessLevelPrototype>>?)tags ?? Array.Empty<ProtoId<AccessLevelPrototype>>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the access tags on the given entity
|
||||
/// Finds any station record keys on an entity.
|
||||
/// </summary>
|
||||
/// <param name="uid">The entity that is being searched.</param>
|
||||
/// <param name="recordKeys"></param>
|
||||
/// <param name="recordKeys">A collection of the station record keys that were found.</param>
|
||||
/// <param name="items">All of the items to search for access. If none are passed in, <see cref="FindPotentialAccessItems"/> will be used.</param>
|
||||
public bool FindStationRecordKeys(EntityUid uid, out ICollection<StationRecordKey> recordKeys, HashSet<EntityUid>? items = null)
|
||||
{
|
||||
|
|
@ -332,11 +344,12 @@ public sealed class AccessReaderSystem : EntitySystem
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try to find <see cref="AccessComponent"/> on this item
|
||||
/// or inside this item (if it's pda)
|
||||
/// This version merges into a set or replaces the set.
|
||||
/// If owned is false, the existing tag-set "isn't ours" and can't be merged with (is read-only).
|
||||
/// Try to find <see cref="AccessComponent"/> on this item or inside this item (if it's a PDA).
|
||||
/// This version merges into a set or replaces the set.
|
||||
/// </summary>
|
||||
/// <param name="uid">The entity that is being searched.</param>
|
||||
/// <param name="tags">The access tags being merged or replaced.</param>
|
||||
/// <param name="owned">If true, the tags will be merged. Otherwise they are replaced.</param>
|
||||
private void FindAccessTagsItem(EntityUid uid, ref HashSet<ProtoId<AccessLevelPrototype>>? tags, ref bool owned)
|
||||
{
|
||||
if (!FindAccessTagsItem(uid, out var targetTags))
|
||||
|
|
@ -363,25 +376,287 @@ public sealed class AccessReaderSystem : EntitySystem
|
|||
}
|
||||
}
|
||||
|
||||
public void SetAccesses(EntityUid uid, AccessReaderComponent component, List<ProtoId<AccessLevelPrototype>> accesses)
|
||||
#region: AccessLists API
|
||||
|
||||
/// <summary>
|
||||
/// Clears the entity's <see cref="AccessReaderComponent.AccessLists"/>.
|
||||
/// </summary>
|
||||
/// <param name="ent">The access reader entity which is having its access permissions cleared.</param>
|
||||
public void ClearAccesses(Entity<AccessReaderComponent> ent)
|
||||
{
|
||||
component.AccessLists.Clear();
|
||||
foreach (var access in accesses)
|
||||
{
|
||||
component.AccessLists.Add(new HashSet<ProtoId<AccessLevelPrototype>>(){access});
|
||||
}
|
||||
Dirty(uid, component);
|
||||
RaiseLocalEvent(uid, new AccessReaderConfigurationChangedEvent());
|
||||
ent.Comp.AccessLists.Clear();
|
||||
|
||||
Dirty(ent);
|
||||
RaiseLocalEvent(ent, new AccessReaderConfigurationChangedEvent());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces the access permissions in an entity's <see cref="AccessReaderComponent.AccessLists"/> with a supplied list.
|
||||
/// </summary>
|
||||
/// <param name="ent">The access reader entity which is having its list of access permissions replaced.</param>
|
||||
/// <param name="accesses">The list of access permissions replacing the original one.</param>
|
||||
public void SetAccesses(Entity<AccessReaderComponent> ent, List<HashSet<ProtoId<AccessLevelPrototype>>> accesses)
|
||||
{
|
||||
ent.Comp.AccessLists.Clear();
|
||||
|
||||
AddAccesses(ent, accesses);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref = "SetAccesses"/>
|
||||
public void SetAccesses(Entity<AccessReaderComponent> ent, List<ProtoId<AccessLevelPrototype>> accesses)
|
||||
{
|
||||
ent.Comp.AccessLists.Clear();
|
||||
|
||||
AddAccesses(ent, accesses);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a collection of access permissions to an access reader entity's <see cref="AccessReaderComponent.AccessLists"/>
|
||||
/// </summary>
|
||||
/// <param name="ent">The access reader entity to which the new access permissions are being added.</param>
|
||||
/// <param name="accesses">The list of access permissions being added.</param>
|
||||
public void AddAccesses(Entity<AccessReaderComponent> ent, List<HashSet<ProtoId<AccessLevelPrototype>>> accesses)
|
||||
{
|
||||
foreach (var access in accesses)
|
||||
{
|
||||
AddAccess(ent, access, false);
|
||||
}
|
||||
|
||||
Dirty(ent);
|
||||
RaiseLocalEvent(ent, new AccessReaderConfigurationChangedEvent());
|
||||
}
|
||||
|
||||
/// <inheritdoc cref = "AddAccesses"/>
|
||||
public void AddAccesses(Entity<AccessReaderComponent> ent, List<ProtoId<AccessLevelPrototype>> accesses)
|
||||
{
|
||||
foreach (var access in accesses)
|
||||
{
|
||||
AddAccess(ent, access, false);
|
||||
}
|
||||
|
||||
Dirty(ent);
|
||||
RaiseLocalEvent(ent, new AccessReaderConfigurationChangedEvent());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds an access permission to an access reader entity's <see cref="AccessReaderComponent.AccessLists"/>
|
||||
/// </summary>
|
||||
/// <param name="ent">The access reader entity to which the access permission is being added.</param>
|
||||
/// <param name="access">The access permission being added.</param>
|
||||
/// <param name="dirty">If true, the component will be marked as changed afterward.</param>
|
||||
public void AddAccess(Entity<AccessReaderComponent> ent, HashSet<ProtoId<AccessLevelPrototype>> access, bool dirty = true)
|
||||
{
|
||||
ent.Comp.AccessLists.Add(access);
|
||||
|
||||
if (!dirty)
|
||||
return;
|
||||
|
||||
Dirty(ent);
|
||||
RaiseLocalEvent(ent, new AccessReaderConfigurationChangedEvent());
|
||||
}
|
||||
|
||||
/// <inheritdoc cref = "AddAccess"/>
|
||||
public void AddAccess(Entity<AccessReaderComponent> ent, ProtoId<AccessLevelPrototype> access, bool dirty = true)
|
||||
{
|
||||
AddAccess(ent, new HashSet<ProtoId<AccessLevelPrototype>>() { access }, dirty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a collection of access permissions from an access reader entity's <see cref="AccessReaderComponent.AccessLists"/>
|
||||
/// </summary>
|
||||
/// <param name="ent">The access reader entity from which the access permissions are being removed.</param>
|
||||
/// <param name="accesses">The list of access permissions being removed.</param>
|
||||
public void RemoveAccesses(Entity<AccessReaderComponent> ent, List<HashSet<ProtoId<AccessLevelPrototype>>> accesses)
|
||||
{
|
||||
foreach (var access in accesses)
|
||||
{
|
||||
RemoveAccess(ent, access, false);
|
||||
}
|
||||
|
||||
Dirty(ent);
|
||||
RaiseLocalEvent(ent, new AccessReaderConfigurationChangedEvent());
|
||||
}
|
||||
|
||||
/// <inheritdoc cref = "RemoveAccesses"/>
|
||||
public void RemoveAccesses(Entity<AccessReaderComponent> ent, List<ProtoId<AccessLevelPrototype>> accesses)
|
||||
{
|
||||
foreach (var access in accesses)
|
||||
{
|
||||
RemoveAccess(ent, access, false);
|
||||
}
|
||||
|
||||
Dirty(ent);
|
||||
RaiseLocalEvent(ent, new AccessReaderConfigurationChangedEvent());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes an access permission from an access reader entity's <see cref="AccessReaderComponent.AccessLists"/>
|
||||
/// </summary>
|
||||
/// <param name="ent">The access reader entity from which the access permission is being removed.</param>
|
||||
/// <param name="access">The access permission being removed.</param>
|
||||
/// <param name="dirty">If true, the component will be marked as changed afterward.</param>
|
||||
public void RemoveAccess(Entity<AccessReaderComponent> ent, HashSet<ProtoId<AccessLevelPrototype>> access, bool dirty = true)
|
||||
{
|
||||
for (int i = ent.Comp.AccessLists.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (ent.Comp.AccessLists[i].SetEquals(access))
|
||||
{
|
||||
ent.Comp.AccessLists.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (!dirty)
|
||||
return;
|
||||
|
||||
Dirty(ent);
|
||||
RaiseLocalEvent(ent, new AccessReaderConfigurationChangedEvent());
|
||||
}
|
||||
|
||||
/// <inheritdoc cref = "RemoveAccess"/>
|
||||
public void RemoveAccess(Entity<AccessReaderComponent> ent, ProtoId<AccessLevelPrototype> access, bool dirty = true)
|
||||
{
|
||||
RemoveAccess(ent, new HashSet<ProtoId<AccessLevelPrototype>>() { access }, dirty);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region: AccessKeys API
|
||||
|
||||
/// <summary>
|
||||
/// Clears all access keys from an access reader.
|
||||
/// </summary>
|
||||
/// <param name="ent">The access reader entity.</param>
|
||||
public void ClearAccessKeys(Entity<AccessReaderComponent> ent)
|
||||
{
|
||||
ent.Comp.AccessKeys.Clear();
|
||||
Dirty(ent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces all access keys on an access reader with those from a supplied list.
|
||||
/// </summary>
|
||||
/// <param name="ent">The access reader entity.</param>
|
||||
/// <param name="keys">The new access keys that are replacing the old ones.</param>
|
||||
public void SetAccessKeys(Entity<AccessReaderComponent> ent, HashSet<StationRecordKey> keys)
|
||||
{
|
||||
ent.Comp.AccessKeys.Clear();
|
||||
|
||||
foreach (var key in keys)
|
||||
{
|
||||
ent.Comp.AccessKeys.Add(key);
|
||||
}
|
||||
|
||||
Dirty(ent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds an access key to an access reader.
|
||||
/// </summary>
|
||||
/// <param name="ent">The access reader entity.</param>
|
||||
/// <param name="key">The access key being added.</param>
|
||||
public void AddAccessKey(Entity<AccessReaderComponent> ent, StationRecordKey key)
|
||||
{
|
||||
ent.Comp.AccessKeys.Add(key);
|
||||
Dirty(ent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes an access key from an access reader.
|
||||
/// </summary>
|
||||
/// <param name="ent">The access reader entity.</param>
|
||||
/// <param name="key">The access key being removed.</param>
|
||||
public void RemoveAccessKey(Entity<AccessReaderComponent> ent, StationRecordKey key)
|
||||
{
|
||||
ent.Comp.AccessKeys.Remove(key);
|
||||
Dirty(ent);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region: DenyTags API
|
||||
|
||||
/// <summary>
|
||||
/// Clears all deny tags from an access reader.
|
||||
/// </summary>
|
||||
/// <param name="ent">The access reader entity.</param>
|
||||
public void ClearDenyTags(Entity<AccessReaderComponent> ent)
|
||||
{
|
||||
ent.Comp.DenyTags.Clear();
|
||||
Dirty(ent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces all deny tags on an access reader with those from a supplied list.
|
||||
/// </summary>
|
||||
/// <param name="ent">The access reader entity.</param>
|
||||
/// <param name="tag">The new tags that are replacing the old.</param>
|
||||
public void SetDenyTags(Entity<AccessReaderComponent> ent, HashSet<ProtoId<AccessLevelPrototype>> tags)
|
||||
{
|
||||
ent.Comp.DenyTags.Clear();
|
||||
|
||||
foreach (var tag in tags)
|
||||
{
|
||||
ent.Comp.DenyTags.Add(tag);
|
||||
}
|
||||
|
||||
Dirty(ent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a tag to an access reader that will be used to deny access.
|
||||
/// </summary>
|
||||
/// <param name="ent">The access reader entity.</param>
|
||||
/// <param name="tag">The tag being added.</param>
|
||||
public void AddDenyTag(Entity<AccessReaderComponent> ent, ProtoId<AccessLevelPrototype> tag)
|
||||
{
|
||||
ent.Comp.DenyTags.Add(tag);
|
||||
Dirty(ent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a tag from an access reader that denied a user access.
|
||||
/// </summary>
|
||||
/// <param name="ent">The access reader entity.</param>
|
||||
/// <param name="tag">The tag being removed.</param>
|
||||
public void RemoveDenyTag(Entity<AccessReaderComponent> ent, ProtoId<AccessLevelPrototype> tag)
|
||||
{
|
||||
ent.Comp.DenyTags.Remove(tag);
|
||||
Dirty(ent);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Enables/disables the access reader on an entity.
|
||||
/// </summary>
|
||||
/// <param name="ent">The access reader entity.</param>
|
||||
/// <param name="enabled">Enable/disable the access reader.</param>
|
||||
public void SetActive(Entity<AccessReaderComponent> ent, bool enabled)
|
||||
{
|
||||
ent.Comp.Enabled = enabled;
|
||||
Dirty(ent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables/disables the logging of access attempts on an access reader entity.
|
||||
/// </summary>
|
||||
/// <param name="ent">The access reader entity.</param>
|
||||
/// <param name="enabled">Enable/disable logging.</param>
|
||||
public void SetLoggingActive(Entity<AccessReaderComponent> ent, bool enabled)
|
||||
{
|
||||
ent.Comp.LoggingDisabled = !enabled;
|
||||
Dirty(ent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches an entity's hand and ID slot for any contained items.
|
||||
/// </summary>
|
||||
/// <param name="uid">The entity being searched.</param>
|
||||
/// <param name="items">The collection of found items.</param>
|
||||
/// <returns>True if one or more items were found.</returns>
|
||||
public bool FindAccessItemsInventory(EntityUid uid, out HashSet<EntityUid> items)
|
||||
{
|
||||
items = new();
|
||||
|
||||
foreach (var item in _handsSystem.EnumerateHeld(uid))
|
||||
{
|
||||
items.Add(item);
|
||||
}
|
||||
items = new(_handsSystem.EnumerateHeld(uid));
|
||||
|
||||
// maybe its inside an inventory slot?
|
||||
if (_inventorySystem.TryGetSlotEntity(uid, "id", out var idUid))
|
||||
|
|
@ -393,9 +668,11 @@ public sealed class AccessReaderSystem : EntitySystem
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try to find <see cref="AccessComponent"/> on this item
|
||||
/// or inside this item (if it's pda)
|
||||
/// Try to find <see cref="AccessComponent"/> on this entity or inside it (if it's a PDA).
|
||||
/// </summary>
|
||||
/// <param name="uid">The entity being searched.</param>
|
||||
/// <param name="tags">The access tags that were found.</param>
|
||||
/// <returns>True if one or more access tags were found.</returns>
|
||||
private bool FindAccessTagsItem(EntityUid uid, out HashSet<ProtoId<AccessLevelPrototype>> tags)
|
||||
{
|
||||
tags = new();
|
||||
|
|
@ -406,9 +683,11 @@ public sealed class AccessReaderSystem : EntitySystem
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try to find <see cref="StationRecordKeyStorageComponent"/> on this item
|
||||
/// or inside this item (if it's pda)
|
||||
/// Try to find <see cref="StationRecordKeyStorageComponent"/> on this entity or inside it (if it's a PDA).
|
||||
/// </summary>
|
||||
/// <param name="uid">The entity being searched.</param>
|
||||
/// <param name="key">The station record key that was found.</param>
|
||||
/// <returns>True if a station record key was found.</returns>
|
||||
private bool FindStationRecordKeyItem(EntityUid uid, [NotNullWhen(true)] out StationRecordKey? key)
|
||||
{
|
||||
if (TryComp(uid, out StationRecordKeyStorageComponent? storage) && storage.Key != null)
|
||||
|
|
@ -462,15 +741,20 @@ public sealed class AccessReaderSystem : EntitySystem
|
|||
/// </summary>
|
||||
/// <param name="ent">The reader to log the access on</param>
|
||||
/// <param name="name">The name to log as</param>
|
||||
public void LogAccess(Entity<AccessReaderComponent> ent, string name)
|
||||
public void LogAccess(Entity<AccessReaderComponent> ent, string name, TimeSpan? accessTime = null, bool force = false)
|
||||
{
|
||||
if (IsPaused(ent) || ent.Comp.LoggingDisabled)
|
||||
return;
|
||||
if (!force)
|
||||
{
|
||||
if (IsPaused(ent) || ent.Comp.LoggingDisabled)
|
||||
return;
|
||||
|
||||
if (ent.Comp.AccessLog.Count >= ent.Comp.AccessLogLimit)
|
||||
ent.Comp.AccessLog.Dequeue();
|
||||
if (ent.Comp.AccessLog.Count >= ent.Comp.AccessLogLimit)
|
||||
ent.Comp.AccessLog.Dequeue();
|
||||
}
|
||||
|
||||
var stationTime = _gameTiming.CurTime.Subtract(_gameTicker.RoundStartTimeSpan);
|
||||
var stationTime = accessTime ?? _gameTiming.CurTime.Subtract(_gameTicker.RoundStartTimeSpan);
|
||||
ent.Comp.AccessLog.Enqueue(new AccessRecord(stationTime, name));
|
||||
|
||||
Dirty(ent);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ public abstract partial class SharedBuckleSystem
|
|||
public static ProtoId<AlertCategoryPrototype> BuckledAlertCategory = "Buckled";
|
||||
|
||||
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
|
||||
[Dependency] private readonly ActionBlockerSystem _actionBlocker = default!;
|
||||
|
||||
private void InitializeBuckle()
|
||||
{
|
||||
|
|
@ -557,7 +556,7 @@ public abstract partial class SharedBuckleSystem
|
|||
if (!_interaction.InRangeUnobstructed(user.Value, strap.Owner, buckle.Comp.Range, popup: popup))
|
||||
return false;
|
||||
|
||||
if (user.Value != buckle.Owner && !_actionBlocker.CanComplexInteract(user.Value))
|
||||
if (user.Value != buckle.Owner && !ActionBlocker.CanComplexInteract(user.Value))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ public sealed partial class ClimbSystem : VirtualController
|
|||
|
||||
private void AddClimbableVerb(EntityUid uid, ClimbableComponent component, GetVerbsEvent<AlternativeVerb> args)
|
||||
{
|
||||
if (!args.CanAccess || !args.CanInteract || !_actionBlockerSystem.CanMove(args.User))
|
||||
if (!args.CanAccess || !args.CanInteract || !_actionBlockerSystem.CanMove(args.User) || !component.Vaultable)
|
||||
return;
|
||||
|
||||
if (!TryComp(args.User, out ClimbingComponent? climbingComponent) || climbingComponent.IsClimbing || !climbingComponent.CanClimb)
|
||||
|
|
|
|||
|
|
@ -17,33 +17,46 @@ namespace Content.Shared.CombatMode.Pacification;
|
|||
[Access(typeof(PacificationSystem))]
|
||||
public sealed partial class PacifiedComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// If true, this will prevent you from disarming opponents in combat.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool DisallowDisarm = false;
|
||||
|
||||
/// <summary>
|
||||
/// If true, this will disable combat entirely instead of only disallowing attacking living creatures and harmful things.
|
||||
/// If true, this will disable combat entirely instead of only disallowing attacking living creatures and harmful things.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool DisallowAllCombat = false;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// When attempting attack against the same entity multiple times,
|
||||
/// don't spam popups every frame and instead have a cooldown.
|
||||
/// When attempting attack against the same entity multiple times,
|
||||
/// don't spam popups every frame and instead have a cooldown.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public TimeSpan PopupCooldown = TimeSpan.FromSeconds(3.0);
|
||||
|
||||
/// <summary>
|
||||
/// Time at which the next popup can be shown.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
[AutoPausedField]
|
||||
public TimeSpan? NextPopupTime = null;
|
||||
|
||||
/// <summary>
|
||||
/// The last entity attacked, used for popup purposes (avoid spam)
|
||||
/// The last entity attacked, used for popup purposes (avoid spam)
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public EntityUid? LastAttackedEntity = null;
|
||||
|
||||
/// <summary>
|
||||
/// The alert to show to owners of this component.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public ProtoId<AlertPrototype> PacifiedAlert = "Pacified";
|
||||
|
||||
// Prevent cheat clients from using this to identify thieves and players that cannot fight back.
|
||||
// This should not matter for prediction reasons since it only blocks user input.
|
||||
public override bool SendOnlyToOwner => true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Light.Components;
|
||||
|
||||
|
|
@ -25,11 +26,32 @@ public sealed partial class SunShadowCycleComponent : Component
|
|||
/// Time to have each direction applied. Will lerp from the current value to the next one.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public List<(float Ratio, Vector2 Direction, float Alpha)> Directions = new()
|
||||
public List<SunShadowCycleDirection> Directions = new()
|
||||
{
|
||||
(0f, new Vector2(0f, 3f), 0f),
|
||||
(0.25f, new Vector2(-3f, -0.1f), 0.5f),
|
||||
(0.5f, new Vector2(0f, -3f), 0.8f),
|
||||
(0.75f, new Vector2(3f, -0.1f), 0.5f),
|
||||
new SunShadowCycleDirection(0f, new Vector2(0f, 3f), 0f),
|
||||
new SunShadowCycleDirection(0.25f, new Vector2(-3f, -0.1f), 0.5f),
|
||||
new SunShadowCycleDirection(0.5f, new Vector2(0f, -3f), 0.8f),
|
||||
new SunShadowCycleDirection(0.75f, new Vector2(3f, -0.1f), 0.5f),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
[DataDefinition]
|
||||
[Serializable, NetSerializable]
|
||||
public partial record struct SunShadowCycleDirection
|
||||
{
|
||||
[DataField]
|
||||
public float Ratio;
|
||||
|
||||
[DataField]
|
||||
public Vector2 Direction;
|
||||
|
||||
[DataField]
|
||||
public float Alpha;
|
||||
|
||||
public SunShadowCycleDirection(float ratio, Vector2 direction, float alpha)
|
||||
{
|
||||
Ratio = ratio;
|
||||
Direction = direction;
|
||||
Alpha = alpha;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ public sealed partial class NpcFactionSystem : EntitySystem
|
|||
/// <summary>
|
||||
/// Returns whether an entity is a member of a faction.
|
||||
/// </summary>
|
||||
public bool IsMember(Entity<NpcFactionMemberComponent?> ent, string faction)
|
||||
public bool IsMember(Entity<NpcFactionMemberComponent?> ent, [ForbidLiteral] string faction)
|
||||
{
|
||||
if (!Resolve(ent, ref ent.Comp, false))
|
||||
return false;
|
||||
|
|
@ -104,7 +104,7 @@ public sealed partial class NpcFactionSystem : EntitySystem
|
|||
/// Returns whether an entity is a member of any listed faction.
|
||||
/// If the list is empty this returns false.
|
||||
/// </summary>
|
||||
public bool IsMemberOfAny(Entity<NpcFactionMemberComponent?> ent, IEnumerable<ProtoId<NpcFactionPrototype>> factions)
|
||||
public bool IsMemberOfAny(Entity<NpcFactionMemberComponent?> ent, [ForbidLiteral] IEnumerable<ProtoId<NpcFactionPrototype>> factions)
|
||||
{
|
||||
if (!Resolve(ent, ref ent.Comp, false))
|
||||
return false;
|
||||
|
|
@ -121,7 +121,7 @@ public sealed partial class NpcFactionSystem : EntitySystem
|
|||
/// <summary>
|
||||
/// Adds this entity to the particular faction.
|
||||
/// </summary>
|
||||
public void AddFaction(Entity<NpcFactionMemberComponent?> ent, string faction, bool dirty = true)
|
||||
public void AddFaction(Entity<NpcFactionMemberComponent?> ent, [ForbidLiteral] string faction, bool dirty = true)
|
||||
{
|
||||
if (!_proto.HasIndex<NpcFactionPrototype>(faction))
|
||||
{
|
||||
|
|
@ -140,7 +140,7 @@ public sealed partial class NpcFactionSystem : EntitySystem
|
|||
/// <summary>
|
||||
/// Adds this entity to the particular faction.
|
||||
/// </summary>
|
||||
public void AddFactions(Entity<NpcFactionMemberComponent?> ent, HashSet<ProtoId<NpcFactionPrototype>> factions, bool dirty = true)
|
||||
public void AddFactions(Entity<NpcFactionMemberComponent?> ent, [ForbidLiteral] HashSet<ProtoId<NpcFactionPrototype>> factions, bool dirty = true)
|
||||
{
|
||||
ent.Comp ??= EnsureComp<NpcFactionMemberComponent>(ent);
|
||||
|
||||
|
|
@ -162,7 +162,7 @@ public sealed partial class NpcFactionSystem : EntitySystem
|
|||
/// <summary>
|
||||
/// Removes this entity from the particular faction.
|
||||
/// </summary>
|
||||
public void RemoveFaction(Entity<NpcFactionMemberComponent?> ent, string faction, bool dirty = true)
|
||||
public void RemoveFaction(Entity<NpcFactionMemberComponent?> ent, [ForbidLiteral] string faction, bool dirty = true)
|
||||
{
|
||||
if (!_proto.HasIndex<NpcFactionPrototype>(faction))
|
||||
{
|
||||
|
|
@ -221,7 +221,7 @@ public sealed partial class NpcFactionSystem : EntitySystem
|
|||
return GetNearbyFactions(ent, range, ent.Comp.FriendlyFactions);
|
||||
}
|
||||
|
||||
private IEnumerable<EntityUid> GetNearbyFactions(EntityUid entity, float range, HashSet<ProtoId<NpcFactionPrototype>> factions)
|
||||
private IEnumerable<EntityUid> GetNearbyFactions(EntityUid entity, float range, [ForbidLiteral] HashSet<ProtoId<NpcFactionPrototype>> factions)
|
||||
{
|
||||
var xform = Transform(entity);
|
||||
foreach (var ent in _lookup.GetEntitiesInRange<NpcFactionMemberComponent>(_xform.GetMapCoordinates((entity, xform)), range))
|
||||
|
|
@ -247,12 +247,12 @@ public sealed partial class NpcFactionSystem : EntitySystem
|
|||
return ent.Comp.Factions.Overlaps(other.Comp.Factions) || ent.Comp.FriendlyFactions.Overlaps(other.Comp.Factions);
|
||||
}
|
||||
|
||||
public bool IsFactionFriendly(string target, string with)
|
||||
public bool IsFactionFriendly([ForbidLiteral] string target, [ForbidLiteral] string with)
|
||||
{
|
||||
return _factions[target].Friendly.Contains(with) && _factions[with].Friendly.Contains(target);
|
||||
}
|
||||
|
||||
public bool IsFactionFriendly(string target, Entity<NpcFactionMemberComponent?> with)
|
||||
public bool IsFactionFriendly([ForbidLiteral] string target, Entity<NpcFactionMemberComponent?> with)
|
||||
{
|
||||
if (!Resolve(with, ref with.Comp, false))
|
||||
return false;
|
||||
|
|
@ -261,12 +261,12 @@ public sealed partial class NpcFactionSystem : EntitySystem
|
|||
with.Comp.FriendlyFactions.Contains(target);
|
||||
}
|
||||
|
||||
public bool IsFactionHostile(string target, string with)
|
||||
public bool IsFactionHostile([ForbidLiteral] string target, [ForbidLiteral] string with)
|
||||
{
|
||||
return _factions[target].Hostile.Contains(with) && _factions[with].Hostile.Contains(target);
|
||||
}
|
||||
|
||||
public bool IsFactionHostile(string target, Entity<NpcFactionMemberComponent?> with)
|
||||
public bool IsFactionHostile([ForbidLiteral] string target, Entity<NpcFactionMemberComponent?> with)
|
||||
{
|
||||
if (!Resolve(with, ref with.Comp, false))
|
||||
return false;
|
||||
|
|
@ -275,7 +275,7 @@ public sealed partial class NpcFactionSystem : EntitySystem
|
|||
with.Comp.HostileFactions.Contains(target);
|
||||
}
|
||||
|
||||
public bool IsFactionNeutral(string target, string with)
|
||||
public bool IsFactionNeutral([ForbidLiteral] string target, [ForbidLiteral] string with)
|
||||
{
|
||||
return !IsFactionFriendly(target, with) && !IsFactionHostile(target, with);
|
||||
}
|
||||
|
|
@ -283,7 +283,7 @@ public sealed partial class NpcFactionSystem : EntitySystem
|
|||
/// <summary>
|
||||
/// Makes the source faction friendly to the target faction, 1-way.
|
||||
/// </summary>
|
||||
public void MakeFriendly(string source, string target)
|
||||
public void MakeFriendly([ForbidLiteral] string source, [ForbidLiteral] string target)
|
||||
{
|
||||
if (!_factions.TryGetValue(source, out var sourceFaction))
|
||||
{
|
||||
|
|
@ -305,7 +305,7 @@ public sealed partial class NpcFactionSystem : EntitySystem
|
|||
/// <summary>
|
||||
/// Makes the source faction hostile to the target faction, 1-way.
|
||||
/// </summary>
|
||||
public void MakeHostile(string source, string target)
|
||||
public void MakeHostile([ForbidLiteral] string source, [ForbidLiteral] string target)
|
||||
{
|
||||
if (!_factions.TryGetValue(source, out var sourceFaction))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,17 +3,38 @@ using Robust.Shared.GameStates;
|
|||
|
||||
namespace Content.Shared.StationAi;
|
||||
|
||||
/// <summary>
|
||||
/// Attached to entities that grant vision to the station AI, such as cameras.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, Access(typeof(SharedStationAiSystem))]
|
||||
public sealed partial class StationAiVisionComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines whether the entity is actively providing vision to the station AI.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public bool Enabled = true;
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the entity's vision is blocked by walls.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public bool Occluded = true;
|
||||
|
||||
/// <summary>
|
||||
/// Range in tiles
|
||||
/// Determines whether the entity needs to be receiving power to provide vision to the station AI.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public bool NeedsPower = false;
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the entity needs to be anchored to provide vision to the station AI.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public bool NeedsAnchoring = false;
|
||||
|
||||
/// <summary>
|
||||
/// Vision range in tiles.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public float Range = 7.5f;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
using Content.Shared.Power.EntitySystems;
|
||||
using Content.Shared.StationAi;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.Threading;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared.Silicons.StationAi;
|
||||
|
||||
|
|
@ -18,6 +18,7 @@ public sealed class StationAiVisionSystem : EntitySystem
|
|||
[Dependency] private readonly EntityLookupSystem _lookup = default!;
|
||||
[Dependency] private readonly SharedMapSystem _maps = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _xforms = default!;
|
||||
[Dependency] private readonly SharedPowerReceiverSystem _power = default!;
|
||||
|
||||
private SeedJob _seedJob;
|
||||
private ViewJob _job;
|
||||
|
|
@ -83,6 +84,12 @@ public sealed class StationAiVisionSystem : EntitySystem
|
|||
if (!seed.Comp.Enabled)
|
||||
continue;
|
||||
|
||||
if (seed.Comp.NeedsPower && !_power.IsPowered(seed.Owner))
|
||||
continue;
|
||||
|
||||
if (seed.Comp.NeedsAnchoring && !Transform(seed.Owner).Anchored)
|
||||
continue;
|
||||
|
||||
_job.Data.Add(seed);
|
||||
}
|
||||
|
||||
|
|
@ -164,6 +171,12 @@ public sealed class StationAiVisionSystem : EntitySystem
|
|||
if (!seed.Comp.Enabled)
|
||||
continue;
|
||||
|
||||
if (seed.Comp.NeedsPower && !_power.IsPowered(seed.Owner))
|
||||
continue;
|
||||
|
||||
if (seed.Comp.NeedsAnchoring && !Transform(seed.Owner).Anchored)
|
||||
continue;
|
||||
|
||||
_job.Data.Add(seed);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ namespace Content.Shared.Weather;
|
|||
public abstract class SharedWeatherSystem : EntitySystem
|
||||
{
|
||||
[Dependency] protected readonly IGameTiming Timing = default!;
|
||||
[Dependency] protected readonly IMapManager MapManager = default!;
|
||||
[Dependency] protected readonly IPrototypeManager ProtoMan = default!;
|
||||
[Dependency] private readonly ITileDefinitionManager _tileDefManager = default!;
|
||||
[Dependency] private readonly MetaDataSystem _metadata = default!;
|
||||
|
|
|
|||
|
|
@ -1163,5 +1163,13 @@ Entries:
|
|||
id: 140
|
||||
time: '2025-05-27T23:44:15.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/37849
|
||||
- author: Samuka
|
||||
changes:
|
||||
- message: the command solution:adjreagent now actually works and no longer needs
|
||||
a "FixedPoint2" for the amount
|
||||
type: Fix
|
||||
id: 141
|
||||
time: '2025-06-08T03:47:37.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/38134
|
||||
Name: Admin
|
||||
Order: 2
|
||||
|
|
|
|||
|
|
@ -1,197 +1,4 @@
|
|||
Entries:
|
||||
- author: Vortebo
|
||||
changes:
|
||||
- message: Relic station revamped
|
||||
type: Tweak
|
||||
id: 8105
|
||||
time: '2025-03-24T16:36:44.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/35507
|
||||
- author: slarticodefast
|
||||
changes:
|
||||
- message: Adjusted thermal regulation again so you no longer overheat in hardsuits.
|
||||
type: Fix
|
||||
id: 8106
|
||||
time: '2025-03-24T23:55:17.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/36062
|
||||
- author: Velcroboy, ErhardSteinhauer, whatston3, MilonPL, Beck, ArtisticRoomba, ScarKy0
|
||||
changes:
|
||||
- message: Smuggler stashes! Will get spawned as a round start event and can also
|
||||
be found in a hacked ClothesMate. Will have loot from a large random pool.
|
||||
type: Add
|
||||
- message: Smuggler stashes can now be bought from the syndicate uplink for 2TC.
|
||||
type: Add
|
||||
id: 8107
|
||||
time: '2025-03-26T15:20:15.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/19460
|
||||
- author: slarticodefast
|
||||
changes:
|
||||
- message: Ghosts of paradox clones now have a name modifier so they can be distinguished
|
||||
by other ghosts.
|
||||
type: Tweak
|
||||
id: 8108
|
||||
time: '2025-03-26T15:30:14.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/35940
|
||||
- author: slarticodefast
|
||||
changes:
|
||||
- message: Paradox clones of nuclear operatives and head revolutionaries now have
|
||||
the corresponding faction icon and need to be killed for a crew major victory.
|
||||
type: Fix
|
||||
id: 8109
|
||||
time: '2025-03-26T15:34:19.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/35910
|
||||
- author: slarticodefast
|
||||
changes:
|
||||
- message: Further improved item copying for paradox clones.
|
||||
type: Tweak
|
||||
id: 8110
|
||||
time: '2025-03-26T16:13:03.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/35993
|
||||
- author: Centronias
|
||||
changes:
|
||||
- message: Raw meatballs, like steaks, can now be cooked in the microwave or on
|
||||
a grill.
|
||||
type: Add
|
||||
id: 8111
|
||||
time: '2025-03-27T06:26:13.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/36003
|
||||
- author: SlamBamActionman
|
||||
changes:
|
||||
- message: Liltenhead! Thank you for over 2 years of update videos, and congrats
|
||||
on the 100th video!
|
||||
type: Add
|
||||
id: 8112
|
||||
time: '2025-03-27T17:19:36.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/36104
|
||||
- author: metalgearsloth
|
||||
changes:
|
||||
- message: Rewrote how mob movement works to make movement more flexible in code.
|
||||
While this should largely function the same (apart from conveyors now being
|
||||
able to launch items) please report any bugs found.
|
||||
type: Tweak
|
||||
id: 8113
|
||||
time: '2025-03-27T22:29:03.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/35931
|
||||
- author: ViceEmargo
|
||||
changes:
|
||||
- message: Botanist's leather gloves must now be equipped in order to pick up Death
|
||||
Nettles.
|
||||
type: Add
|
||||
- message: Death Nettles will now pierce hardsuits, injecting 5 units of reagent.
|
||||
type: Tweak
|
||||
- message: Death Nettles will now "wilt" after 5 hits.
|
||||
type: Add
|
||||
- message: Fly Amanita has been changed to contain less Amatoxin.
|
||||
type: Tweak
|
||||
id: 8114
|
||||
time: '2025-03-29T09:35:16.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/25253
|
||||
- author: chromiumboy
|
||||
changes:
|
||||
- message: Sentry turrets can potentially be found guarding sensitive areas of the
|
||||
station. When deployed, they will shoot unauthorized personnel on sight with
|
||||
either stunning or lethal laser bolts. Note that only cyborgs and robots can
|
||||
safely pass sentry turrets that protect the station AI core
|
||||
type: Add
|
||||
id: 8115
|
||||
time: '2025-03-29T17:55:59.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/35123
|
||||
- author: Killerqu00
|
||||
changes:
|
||||
- message: Uncuffing someone with combat mode on will shove them down.
|
||||
type: Add
|
||||
id: 8116
|
||||
time: '2025-03-29T20:09:34.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/35193
|
||||
- author: metalgearsloth
|
||||
changes:
|
||||
- message: Jetpacks emit particles more frequently.
|
||||
type: Tweak
|
||||
id: 8117
|
||||
time: '2025-03-30T04:06:01.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/36093
|
||||
- author: beck-thompson
|
||||
changes:
|
||||
- message: Stethoscopes now automatically start doafters and also can tell if a
|
||||
patient is losing oxygen damage or gaining it.
|
||||
type: Add
|
||||
- message: Moths can no longer eat stethoscopes.
|
||||
type: Fix
|
||||
- message: Stethoscopes action button now works properly.
|
||||
type: Fix
|
||||
id: 8118
|
||||
time: '2025-03-31T02:27:08.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/36210
|
||||
- author: Tayrtahn
|
||||
changes:
|
||||
- message: Items thrown when someone slips now tend to scatter in the direction
|
||||
they are moving, and respect the item's mass.
|
||||
type: Tweak
|
||||
id: 8119
|
||||
time: '2025-03-31T22:00:04.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/36232
|
||||
- author: ScarKy0
|
||||
changes:
|
||||
- message: Thieves now start with the thieving satchel instead of their toolbox.
|
||||
The satchel will get all the selected kits spawned inside of it.
|
||||
type: Add
|
||||
- message: Thief Chameleon kit now comes with a backpack and a bonus pair of chameleon
|
||||
gloves. Be careful, they aren't thieving gloves and can be tough to tell apart!
|
||||
type: Tweak
|
||||
- message: Updated smuggler stachel's description to reflect what it's used for.
|
||||
type: Tweak
|
||||
- message: Thieving satchel and toolbox now correctly play a sound when their kits
|
||||
are selected.
|
||||
type: Fix
|
||||
id: 8120
|
||||
time: '2025-03-31T22:32:31.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/36201
|
||||
- author: Tayrtahn
|
||||
changes:
|
||||
- message: Electric grills no longer appear powered when cycled while disconnected
|
||||
from power.
|
||||
type: Fix
|
||||
- message: Interactions with electric grills are now predicted.
|
||||
type: Tweak
|
||||
id: 8121
|
||||
time: '2025-04-01T16:43:19.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/36241
|
||||
- author: MisterImp
|
||||
changes:
|
||||
- message: A new recipe has been added for pizza made with world peas, world peazza.
|
||||
type: Add
|
||||
id: 8122
|
||||
time: '2025-04-01T23:26:53.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/35191
|
||||
- author: Fildrance
|
||||
changes:
|
||||
- message: fixed missing deconstruct on RCD
|
||||
type: Fix
|
||||
id: 8123
|
||||
time: '2025-04-02T16:11:35.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/36255
|
||||
- author: qwerltaz
|
||||
changes:
|
||||
- message: Dragon rifts now shine a different color depending on charge progress.
|
||||
type: Add
|
||||
id: 8124
|
||||
time: '2025-04-02T18:37:35.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/36216
|
||||
- author: aada
|
||||
changes:
|
||||
- message: Diphenhydramine now causes light drowsiness.
|
||||
type: Tweak
|
||||
id: 8125
|
||||
time: '2025-04-03T06:29:52.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/36212
|
||||
- author: sowelipililimute
|
||||
changes:
|
||||
- message: You can now more easily interact with objects behind faded ones, and
|
||||
you can look behind fadeable objects in your FOV by hovering them with your
|
||||
mouse pointer
|
||||
type: Add
|
||||
id: 8126
|
||||
time: '2025-04-03T06:58:05.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/35863
|
||||
- author: whatston3
|
||||
changes:
|
||||
- message: Fancy tables and curtains now respect carpet stacks.
|
||||
|
|
@ -3928,3 +3735,172 @@
|
|||
id: 8616
|
||||
time: '2025-06-05T12:52:39.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/38080
|
||||
- author: Orsoniks
|
||||
changes:
|
||||
- message: Added more in-hand sprites for food items
|
||||
type: Add
|
||||
id: 8617
|
||||
time: '2025-06-05T21:06:38.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/38024
|
||||
- author: chromiumboy
|
||||
changes:
|
||||
- message: Holopads now provide less visual coverage to station AIs (1 tile radius,
|
||||
down from 7.5). Holopads must also be anchored to the floor to provide vision.
|
||||
type: Tweak
|
||||
id: 8618
|
||||
time: '2025-06-05T23:15:55.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/38059
|
||||
- author: Simyon
|
||||
changes:
|
||||
- message: Sleeper agents no longer have different codewords than round-start traitors.
|
||||
type: Fix
|
||||
id: 8619
|
||||
time: '2025-06-05T23:19:41.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/37928
|
||||
- author: Gentleman-Bird
|
||||
changes:
|
||||
- message: Fixed the "create soap" recipe so it can actually be made
|
||||
type: Fix
|
||||
id: 8620
|
||||
time: '2025-06-05T23:20:44.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/37923
|
||||
- author: Hitlinemoss
|
||||
changes:
|
||||
- message: The security mime mask has been added to the SecDrobe's manager inventory.
|
||||
type: Add
|
||||
id: 8621
|
||||
time: '2025-06-05T23:23:14.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/37890
|
||||
- author: ArtisticRoomba
|
||||
changes:
|
||||
- message: Most syndicate contraband have been given sell prices (depending on the
|
||||
"power" of the item) to discourage powergaming and encourage Security's interaction
|
||||
with Departmental Economy.
|
||||
type: Add
|
||||
id: 8622
|
||||
time: '2025-06-05T23:26:31.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/37835
|
||||
- author: RedBookcase
|
||||
changes:
|
||||
- message: The running and walking speed debuffs on equipped gear have been standardized.
|
||||
type: Tweak
|
||||
id: 8623
|
||||
time: '2025-06-05T23:27:02.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/37828
|
||||
- author: august-sun
|
||||
changes:
|
||||
- message: Added individual Bulldog drum magazines for sale in the syndicate uplink.
|
||||
Ammo types available are pellets and slugs.
|
||||
type: Add
|
||||
id: 8624
|
||||
time: '2025-06-05T23:35:15.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/37917
|
||||
- author: Xeri7
|
||||
changes:
|
||||
- message: Added ability to pick up potted plants in two hands, as well as store
|
||||
them in crates!
|
||||
type: Add
|
||||
- message: Added purchasable potted plant crate!
|
||||
type: Add
|
||||
id: 8625
|
||||
time: '2025-06-05T23:36:31.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/37591
|
||||
- author: K-Dynamic
|
||||
changes:
|
||||
- message: Rifle crates with two Lecters and four magazines can be ordered from
|
||||
Cargo for 8000 spesos.
|
||||
type: Add
|
||||
- message: Lethal Weapons gift event now includes a Rifle crate.
|
||||
type: Tweak
|
||||
- message: SMG crates are properly described and no longer reference 'semiautomatic
|
||||
rifles.'
|
||||
type: Tweak
|
||||
id: 8626
|
||||
time: '2025-06-05T23:40:51.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/35535
|
||||
- author: themias
|
||||
changes:
|
||||
- message: Wearing a muzzle now reduces the sound of vocal emotes
|
||||
type: Tweak
|
||||
id: 8627
|
||||
time: '2025-06-05T23:45:55.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/34444
|
||||
- author: RedBookcase
|
||||
changes:
|
||||
- message: Added Scrap Armor and Scrap Helmets.
|
||||
type: Add
|
||||
id: 8628
|
||||
time: '2025-06-06T00:13:36.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/37601
|
||||
- author: Samuka
|
||||
changes:
|
||||
- message: Fire bombs are now minor contra
|
||||
type: Tweak
|
||||
- message: Pipe bombs are now minor contra
|
||||
type: Tweak
|
||||
id: 8629
|
||||
time: '2025-06-06T02:28:04.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/38088
|
||||
- author: Minemoder
|
||||
changes:
|
||||
- message: Shark plushies now bite.
|
||||
type: Tweak
|
||||
id: 8630
|
||||
time: '2025-06-06T21:07:10.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/38113
|
||||
- author: themias
|
||||
changes:
|
||||
- message: Increased the chance of throwing trash into a disposal unit
|
||||
type: Tweak
|
||||
id: 8631
|
||||
time: '2025-06-06T22:13:21.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/38116
|
||||
- author: spanky-spanky
|
||||
changes:
|
||||
- message: Landmines now light up in the dark!
|
||||
type: Tweak
|
||||
id: 8632
|
||||
time: '2025-06-06T23:01:14.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/38092
|
||||
- author: slarticodefast
|
||||
changes:
|
||||
- message: Fixed wallmount vending machines dispensing in the wrong direction.
|
||||
type: Fix
|
||||
id: 8633
|
||||
time: '2025-06-06T23:08:16.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/38112
|
||||
- author: hoshizora-sayo
|
||||
changes:
|
||||
- message: Added proper name to the chameleon controller implanter
|
||||
type: Add
|
||||
id: 8634
|
||||
time: '2025-06-07T02:29:13.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/38117
|
||||
- author: K-Dynamic
|
||||
changes:
|
||||
- message: Disablers now hold 16 shots instead of 20
|
||||
type: Tweak
|
||||
id: 8635
|
||||
time: '2025-06-07T13:05:25.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/36019
|
||||
- author: perryprog
|
||||
changes:
|
||||
- message: Diamonds can now be ejected from lathes and material silos.
|
||||
type: Fix
|
||||
id: 8636
|
||||
time: '2025-06-07T17:36:58.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/38132
|
||||
- author: slarticodefast
|
||||
changes:
|
||||
- message: Fixed the stripping UI layout when having more than 2 hands.
|
||||
type: Fix
|
||||
id: 8637
|
||||
time: '2025-06-07T22:23:46.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/37577
|
||||
- author: Nox38
|
||||
changes:
|
||||
- message: Space Carp ghost roles no longer have a raffle!
|
||||
type: Tweak
|
||||
id: 8638
|
||||
time: '2025-06-08T02:49:44.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/38101
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1 @@
|
|||
cmd-showmeleespread-desc = Shows the current weapon's range and arc for debugging.
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
cmd-persistencesave-desc = Saves server data to a persistence file to be loaded later.
|
||||
cmd-persistencesave-usage = persistencesave [mapId] [filePath - default: game.map (CCVar) ]
|
||||
cmd-persistencesave-no-path = filePath was not specified and CCVar {$cvar} is not set. Manually set the filePath param in order to save the map.
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
cmd-showaccessreaders-desc = Toggles showing access reader permissions on the map
|
||||
cmd-showaccessreaders-help =
|
||||
Overlay Info:
|
||||
-Disabled | The access reader is disabled
|
||||
+Unrestricted | The access reader has no restrictions
|
||||
+Set [Index]: [Tag Name]| A tag in an access set (accessor needs all tags in the set to be allowed by the set)
|
||||
+Key [StationUid]: [StationRecordKeyId] | A StationRecordKey that is allowed
|
||||
-Tag [Tag Name] | A tag that is not allowed (takes priority over other allows)
|
||||
cmd-showaccessreaders-status = Set access reader debug overlay to {$status}.
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
cmd-showemergencyshuttle-desc = Shows the expected position of the emergency shuttle.
|
||||
cmd-showemergencyshuttle-status = Set emergency shuttle debug to {$status}.
|
||||
|
|
@ -1 +0,0 @@
|
|||
cmd-persistencesave-no-path = filePath was not specified and CCVar {$cvar} is not set. Manually set the filePath param in order to save the map.
|
||||
|
|
@ -85,16 +85,22 @@ uplink-shrapnel-grenade-desc = Launches a spray of sharp fragments dealing great
|
|||
|
||||
# Ammo
|
||||
uplink-pistol-magazine-name = Pistol Magazine (.35 auto)
|
||||
uplink-pistol-magazine-desc = Pistol magazine with 10 catridges. Compatible with the Viper.
|
||||
uplink-pistol-magazine-desc = Pistol magazine with 10 cartridges. Compatible with the Viper.
|
||||
|
||||
uplink-pistol-magazine-c20r-name = SMG magazine (.35 auto)
|
||||
uplink-pistol-magazine-c20r-desc = Rifle magazine with 30 catridges. Compatible with C-20r.
|
||||
uplink-pistol-magazine-c20r-desc = Rifle magazine with 30 cartridges. Compatible with C-20r.
|
||||
|
||||
uplink-magazine-bulldog-pellet-name = Drum magazine (.50 pellet)
|
||||
uplink-magazine-bulldog-pellet-desc = Shotgun magazine with 8 shells filled with buckshot. Compatible with the Bulldog.
|
||||
|
||||
uplink-magazine-bulldog-slug-name = Drum magazine (.50 slug)
|
||||
uplink-magazine-bulldog-slug-desc = Shotgun magazine with 8 shells filled with slugs. Compatible with the Bulldog.
|
||||
|
||||
uplink-pistol-magazine-caseless-name = Pistol Magazine (.25 caseless)
|
||||
uplink-pistol-magazine-caseless-desc = Pistol magazine with 10 catridges. Compatible with the Cobra.
|
||||
uplink-pistol-magazine-caseless-desc = Pistol magazine with 10 cartridges. Compatible with the Cobra.
|
||||
|
||||
uplink-speedloader-magnum-name = Speedloader (.45 magnum AP)
|
||||
uplink-speedloader-magnu-desc = Revolver speedloader with 6 armor-piercing catridges, capable of ignoring armor entirely. Compatible with the Python.
|
||||
uplink-speedloader-magnu-desc = Revolver speedloader with 6 armor-piercing cartridges, capable of ignoring armor entirely. Compatible with the Python.
|
||||
|
||||
uplink-mosin-ammo-name = Ammunition box (.30 rifle)
|
||||
uplink-mosin-ammo-desc = A box of 60 cartridges for the surplus rifle.
|
||||
|
|
|
|||
|
|
@ -69,6 +69,8 @@ construction-graph-tag-match-stick = match stick
|
|||
construction-graph-tag-potato = a potato
|
||||
construction-graph-tag-wheat-bushel = wheat bushel
|
||||
construction-graph-tag-corgi-hide = corgi hide
|
||||
construction-graph-tag-apron = an apron
|
||||
construction-graph-tag-utility-belt = a utility belt
|
||||
soil-construction-graph-any-mushroom = any mushroom
|
||||
|
||||
# toys
|
||||
|
|
|
|||
|
|
@ -67,3 +67,13 @@
|
|||
cost: 5200
|
||||
category: cargoproduct-category-name-armory
|
||||
group: market
|
||||
|
||||
- type: cargoProduct
|
||||
id: ArmoryRifle
|
||||
icon:
|
||||
sprite: Objects/Weapons/Guns/Rifles/lecter.rsi
|
||||
state: icon
|
||||
product: CrateArmoryRifle
|
||||
cost: 8000
|
||||
category: cargoproduct-category-name-armory
|
||||
group: market
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@
|
|||
cost: 500
|
||||
category: cargoproduct-category-name-fun
|
||||
group: market
|
||||
|
||||
|
||||
- type: cargoProduct
|
||||
id: FunSharkPlushies
|
||||
icon:
|
||||
|
|
@ -347,3 +347,13 @@
|
|||
cost: 1500
|
||||
category: cargoproduct-category-name-fun
|
||||
group: market
|
||||
|
||||
- type: cargoProduct
|
||||
id: FunPlants
|
||||
icon:
|
||||
sprite: Structures/Furniture/potted_plants.rsi
|
||||
state: random
|
||||
product: CratePlants
|
||||
cost: 1000
|
||||
category: cargoproduct-category-name-fun
|
||||
group: market
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# id: CrateArmorySMG
|
||||
# parent: [ CrateWeaponSecure, BaseSecurityContraband ]
|
||||
# name: SMG crate
|
||||
# description: Contains two high-powered, semiautomatic rifles with four mags. Requires Armory access to open.
|
||||
# description: Contains two SMGs with four mags. Requires Armory access to open.
|
||||
# components:
|
||||
# - type: StorageFill
|
||||
# contents:
|
||||
|
|
@ -91,3 +91,16 @@
|
|||
amount: 2
|
||||
- id: RiotShield
|
||||
amount: 2
|
||||
|
||||
- type: entity
|
||||
id: CrateArmoryRifle
|
||||
parent: [ CrateWeaponSecure, BaseSecurityContraband ]
|
||||
name: rifle crate
|
||||
description: Contains two high-powered assault rifles with four mags. Requires Armory access to open.
|
||||
components:
|
||||
- type: StorageFill
|
||||
contents:
|
||||
- id: WeaponRifleLecter
|
||||
amount: 2
|
||||
- id: MagazineRifle
|
||||
amount: 4
|
||||
|
|
|
|||
|
|
@ -66,6 +66,49 @@
|
|||
- id: PlushieRedfox
|
||||
# Sunrise-end
|
||||
|
||||
- type: entityTable
|
||||
id: AllPottedPlantsTable
|
||||
table: !type:GroupSelector
|
||||
children:
|
||||
- id: PottedPlant0
|
||||
- id: PottedPlant1
|
||||
- id: PottedPlant2
|
||||
- id: PottedPlant3
|
||||
- id: PottedPlant4
|
||||
- id: PottedPlant5
|
||||
- id: PottedPlant6
|
||||
- id: PottedPlant7
|
||||
- id: PottedPlant8
|
||||
- id: PottedPlant10
|
||||
- id: PottedPlant11
|
||||
- id: PottedPlant12
|
||||
- id: PottedPlant13
|
||||
- id: PottedPlant14
|
||||
- id: PottedPlant15
|
||||
- id: PottedPlant16
|
||||
- id: PottedPlant17
|
||||
- id: PottedPlant18
|
||||
- id: PottedPlant19
|
||||
- id: PottedPlant20
|
||||
- id: PottedPlant21
|
||||
- id: PottedPlant22
|
||||
- id: PottedPlant23
|
||||
- id: PottedPlant24
|
||||
- id: PottedPlant26
|
||||
|
||||
- type: entity
|
||||
id: CratePlants
|
||||
parent: CrateGenericSteel
|
||||
name: plant crate
|
||||
description: A variety pack of potted plants to spruce up your station!
|
||||
components:
|
||||
- type: EntityTableContainerFill
|
||||
containers:
|
||||
entity_storage: !type:NestedSelector
|
||||
tableId: AllPottedPlantsTable
|
||||
rolls: !type:ConstantNumberSelector
|
||||
value: 5
|
||||
|
||||
- type: entity
|
||||
id: CrateFunPlushie
|
||||
parent: CrateGenericSteel
|
||||
|
|
|
|||
|
|
@ -135,6 +135,8 @@
|
|||
- id: Multitool
|
||||
- id: ClothingHandsGlovesCombat
|
||||
- id: ClothingEyesGlassesWelding #Sunrise-edit: rebalance toolbox
|
||||
- type: StaticPrice
|
||||
price: 1000
|
||||
|
||||
- type: entity
|
||||
id: ToolboxGoldFilled
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
PepperSprayBottleBlue: 2 # Sunrise-Edit
|
||||
contrabandInventory:
|
||||
ClothingMaskClownSecurity: 1
|
||||
ClothingMaskMimeSecurity: 1
|
||||
ToyFigurineSecurity: 1
|
||||
ToyFigurineWarden: 1
|
||||
ToyFigurineHeadOfSecurity: 1
|
||||
|
|
|
|||
|
|
@ -592,6 +592,29 @@
|
|||
- AssaultOpsUplink
|
||||
#Sunrise-end
|
||||
|
||||
# For the Bulldog
|
||||
- type: listing
|
||||
id: UplinkMagazineShotgunPellet
|
||||
name: uplink-magazine-bulldog-pellet-name
|
||||
description: uplink-magazine-bulldog-pellet-desc
|
||||
icon: { sprite: /Textures/Objects/Weapons/Guns/Ammunition/Magazine/Shotgun/m12.rsi, state: pellets }
|
||||
productEntity: MagazineShotgun
|
||||
cost:
|
||||
Telecrystal: 2
|
||||
categories:
|
||||
- UplinkAmmo
|
||||
|
||||
- type: listing
|
||||
id: UplinkMagazineShotgunSlug
|
||||
name: uplink-magazine-bulldog-slug-name
|
||||
description: uplink-magazine-bulldog-slug-desc
|
||||
icon: { sprite: /Textures/Objects/Weapons/Guns/Ammunition/Magazine/Shotgun/m12.rsi, state: slug }
|
||||
productEntity: MagazineShotgunSlug
|
||||
cost:
|
||||
Telecrystal: 3
|
||||
categories:
|
||||
- UplinkAmmo
|
||||
|
||||
# For the Cobra
|
||||
- type: listing
|
||||
id: UplinkMagazinePistolCaselessRifle
|
||||
|
|
|
|||
3
Resources/Prototypes/Codewords/codeword_factions.yml
Normal file
3
Resources/Prototypes/Codewords/codeword_factions.yml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
- type: codewordFaction
|
||||
id: Traitor
|
||||
generator: TraitorCodewordGenerator
|
||||
6
Resources/Prototypes/Codewords/codeword_generators.yml
Normal file
6
Resources/Prototypes/Codewords/codeword_generators.yml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
- type: codewordGenerator
|
||||
id: TraitorCodewordGenerator
|
||||
words:
|
||||
- Adjectives
|
||||
- Verbs
|
||||
amount: 4
|
||||
|
|
@ -284,6 +284,8 @@
|
|||
grid:
|
||||
- 0,0,7,3
|
||||
- 8,1,8,3
|
||||
- type: StaticPrice
|
||||
price: 1000
|
||||
|
||||
#Special
|
||||
- type: entity
|
||||
|
|
|
|||
|
|
@ -97,11 +97,10 @@
|
|||
- Multitool
|
||||
sprite: Clothing/Belt/belt_overlay.rsi
|
||||
- type: Appearance
|
||||
# Sunrise-Start
|
||||
- type: Tag
|
||||
tags:
|
||||
- UtilityBelt
|
||||
# Sunrise-End
|
||||
- WhitelistChameleon
|
||||
|
||||
- type: entity
|
||||
parent: [ClothingBeltStorageBase, BaseClothingBeltSounds] # Sunrise
|
||||
|
|
@ -671,6 +670,8 @@
|
|||
- Gun
|
||||
- BallisticAmmoProvider
|
||||
- CartridgeAmmo
|
||||
- type: StaticPrice
|
||||
price: 500
|
||||
|
||||
- type: entity
|
||||
parent: [ ClothingBeltStorageBase, BaseSecurityContraband ]
|
||||
|
|
@ -717,6 +718,8 @@
|
|||
sprite: Clothing/Belt/militarywebbing.rsi
|
||||
- type: ExplosionResistance
|
||||
damageCoefficient: 0.1
|
||||
- type: StaticPrice
|
||||
price: 500
|
||||
|
||||
- type: entity
|
||||
parent: ClothingBeltMilitaryWebbing
|
||||
|
|
|
|||
|
|
@ -124,6 +124,8 @@
|
|||
sprite: Clothing/Eyes/Glasses/outlawglasses.rsi
|
||||
- type: VisionCorrection
|
||||
- type: IdentityBlocker
|
||||
- type: StaticPrice
|
||||
price: 500
|
||||
|
||||
- type: entity
|
||||
parent: ClothingEyesBase
|
||||
|
|
|
|||
|
|
@ -421,7 +421,7 @@
|
|||
enum.MeleeSpeechUiKey.Key:
|
||||
type: MeleeSpeechBoundUserInterface
|
||||
- type: StaticPrice
|
||||
price: 0
|
||||
price: 2500
|
||||
- type: Tag
|
||||
tags:
|
||||
- Kangaroo
|
||||
|
|
@ -559,6 +559,8 @@
|
|||
tags:
|
||||
- WhitelistChameleon
|
||||
- Kangaroo
|
||||
- type: StaticPrice
|
||||
price: 2000
|
||||
|
||||
- type: entity
|
||||
name: stun knuckle dusters
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@
|
|||
sprite: Clothing/Head/Helmets/eva_syndicate.rsi
|
||||
- type: Clothing
|
||||
sprite: Clothing/Head/Helmets/eva_syndicate.rsi
|
||||
- type: StaticPrice
|
||||
price: 500 # Suit is 1000
|
||||
|
||||
#Cosmonaut Helmet
|
||||
- type: entity
|
||||
|
|
|
|||
|
|
@ -66,11 +66,6 @@
|
|||
- type: Tag
|
||||
tags:
|
||||
- WhitelistChameleon
|
||||
- type: HideLayerClothing
|
||||
layers:
|
||||
Hair: HEAD
|
||||
HeadTop: HEAD
|
||||
HeadSide: HEAD
|
||||
|
||||
- type: entity
|
||||
parent: ClothingHeadHatHardhatBase
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
- type: Tag
|
||||
tags:
|
||||
- ClothMade
|
||||
- Recyclable
|
||||
- Recyclable
|
||||
- WhitelistChameleon
|
||||
|
||||
- type: entity
|
||||
|
|
@ -383,6 +383,8 @@
|
|||
sprite: Clothing/Head/Hats/outlawhat.rsi
|
||||
- type: Clothing
|
||||
sprite: Clothing/Head/Hats/outlawhat.rsi
|
||||
- type: StaticPrice
|
||||
price: 500
|
||||
|
||||
- type: entity
|
||||
parent: ClothingHeadBase
|
||||
|
|
@ -477,8 +479,8 @@
|
|||
- state: icon-nobeard
|
||||
map: [ "foldedLayer" ]
|
||||
visible: true
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
- type: entity
|
||||
parent: ClothingHeadBase
|
||||
|
|
|
|||
|
|
@ -218,6 +218,8 @@
|
|||
sprite: Clothing/Head/Hats/catears.rsi
|
||||
- type: AddAccentClothing
|
||||
accent: OwOAccent
|
||||
- type: StaticPrice
|
||||
price: 15000
|
||||
|
||||
- type: entity
|
||||
parent: [ClothingHeadHatCatEars, BaseToggleClothing]
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@
|
|||
# The helmet itself
|
||||
- type: entity
|
||||
parent: [ClothingHeadHelmetBase, BaseMajorContraband]
|
||||
id: ClothingHeadHelmetScrap
|
||||
id: ClothingHeadHelmetScrap #When we get the tech for it this bad boy needs to be given a vision reduction when equipped. 1-2 tiles less than normal should be good.
|
||||
name: scrap helmet
|
||||
description: A cobbled-together helmet made from cabling, steel, and a bucket.
|
||||
components:
|
||||
|
|
@ -70,8 +70,8 @@
|
|||
- type: Armor
|
||||
modifiers:
|
||||
coefficients:
|
||||
Blunt: 0.85
|
||||
Slash: 0.8
|
||||
Blunt: 0.9
|
||||
Slash: 0.9
|
||||
Piercing: 0.9
|
||||
Heat: 0.9
|
||||
Shock: 1.05
|
||||
|
|
|
|||
|
|
@ -582,6 +582,24 @@
|
|||
- type: Clothing
|
||||
sprite: Clothing/Mask/scaredmime.rsi
|
||||
|
||||
- type: entity
|
||||
parent: [ClothingMaskMime, BaseSecurityContraband]
|
||||
id: ClothingMaskMimeSecurity
|
||||
name: security mime mask
|
||||
description: You have the right to remain silent.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: Clothing/Mask/mime_security.rsi
|
||||
- type: Clothing
|
||||
sprite: Clothing/Mask/mime_security.rsi
|
||||
- type: Armor
|
||||
modifiers:
|
||||
coefficients:
|
||||
Blunt: 0.95
|
||||
Slash: 0.95
|
||||
Piercing: 0.95
|
||||
Heat: 0.95
|
||||
|
||||
- type: entity
|
||||
parent: ClothingMaskBase
|
||||
id: ClothingMaskItalianMoustache
|
||||
|
|
|
|||
|
|
@ -96,6 +96,8 @@
|
|||
sprite: Clothing/Neck/Scarfs/syndiegreen.rsi
|
||||
- type: Clothing
|
||||
sprite: Clothing/Neck/Scarfs/syndiegreen.rsi
|
||||
- type: StaticPrice
|
||||
price: 500
|
||||
|
||||
- type: entity
|
||||
parent: [ ClothingScarfBase, BaseSyndicateContraband ]
|
||||
|
|
@ -107,6 +109,8 @@
|
|||
sprite: Clothing/Neck/Scarfs/syndiered.rsi
|
||||
- type: Clothing
|
||||
sprite: Clothing/Neck/Scarfs/syndiered.rsi
|
||||
- type: StaticPrice
|
||||
price: 500
|
||||
|
||||
- type: entity
|
||||
parent: [ ClothingScarfBase, BaseCentcommContraband ]
|
||||
|
|
|
|||
|
|
@ -167,6 +167,8 @@
|
|||
Heat: 0.9
|
||||
- type: ExplosionResistance
|
||||
damageCoefficient: 0.9
|
||||
- type: StaticPrice
|
||||
price: 1500
|
||||
|
||||
#Elite web vest
|
||||
- type: entity
|
||||
|
|
@ -195,6 +197,8 @@
|
|||
damageCoefficient: 0.5
|
||||
- type: FireProtection
|
||||
reduction: 0.85
|
||||
- type: StaticPrice
|
||||
price: 2500
|
||||
|
||||
#Mercenary web vest
|
||||
- type: entity
|
||||
|
|
@ -468,7 +472,7 @@
|
|||
Heat: 0.9
|
||||
Radiation: 0.8
|
||||
- type: ClothingSpeedModifier
|
||||
walkModifier: 0.7
|
||||
walkModifier: 0.65
|
||||
sprintModifier: 0.65
|
||||
- type: HeldSpeedModifier
|
||||
- type: ExplosionResistance
|
||||
|
|
@ -501,6 +505,7 @@
|
|||
Piercing: 0.4
|
||||
- type: ClothingSpeedModifier
|
||||
walkModifier: 0.8
|
||||
sprintModifier: 0.8
|
||||
- type: HeldSpeedModifier
|
||||
- type: ExplosionResistance
|
||||
damageCoefficient: 0.4
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@
|
|||
heatingCoefficient: 0.01
|
||||
coolingCoefficient: 0.01
|
||||
- type: ClothingSpeedModifier
|
||||
walkModifier: 0.4
|
||||
walkModifier: 0.6
|
||||
sprintModifier: 0.6
|
||||
- type: HeldSpeedModifier
|
||||
- type: Item
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
zombificationResistanceCoefficient: 0.35
|
||||
- type: GroupExamine
|
||||
- type: ClothingSpeedModifier
|
||||
walkModifier: 1
|
||||
walkModifier: 0.95
|
||||
sprintModifier: 0.95
|
||||
# Sunrise-Start
|
||||
- type: Tag
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@
|
|||
Radiation: 0.3 #salv is supposed to have radiation hazards in the future
|
||||
Caustic: 0.8
|
||||
- type: ClothingSpeedModifier
|
||||
walkModifier: 0.9
|
||||
walkModifier: 0.8
|
||||
sprintModifier: 0.8
|
||||
- type: HeldSpeedModifier
|
||||
- type: ToggleableClothing
|
||||
|
|
@ -375,7 +375,7 @@
|
|||
Radiation: 0.0
|
||||
Caustic: 0.7
|
||||
- type: ClothingSpeedModifier
|
||||
walkModifier: 0.75
|
||||
walkModifier: 0.8
|
||||
sprintModifier: 0.8
|
||||
- type: HeldSpeedModifier
|
||||
- type: ToggleableClothing
|
||||
|
|
@ -402,7 +402,7 @@
|
|||
- type: ZombificationResistance
|
||||
zombificationResistanceCoefficient: 0.4
|
||||
- type: ClothingSpeedModifier
|
||||
walkModifier: 0.9
|
||||
walkModifier: 0.95
|
||||
sprintModifier: 0.95
|
||||
- type: HeldSpeedModifier
|
||||
- type: ToggleableClothing
|
||||
|
|
@ -512,7 +512,7 @@
|
|||
Radiation: 0.5
|
||||
Caustic: 0.8
|
||||
- type: ClothingSpeedModifier
|
||||
walkModifier: 0.85
|
||||
walkModifier: 0.9
|
||||
sprintModifier: 0.9
|
||||
- type: HeldSpeedModifier
|
||||
- type: ToggleableClothing
|
||||
|
|
@ -559,6 +559,8 @@
|
|||
- MonkeyWearable
|
||||
- Hardsuit
|
||||
- WhitelistChameleon
|
||||
- type: StaticPrice
|
||||
price: 5000
|
||||
|
||||
# Syndicate Medic Hardsuit
|
||||
- type: entity
|
||||
|
|
@ -613,8 +615,8 @@
|
|||
- type: Item
|
||||
size: Huge
|
||||
- type: ClothingSpeedModifier
|
||||
walkModifier: 1.0
|
||||
sprintModifier: 0.90
|
||||
walkModifier: 0.9
|
||||
sprintModifier: 0.9
|
||||
- type: HeldSpeedModifier
|
||||
- type: ToggleableClothing
|
||||
clothingPrototype: ClothingHeadHelmetHardsuitSyndieElite
|
||||
|
|
@ -681,7 +683,7 @@
|
|||
Radiation: 0.2
|
||||
Caustic: 0.2
|
||||
- type: ClothingSpeedModifier
|
||||
walkModifier: 0.9
|
||||
walkModifier: 0.65
|
||||
sprintModifier: 0.65
|
||||
- type: HeldSpeedModifier
|
||||
- type: ToggleableClothing
|
||||
|
|
|
|||
|
|
@ -8,28 +8,26 @@
|
|||
sprite: Clothing/OuterClothing/Misc/apron.rsi
|
||||
- type: Clothing
|
||||
sprite: Clothing/OuterClothing/Misc/apron.rsi
|
||||
#Sunrise-Start #If merge Scrap Armor PR Delete
|
||||
- type: Tag
|
||||
tags:
|
||||
- Apron
|
||||
#Sunrise-End #If merge Scrap Armor PR Delete
|
||||
- WhitelistChameleon
|
||||
|
||||
- type: entity
|
||||
parent: [ClothingOuterStorageBase, BaseClothingOuterSounds] # Sunrise
|
||||
id: ClothingOuterApronBar
|
||||
name: apron
|
||||
suffix: Bartender
|
||||
name: apron
|
||||
description: A darker apron designed for bartenders.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: Clothing/OuterClothing/Misc/apronbar.rsi
|
||||
- type: Clothing
|
||||
sprite: Clothing/OuterClothing/Misc/apronbar.rsi
|
||||
#Sunrise-Start #If merge Scrap Armor PR Delete
|
||||
- type: Tag
|
||||
tags:
|
||||
- Apron
|
||||
#Sunrise-End #If merge Scrap Armor PR Delete
|
||||
- WhitelistChameleon
|
||||
|
||||
- type: entity
|
||||
parent: [ClothingOuterStorageBase, BaseClothingOuterSounds] # Sunrise
|
||||
|
|
@ -42,11 +40,10 @@
|
|||
sprite: Clothing/OuterClothing/Misc/apronbotanist.rsi
|
||||
- type: Clothing
|
||||
sprite: Clothing/OuterClothing/Misc/apronbotanist.rsi
|
||||
#Sunrise-Start #If merge Scrap Armor PR Delete
|
||||
- type: Tag
|
||||
tags:
|
||||
- Apron
|
||||
#Sunrise-End #If merge Scrap Armor PR Delete
|
||||
- WhitelistChameleon
|
||||
|
||||
- type: entity
|
||||
parent: [ClothingOuterStorageBase, BaseClothingOuterSounds] # Sunrise
|
||||
|
|
@ -59,11 +56,10 @@
|
|||
sprite: Clothing/OuterClothing/Misc/apronchef.rsi
|
||||
- type: Clothing
|
||||
sprite: Clothing/OuterClothing/Misc/apronchef.rsi
|
||||
#Sunrise-Start #If merge Scrap Armor PR Delete
|
||||
- type: Tag
|
||||
tags:
|
||||
- Apron
|
||||
#Sunrise-End #If merge Scrap Armor PR Delete
|
||||
- WhitelistChameleon
|
||||
|
||||
- type: entity
|
||||
parent: [ClothingOuterStorageBase, BaseClothingOuterSounds] # Sunrise
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@
|
|||
|
||||
# The armor itself
|
||||
- type: entity
|
||||
parent: [ClothingOuterArmorHeavy, BaseMajorContraband]
|
||||
parent: [ClothingOuterBaseLarge, AllowSuitStorageClothing, BaseMajorContraband]
|
||||
id: ClothingOuterArmorScrap
|
||||
name: scrap armor
|
||||
description: A tider's gleaming plate mail. Bail up, or you're a dead man.
|
||||
|
|
@ -73,18 +73,13 @@
|
|||
Slash: 0.5
|
||||
Piercing: 0.5 #Some nukie tier physical protection...
|
||||
Heat: 0.8
|
||||
Shock: 1.8 # #Hey, it's a bunch of solid steel. Bzzzzz
|
||||
Radiation: 0.8 #Hey, it's a bunch of solid steel.
|
||||
- type: ExplosionResistance
|
||||
damageCoefficient: 0.80
|
||||
- type: StaminaResistance
|
||||
damageCoefficient: 1.35 # Тяжело в нем явно
|
||||
- type: ClothingSpeedModifier #But that protection comes at a price.
|
||||
walkModifier: 0.7
|
||||
sprintModifier: 0.7
|
||||
walkModifier: 0.6
|
||||
sprintModifier: 0.6
|
||||
- type: GroupExamine
|
||||
- type: ProtectedFromStepTriggers
|
||||
slots: WITHOUT_POCKET
|
||||
- type: Construction
|
||||
graph: scraparmor
|
||||
node: scraparmorfinished
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@
|
|||
- SuitEVA
|
||||
- MonkeyWearable
|
||||
- WhitelistChameleon
|
||||
- type: StaticPrice
|
||||
price: 1000 # Helmet is 500
|
||||
|
||||
#Emergency EVA
|
||||
- type: entity
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@
|
|||
Heat: 0.8
|
||||
Cold: 0.8
|
||||
- type: ClothingSpeedModifier
|
||||
walkModifier: 0.8
|
||||
walkModifier: 0.7
|
||||
sprintModifier: 0.7
|
||||
- type: HeldSpeedModifier
|
||||
- type: GroupExamine
|
||||
|
|
@ -348,3 +348,6 @@
|
|||
coolingCoefficient: 0.01
|
||||
- type: ToggleableClothing
|
||||
clothingPrototype: ClothingHeadHelmetHardsuitCarp
|
||||
- type: StaticPrice
|
||||
price: 1500
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
prefixOn: on
|
||||
- type: Magboots
|
||||
- type: ClothingSpeedModifier
|
||||
walkModifier: 0.85
|
||||
walkModifier: 0.8
|
||||
sprintModifier: 0.8
|
||||
- type: Appearance
|
||||
- type: GenericVisualizer
|
||||
|
|
@ -82,8 +82,8 @@
|
|||
description: These would look fetching on a fetcher like you.
|
||||
components:
|
||||
- type: ClothingSpeedModifier
|
||||
walkModifier: 1.10 #PVS isn't too much of an issue when you are blind...
|
||||
sprintModifier: 1.10
|
||||
walkModifier: 1.1 #PVS isn't too much of an issue when you are blind...
|
||||
sprintModifier: 1.1
|
||||
- type: StaticPrice
|
||||
price: 3000
|
||||
|
||||
|
|
@ -99,7 +99,7 @@
|
|||
- type: Clothing
|
||||
sprite: Clothing/Shoes/Boots/magboots-syndicate.rsi
|
||||
- type: ClothingSpeedModifier
|
||||
walkModifier: 0.95
|
||||
walkModifier: 0.9
|
||||
sprintModifier: 0.9
|
||||
- type: GasTank
|
||||
outputPressure: 42.6
|
||||
|
|
@ -113,6 +113,8 @@
|
|||
- type: Item
|
||||
sprite: null
|
||||
size: Normal
|
||||
- type: StaticPrice
|
||||
price: 1500
|
||||
|
||||
- type: entity
|
||||
parent: BaseAction
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@
|
|||
- type: Magboots # always have gravity because le suction cups
|
||||
- type: ClothingSpeedModifier
|
||||
# ninja are masters of sneaking around relatively quickly, won't break cloak
|
||||
walkModifier: 1.1
|
||||
walkModifier: 1.3
|
||||
sprintModifier: 1.3
|
||||
- type: FootstepModifier
|
||||
footstepSoundCollection: null
|
||||
|
|
@ -272,7 +272,7 @@
|
|||
size: Small
|
||||
sprite: Clothing/Shoes/Specific/large_clown.rsi
|
||||
- type: ClothingSpeedModifier
|
||||
walkModifier: 0.85
|
||||
walkModifier: 0.8
|
||||
sprintModifier: 0.8
|
||||
|
||||
- type: entity
|
||||
|
|
|
|||
|
|
@ -521,6 +521,8 @@
|
|||
sprite: Clothing/Uniforms/Jumpskirt/operative_s.rsi
|
||||
- type: Clothing
|
||||
sprite: Clothing/Uniforms/Jumpskirt/operative_s.rsi
|
||||
- type: StaticPrice
|
||||
price: 500
|
||||
|
||||
- type: entity
|
||||
parent: ClothingUniformSkirtBase
|
||||
|
|
|
|||
|
|
@ -855,6 +855,8 @@
|
|||
sprite: Clothing/Uniforms/Jumpsuit/operative.rsi
|
||||
- type: Clothing
|
||||
sprite: Clothing/Uniforms/Jumpsuit/operative.rsi
|
||||
- type: StaticPrice
|
||||
price: 500
|
||||
|
||||
- type: entity
|
||||
parent: ClothingUniformBase
|
||||
|
|
|
|||
|
|
@ -181,8 +181,6 @@
|
|||
rules: ghost-role-information-space-dragon-summoned-carp-rules
|
||||
mindRoles:
|
||||
- MindRoleGhostRoleTeamAntagonistFlock
|
||||
raffle:
|
||||
settings: short
|
||||
- type: GhostTakeoverAvailable
|
||||
- type: HTN
|
||||
rootTask:
|
||||
|
|
|
|||
|
|
@ -96,6 +96,8 @@
|
|||
- type: Sprite
|
||||
layers:
|
||||
- state: margherita-slice
|
||||
- type: Item
|
||||
heldPrefix: margherita-slice
|
||||
|
||||
- type: entity
|
||||
name: meat pizza
|
||||
|
|
@ -134,6 +136,8 @@
|
|||
- type: Sprite
|
||||
layers:
|
||||
- state: meat-slice
|
||||
- type: Item
|
||||
heldPrefix: meat-slice
|
||||
- type: Tag
|
||||
tags:
|
||||
- Meat
|
||||
|
|
@ -172,6 +176,8 @@
|
|||
- type: Sprite
|
||||
layers:
|
||||
- state: mushroom-slice
|
||||
- type: Item
|
||||
heldPrefix: mushroom-slice
|
||||
# Tastes like crust, tomato, cheese, mushroom.
|
||||
|
||||
- type: entity
|
||||
|
|
@ -223,6 +229,8 @@
|
|||
- type: Sprite
|
||||
layers:
|
||||
- state: vegetable-slice
|
||||
- type: Item
|
||||
heldPrefix: vegetable-slice
|
||||
- type: SolutionContainerManager
|
||||
solutions:
|
||||
food:
|
||||
|
|
@ -280,6 +288,8 @@
|
|||
- type: Sprite
|
||||
layers:
|
||||
- state: donkpocket-slice
|
||||
- type: Item
|
||||
heldPrefix: donkpocket-slice
|
||||
- type: SolutionContainerManager
|
||||
solutions:
|
||||
food:
|
||||
|
|
@ -340,6 +350,8 @@
|
|||
- type: Sprite
|
||||
layers:
|
||||
- state: dank-slice
|
||||
- type: Item
|
||||
heldPrefix: dank-slice
|
||||
- type: SolutionContainerManager
|
||||
solutions:
|
||||
food:
|
||||
|
|
@ -388,6 +400,8 @@
|
|||
- type: Sprite
|
||||
layers:
|
||||
- state: sassysage-slice
|
||||
- type: Item
|
||||
heldPrefix: sassysage-slice
|
||||
- type: Tag
|
||||
tags:
|
||||
- Meat
|
||||
|
|
@ -434,6 +448,8 @@
|
|||
- type: Sprite
|
||||
layers:
|
||||
- state: pineapple-slice
|
||||
- type: Item
|
||||
heldPrefix: pineapple-slice
|
||||
- type: Tag
|
||||
tags:
|
||||
- Meat
|
||||
|
|
@ -494,6 +510,8 @@
|
|||
- type: Sprite
|
||||
layers:
|
||||
- state: arnold-slice
|
||||
- type: Item
|
||||
heldPrefix: arnold-slice
|
||||
- type: SolutionContainerManager
|
||||
solutions:
|
||||
food:
|
||||
|
|
@ -529,6 +547,8 @@
|
|||
- type: Sprite
|
||||
layers:
|
||||
- state: moldy-slice
|
||||
- type: Item
|
||||
heldPrefix: moldy-slice
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
|
|
@ -597,6 +617,8 @@
|
|||
- type: Sprite
|
||||
layers:
|
||||
- state: uranium-slice
|
||||
- type: Item
|
||||
heldPrefix: uranium-slice
|
||||
- type: Tag
|
||||
tags:
|
||||
- Meat
|
||||
|
|
@ -665,6 +687,8 @@
|
|||
- type: Sprite
|
||||
layers:
|
||||
- state: cotton-slice
|
||||
- type: Item
|
||||
heldPrefix: cotton-slice
|
||||
- type: Tag
|
||||
tags:
|
||||
- ClothMade
|
||||
|
|
@ -722,6 +746,8 @@
|
|||
- type: Sprite
|
||||
layers:
|
||||
- state: worldpeas-slice
|
||||
- type: Item
|
||||
heldPrefix: worldpeas-slice
|
||||
- type: SolutionContainerManager
|
||||
solutions:
|
||||
food:
|
||||
|
|
|
|||
|
|
@ -19,6 +19,11 @@
|
|||
shape:
|
||||
- 0,0,1,0
|
||||
storedOffset: 0,-6
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: plate-inhand-left
|
||||
right:
|
||||
- state: plate-inhand-right
|
||||
- type: DamageOnLand
|
||||
damage:
|
||||
types:
|
||||
|
|
@ -86,6 +91,11 @@
|
|||
state: plate-small
|
||||
- type: Item
|
||||
storedOffset: 0,-3
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: plate-inhand-left
|
||||
right:
|
||||
- state: plate-inhand-right
|
||||
# Needs the full thing because inherting is dumb sometimes.
|
||||
- type: Destructible
|
||||
thresholds:
|
||||
|
|
@ -145,6 +155,11 @@
|
|||
shape:
|
||||
- 0,0,1,0
|
||||
storedOffset: 0,-6
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: plate-plastic-inhand-left
|
||||
right:
|
||||
- state: plate-plastic-inhand-right
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
|
|
@ -162,6 +177,11 @@
|
|||
shape:
|
||||
- 0,0,1,0
|
||||
storedOffset: 0,-3
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: plate-plastic-inhand-left
|
||||
right:
|
||||
- state: plate-plastic-inhand-right
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
|
|
|
|||
|
|
@ -720,6 +720,12 @@
|
|||
entries:
|
||||
Taco: CheeseTaco
|
||||
Burger: CheeseBurger
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: cheesewedge-inhand-left
|
||||
right:
|
||||
- state: cheesewedge-inhand-right
|
||||
|
||||
- type: entity
|
||||
name: chèvre log
|
||||
|
|
|
|||
|
|
@ -109,6 +109,12 @@
|
|||
- type: Tag
|
||||
tags:
|
||||
- Meat
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: plain-inhand-left
|
||||
right:
|
||||
- state: plain-inhand-right
|
||||
|
||||
- type: entity
|
||||
name: raw human meat
|
||||
|
|
@ -127,6 +133,12 @@
|
|||
- type: SliceableFood
|
||||
count: 3
|
||||
slice: FoodMeatCutlet
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: plain-inhand-left
|
||||
right:
|
||||
- state: plain-inhand-right
|
||||
|
||||
- type: entity
|
||||
name: raw carp fillet
|
||||
|
|
@ -155,6 +167,12 @@
|
|||
reagents:
|
||||
- ReagentId: CarpoToxin
|
||||
Quantity: 5
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: generic-pink-inhand-left
|
||||
right:
|
||||
- state: generic-pink-inhand-right
|
||||
|
||||
- type: entity
|
||||
name: raw bacon
|
||||
|
|
@ -185,6 +203,12 @@
|
|||
graph: Bacon
|
||||
node: start
|
||||
defaultTarget: bacon
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: generic-pink-inhand-left
|
||||
right:
|
||||
- state: generic-pink-inhand-right
|
||||
|
||||
- type: entity
|
||||
name: raw bear meat
|
||||
|
|
@ -209,6 +233,14 @@
|
|||
graph: BearSteak
|
||||
node: start
|
||||
defaultTarget: filet migrawr
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: generic-pink-inhand-left
|
||||
color: "#934C64"
|
||||
right:
|
||||
- state: generic-pink-inhand-right
|
||||
color: "#934C64"
|
||||
|
||||
- type: entity
|
||||
name: raw penguin meat
|
||||
|
|
@ -233,6 +265,12 @@
|
|||
graph: PenguinSteak
|
||||
node: start
|
||||
defaultTarget: cooked penguin
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: generic-pink-inhand-left
|
||||
right:
|
||||
- state: generic-pink-inhand-right
|
||||
|
||||
- type: entity
|
||||
name: raw chicken meat
|
||||
|
|
@ -259,6 +297,12 @@
|
|||
graph: ChickenSteak
|
||||
node: start
|
||||
defaultTarget: cooked chicken
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: generic-pink-inhand-left
|
||||
right:
|
||||
- state: generic-pink-inhand-right
|
||||
|
||||
- type: entity
|
||||
name: raw duck meat
|
||||
|
|
@ -283,6 +327,12 @@
|
|||
graph: DuckSteak
|
||||
node: start
|
||||
defaultTarget: cooked duck
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: generic-pink-inhand-left
|
||||
right:
|
||||
- state: generic-pink-inhand-right
|
||||
|
||||
- type: entity
|
||||
name: prime-cut corgi meat
|
||||
|
|
@ -308,6 +358,12 @@
|
|||
price: 750
|
||||
- type: StealTarget
|
||||
stealGroup: FoodMeatCorgi
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: corgi-inhand-left
|
||||
right:
|
||||
- state: corgi-inhand-right
|
||||
|
||||
- type: entity
|
||||
name: raw crab meat
|
||||
|
|
@ -355,6 +411,12 @@
|
|||
graph: GoliathSteak
|
||||
node: start
|
||||
defaultTarget: goliath steak
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: plain-inhand-left
|
||||
right:
|
||||
- state: plain-inhand-right
|
||||
|
||||
- type: entity
|
||||
name: dragon flesh
|
||||
|
|
@ -389,6 +451,12 @@
|
|||
graph: DragonSteak
|
||||
node: start
|
||||
defaultTarget: dragon steak
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: dragon-inhand-left
|
||||
right:
|
||||
- state: dragon-inhand-right
|
||||
|
||||
- type: entity
|
||||
name: raw rat meat
|
||||
|
|
@ -409,6 +477,12 @@
|
|||
- type: SliceableFood
|
||||
count: 3
|
||||
slice: FoodMeatCutlet
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: plain-inhand-left
|
||||
right:
|
||||
- state: plain-inhand-right
|
||||
|
||||
- type: entity
|
||||
name: raw lizard meat
|
||||
|
|
@ -433,6 +507,14 @@
|
|||
graph: LizardSteak
|
||||
node: start
|
||||
defaultTarget: lizard steak
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: plain-inhand-left
|
||||
color: "#6EFF41"
|
||||
right:
|
||||
- state: plain-inhand-right
|
||||
color: "#6EFF41"
|
||||
|
||||
- type: entity
|
||||
name: raw plant meat
|
||||
|
|
@ -467,6 +549,12 @@
|
|||
Quantity: 4
|
||||
- ReagentId: Fat
|
||||
Quantity: 4
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: rotten-inhand-left
|
||||
right:
|
||||
- state: rotten-inhand-right
|
||||
|
||||
- type: entity
|
||||
name: raw spider meat
|
||||
|
|
@ -487,6 +575,8 @@
|
|||
- type: SliceableFood
|
||||
count: 3
|
||||
slice: FoodMeatSpiderCutlet
|
||||
- type: Item
|
||||
heldPrefix: spider
|
||||
|
||||
- type: entity
|
||||
name: raw spider leg
|
||||
|
|
@ -504,6 +594,14 @@
|
|||
Quantity: 10
|
||||
- ReagentId: Fat
|
||||
Quantity: 3
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: snake-inhand-left
|
||||
color: "#333333"
|
||||
right:
|
||||
- state: snake-inhand-right
|
||||
color: "#333333"
|
||||
|
||||
- type: entity
|
||||
name: meatwheat clump
|
||||
|
|
@ -522,6 +620,14 @@
|
|||
reagents:
|
||||
- ReagentId: UncookedAnimalProteins
|
||||
Quantity: 1
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: generic-pink-inhand-left
|
||||
color: "#934C64"
|
||||
right:
|
||||
- state: generic-pink-inhand-right
|
||||
color: "#934C64"
|
||||
|
||||
- type: entity
|
||||
name: raw snake meat
|
||||
|
|
@ -543,6 +649,12 @@
|
|||
Quantity: 10
|
||||
- ReagentId: Toxin
|
||||
Quantity: 2
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: snake-inhand-left
|
||||
right:
|
||||
- state: snake-inhand-right
|
||||
|
||||
- type: entity
|
||||
name: raw xeno meat
|
||||
|
|
@ -570,6 +682,14 @@
|
|||
- type: SliceableFood
|
||||
count: 3
|
||||
slice: FoodMeatXenoCutlet
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: plain-inhand-left
|
||||
color: "#6EFF41"
|
||||
right:
|
||||
- state: plain-inhand-right
|
||||
color: "#6EFF41"
|
||||
|
||||
- type: entity
|
||||
name: raw rouny meat
|
||||
|
|
@ -599,6 +719,12 @@
|
|||
graph: RounySteak
|
||||
node: start
|
||||
defaultTarget: rouny steak
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: plain-inhand-left
|
||||
right:
|
||||
- state: plain-inhand-right
|
||||
|
||||
- type: entity
|
||||
name: killer tomato meat
|
||||
|
|
@ -613,6 +739,12 @@
|
|||
slice: FoodMeatTomatoCutlet
|
||||
- type: StaticPrice
|
||||
price: 100
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: tomato-inhand-left
|
||||
right:
|
||||
- state: tomato-inhand-right
|
||||
|
||||
- type: entity
|
||||
name: salami
|
||||
|
|
@ -695,6 +827,8 @@
|
|||
graph: CookedPatty
|
||||
node: start
|
||||
defaultTarget: cooked meat patty
|
||||
- type: Item
|
||||
heldPrefix: generic-pink
|
||||
|
||||
- type: entity
|
||||
name: slimeball
|
||||
|
|
@ -716,6 +850,12 @@
|
|||
Quantity: 10
|
||||
- type: Sprite
|
||||
state: slime
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: slime-inhand-left
|
||||
right:
|
||||
- state: slime-inhand-right
|
||||
|
||||
- type: entity
|
||||
name: raw snail meat
|
||||
|
|
@ -736,6 +876,14 @@
|
|||
Quantity: 3
|
||||
- ReagentId: Water
|
||||
Quantity: 4 #It makes saline if you add salt!
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: generic-pink-inhand-left
|
||||
color: "#E2AE7C"
|
||||
right:
|
||||
- state: generic-pink-inhand-right
|
||||
color: "#E2AE7C"
|
||||
|
||||
- type: entity
|
||||
name: anomalous meat mass
|
||||
|
|
@ -766,6 +914,12 @@
|
|||
- type: Tag
|
||||
tags:
|
||||
- Meat
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: plain-inhand-left
|
||||
right:
|
||||
- state: plain-inhand-right
|
||||
|
||||
# Cooked
|
||||
|
||||
|
|
@ -833,6 +987,12 @@
|
|||
entries:
|
||||
Burger: MeatSteak
|
||||
Taco: MeatSteak
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: plain-cooked-inhand-left
|
||||
right:
|
||||
- state: plain-cooked-inhand-right
|
||||
|
||||
- type: entity
|
||||
name: bacon
|
||||
|
|
@ -868,6 +1028,14 @@
|
|||
entries:
|
||||
Burger: MeatBacon
|
||||
Taco: MeatBacon
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: generic-pink-inhand-left
|
||||
color: "#5B3E2A"
|
||||
right:
|
||||
- state: generic-pink-inhand-right
|
||||
color: "#5B3E2A"
|
||||
|
||||
- type: entity
|
||||
name: cooked bear
|
||||
|
|
@ -901,6 +1069,8 @@
|
|||
entries:
|
||||
Burger: MeatBearBurger
|
||||
Taco: MeatBear
|
||||
- type: Item
|
||||
heldPrefix: meatball
|
||||
|
||||
- type: entity
|
||||
name: penguin filet
|
||||
|
|
@ -933,6 +1103,14 @@
|
|||
entries:
|
||||
Burger: MeatPenguinBurger
|
||||
Taco: MeatPenguin
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: plain-cooked-inhand-left
|
||||
color: "#F7E3A3"
|
||||
right:
|
||||
- state: plain-cooked-inhand-right
|
||||
color: "#F7E3A3"
|
||||
|
||||
- type: entity
|
||||
name: cooked chicken
|
||||
|
|
@ -965,6 +1143,14 @@
|
|||
entries:
|
||||
Burger: MeatChicken
|
||||
Taco: MeatChicken
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: plain-cooked-inhand-left
|
||||
color: "#F7E3A3"
|
||||
right:
|
||||
- state: plain-cooked-inhand-right
|
||||
color: "#F7E3A3"
|
||||
|
||||
- type: entity
|
||||
name: fried chicken
|
||||
|
|
@ -997,6 +1183,14 @@
|
|||
entries:
|
||||
Burger: MeatChicken
|
||||
Taco: MeatChicken
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: plain-cooked-inhand-left
|
||||
color: "#F7E3A3"
|
||||
right:
|
||||
- state: plain-cooked-inhand-right
|
||||
color: "#F7E3A3"
|
||||
|
||||
- type: entity
|
||||
name: cooked duck
|
||||
|
|
@ -1029,6 +1223,14 @@
|
|||
entries:
|
||||
Burger: MeatDuck
|
||||
Taco: MeatDuck
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: plain-cooked-inhand-left
|
||||
color: "#F7E3A3"
|
||||
right:
|
||||
- state: plain-cooked-inhand-right
|
||||
color: "#F7E3A3"
|
||||
|
||||
- type: entity
|
||||
name: cooked crab
|
||||
|
|
@ -1061,6 +1263,12 @@
|
|||
entries:
|
||||
Burger: MeatCrabBurger
|
||||
Taco: MeatCrab
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: plain-cooked-inhand-left
|
||||
right:
|
||||
- state: plain-cooked-inhand-right
|
||||
|
||||
- type: entity
|
||||
name: goliath steak
|
||||
|
|
@ -1091,6 +1299,12 @@
|
|||
entries:
|
||||
Burger: MeatGoliathBurger
|
||||
Taco: MeatGoliath
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: plain-cooked-inhand-left
|
||||
right:
|
||||
- state: plain-cooked-inhand-right
|
||||
|
||||
- type: entity
|
||||
name: rouny steak
|
||||
|
|
@ -1125,6 +1339,12 @@
|
|||
entries:
|
||||
Burger: MeatXeno
|
||||
Taco: MeatXeno
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: plain-cooked-inhand-left
|
||||
right:
|
||||
- state: plain-cooked-inhand-right
|
||||
|
||||
- type: entity
|
||||
name: lizard steak
|
||||
|
|
@ -1158,6 +1378,12 @@
|
|||
entries:
|
||||
Burger: MeatLizardBurger
|
||||
Taco: MeatLizard
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: plain-cooked-inhand-left
|
||||
right:
|
||||
- state: plain-cooked-inhand-right
|
||||
|
||||
- type: entity
|
||||
name: boiled spider leg
|
||||
|
|
@ -1184,6 +1410,14 @@
|
|||
entries:
|
||||
Burger: MeatSpiderBurger
|
||||
Taco: MeatSpider
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: snake-inhand-left
|
||||
color: "#44201A"
|
||||
right:
|
||||
- state: snake-inhand-right
|
||||
color: "#44201A"
|
||||
|
||||
- type: entity
|
||||
name: meatball
|
||||
|
|
@ -1212,6 +1446,8 @@
|
|||
- type: Construction
|
||||
graph: MeatMeatballCooked
|
||||
node: meatball cooked
|
||||
- type: Item
|
||||
heldPrefix: meatball
|
||||
|
||||
- type: entity
|
||||
name: cooked meat patty
|
||||
|
|
@ -1241,6 +1477,8 @@
|
|||
entries:
|
||||
Burger: MeatPatty
|
||||
Taco: MeatPatty
|
||||
- type: Item
|
||||
heldPrefix: meatball
|
||||
|
||||
- type: entity
|
||||
name: boiled snail
|
||||
|
|
@ -1270,6 +1508,14 @@
|
|||
entries:
|
||||
Burger: MeatSnail
|
||||
Taco: MeatSnail
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: generic-pink-inhand-left
|
||||
color: "#5B3E2A"
|
||||
right:
|
||||
- state: generic-pink-inhand-right
|
||||
color: "#5B3E2A"
|
||||
|
||||
- type: entity
|
||||
name: anomalous steak
|
||||
|
|
@ -1299,6 +1545,12 @@
|
|||
- type: Construction
|
||||
graph: AnomalyMeatSteak
|
||||
node: anomaly steak
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: plain-cooked-inhand-left
|
||||
right:
|
||||
- state: plain-cooked-inhand-right
|
||||
|
||||
- type: entity
|
||||
name: dragon steak
|
||||
|
|
@ -1334,6 +1586,12 @@
|
|||
entries:
|
||||
Burger: DragonSteak
|
||||
Taco: DragonSteak
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: dragon-cooked-inhand-left
|
||||
right:
|
||||
- state: dragon-cooked-inhand-right
|
||||
|
||||
# Cutlets
|
||||
|
||||
|
|
@ -1364,6 +1622,12 @@
|
|||
graph: Cutlet
|
||||
node: start
|
||||
defaultTarget: cutlet
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: generic-pink-inhand-left
|
||||
right:
|
||||
- state: generic-pink-inhand-right
|
||||
|
||||
- type: entity
|
||||
name: raw bear cutlet
|
||||
|
|
@ -1393,6 +1657,14 @@
|
|||
graph: BearCutlet
|
||||
node: start
|
||||
defaultTarget: bear cutlet
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: generic-pink-inhand-left
|
||||
color: brown
|
||||
right:
|
||||
- state: generic-pink-inhand-right
|
||||
color: brown
|
||||
|
||||
- type: entity
|
||||
name: raw penguin cutlet
|
||||
|
|
@ -1420,6 +1692,14 @@
|
|||
graph: PenguinCutlet
|
||||
node: start
|
||||
defaultTarget: penguin cutlet
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: generic-pink-inhand-left
|
||||
color: white
|
||||
right:
|
||||
- state: generic-pink-inhand-right
|
||||
color: white
|
||||
|
||||
- type: entity
|
||||
name: raw chicken cutlet
|
||||
|
|
@ -1447,6 +1727,12 @@
|
|||
graph: ChickenCutlet
|
||||
node: start
|
||||
defaultTarget: chicken cutlet
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: generic-pink-inhand-left
|
||||
right:
|
||||
- state: generic-pink-inhand-right
|
||||
|
||||
- type: entity
|
||||
name: raw duck cutlet
|
||||
|
|
@ -1474,6 +1760,12 @@
|
|||
graph: DuckCutlet
|
||||
node: start
|
||||
defaultTarget: duck cutlet
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: generic-pink-inhand-left
|
||||
right:
|
||||
- state: generic-pink-inhand-right
|
||||
|
||||
- type: entity
|
||||
name: raw lizard cutlet
|
||||
|
|
@ -1504,6 +1796,14 @@
|
|||
graph: LizardCutlet
|
||||
node: start
|
||||
defaultTarget: lizard cutlet
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: generic-pink-inhand-left
|
||||
color: green
|
||||
right:
|
||||
- state: generic-pink-inhand-right
|
||||
color: green
|
||||
|
||||
- type: entity
|
||||
name: raw spider cutlet
|
||||
|
|
@ -1530,6 +1830,14 @@
|
|||
graph: SpiderCutlet
|
||||
node: start
|
||||
defaultTarget: spider cutlet
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: generic-pink-inhand-left
|
||||
color: green
|
||||
right:
|
||||
- state: generic-pink-inhand-right
|
||||
color: green
|
||||
|
||||
- type: entity
|
||||
name: raw xeno cutlet
|
||||
|
|
@ -1558,6 +1866,14 @@
|
|||
graph: XenoCutlet
|
||||
node: start
|
||||
defaultTarget: xeno cutlet
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: generic-pink-inhand-left
|
||||
color: green
|
||||
right:
|
||||
- state: generic-pink-inhand-right
|
||||
color: green
|
||||
|
||||
- type: entity
|
||||
name: raw killer tomato cutlet
|
||||
|
|
@ -1623,6 +1939,14 @@
|
|||
graph: DragonCutlet
|
||||
node: start
|
||||
defaultTarget: dragon cutlet
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: generic-pink-inhand-left
|
||||
color: "#D127A7"
|
||||
right:
|
||||
- state: generic-pink-inhand-right
|
||||
color: "#D127A7"
|
||||
|
||||
# Cooked
|
||||
|
||||
|
|
@ -1654,6 +1978,14 @@
|
|||
entries:
|
||||
Burger: MeatCutlet
|
||||
Taco: MeatCutlet
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: generic-pink-inhand-left
|
||||
color: "#5B3614"
|
||||
right:
|
||||
- state: generic-pink-inhand-right
|
||||
color: "#5B3614"
|
||||
|
||||
- type: entity
|
||||
name: bear cutlet
|
||||
|
|
@ -1686,6 +2018,14 @@
|
|||
entries:
|
||||
Burger: BearCutletBurger
|
||||
Taco: BearCutlet
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: generic-pink-inhand-left
|
||||
color: "#5B3614"
|
||||
right:
|
||||
- state: generic-pink-inhand-right
|
||||
color: "#5B3614"
|
||||
|
||||
- type: entity
|
||||
name: penguin cutlet
|
||||
|
|
@ -1716,6 +2056,14 @@
|
|||
entries:
|
||||
Burger: PenguinCutletBurger
|
||||
Taco: PenguinCutlet
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: generic-pink-inhand-left
|
||||
color: "#5B3614"
|
||||
right:
|
||||
- state: generic-pink-inhand-right
|
||||
color: "#5B3614"
|
||||
|
||||
- type: entity
|
||||
name: chicken cutlet
|
||||
|
|
@ -1746,6 +2094,14 @@
|
|||
entries:
|
||||
Burger: ChickenCutlet
|
||||
Taco: ChickenCutlet
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: generic-pink-inhand-left
|
||||
color: "#5B3614"
|
||||
right:
|
||||
- state: generic-pink-inhand-right
|
||||
color: "#5B3614"
|
||||
|
||||
- type: entity
|
||||
name: duck cutlet
|
||||
|
|
@ -1776,6 +2132,14 @@
|
|||
entries:
|
||||
Burger: DuckCutlet
|
||||
Taco: DuckCutlet
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: generic-pink-inhand-left
|
||||
color: "#5B3614"
|
||||
right:
|
||||
- state: generic-pink-inhand-right
|
||||
color: "#5B3614"
|
||||
|
||||
- type: entity
|
||||
name: lizard cutlet
|
||||
|
|
@ -1807,6 +2171,14 @@
|
|||
entries:
|
||||
Burger: LizardCutletBurger
|
||||
Taco: LizardCutlet
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: generic-pink-inhand-left
|
||||
color: "#153F06"
|
||||
right:
|
||||
- state: generic-pink-inhand-right
|
||||
color: "#153F06"
|
||||
|
||||
- type: entity
|
||||
name: spider cutlet
|
||||
|
|
@ -1836,6 +2208,14 @@
|
|||
entries:
|
||||
Burger: SpiderCutletBurger
|
||||
Taco: SpiderCutlet
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: generic-pink-inhand-left
|
||||
color: "#153F06"
|
||||
right:
|
||||
- state: generic-pink-inhand-right
|
||||
color: "#153F06"
|
||||
|
||||
- type: entity
|
||||
name: xeno cutlet
|
||||
|
|
@ -1865,6 +2245,14 @@
|
|||
entries:
|
||||
Burger: XenoCutlet
|
||||
Taco: XenoCutlet
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: generic-pink-inhand-left
|
||||
color: "#153F06"
|
||||
right:
|
||||
- state: generic-pink-inhand-right
|
||||
color: "#153F06"
|
||||
|
||||
- type: entity
|
||||
name: dragon cutlet
|
||||
|
|
@ -1896,3 +2284,11 @@
|
|||
entries:
|
||||
Burger: DragonCutlet
|
||||
Taco: DragonCutlet
|
||||
- type: Item
|
||||
inhandVisuals:
|
||||
left:
|
||||
- state: generic-pink-inhand-left
|
||||
color: "#7A1763"
|
||||
right:
|
||||
- state: generic-pink-inhand-right
|
||||
color: "#7A1763"
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue