From ca4172c987957710419972ae6ed3338c5a23eed8 Mon Sep 17 00:00:00 2001 From: Ed <96445749+TheShuEd@users.noreply.github.com> Date: Tue, 2 Apr 2024 20:59:40 +0300 Subject: [PATCH 1/7] =?UTF-8?q?=D0=A1=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D0=B0?= =?UTF-8?q?=20=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=B9=20(#7)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * new Dev map * добавлена генерация узора ключей раундстартом * каменная стена подгон KREKSa фиксы * add verbs to lock comp * more Loc work * some popups, logic to lock and unlock locks * return old Dev * ability to add locks into doors * check to locked lock, to insert or remove locks * doors examine * key can uses directly to door * really lockable! * lockable crates! * Bruh... Really big update * Key sprites, long wall template * KeyRingComponent * lock entity start * lockpicking! * Shiny 1 * Update keys.yml * Отображение только для держащего в руке * Final --------- Co-authored-by: Tornado Tech <54727692+Tornado-Technology@users.noreply.github.com> --- .../LockKey/KeyholeGenerationSystem.cs | 136 +++++++ .../StationBiomeComponent.cs | 2 +- .../StationBiomeSystem.cs | 2 +- .../EntitySystems/EntityStorageSystem.cs | 3 +- .../LockKey/CPLockCategoryPrototype.cs | 19 + .../LockKey/Components/CPKeyComponent.cs | 19 + .../LockKey/Components/CPKeyRingComponent.cs | 9 + .../LockKey/Components/CPLockComponent.cs | 37 ++ .../LockKey/Components/CPLockpickComponent.cs | 32 ++ .../LockKey/SharedCPLockKeySystem.cs | 334 ++++++++++++++++++ Content.Shared/Lock/LockComponent.cs | 8 +- Content.Shared/Lock/LockSystem.cs | 85 +++-- Content.Shared/Verbs/VerbCategory.cs | 3 + Resources/Audio/_CP14/Items/attributions.yml | 14 + Resources/Audio/_CP14/Items/key_drop.ogg | Bin 0 -> 14874 bytes Resources/Audio/_CP14/Items/lockpick_fail.ogg | Bin 0 -> 9735 bytes Resources/Audio/_CP14/Items/lockpick_use.ogg | Bin 0 -> 30898 bytes .../Locale/ru-RU/lock/lock-component.ftl | 9 + .../Locale/ru-RU/lock/lock-crystall-punk.ftl | 29 ++ Resources/Maps/CrystallPunk/dev_map.yml | 14 +- .../Entities/Markers/Spawners/jobs.yml | 0 .../Structures/Doors/wooden_doors.yml | 67 ++++ .../Entities/Structures/Furniture/chairs.yml | 0 .../Entities/Structures/Furniture/tables.yml | 0 .../Entities/Structures/Walls/walls.yml | 14 + .../Prototypes/_CP14/Entities/keyrings.yml | 41 +++ Resources/Prototypes/_CP14/Entities/keys.yml | 42 +++ Resources/Prototypes/_CP14/Entities/locks.yml | 22 ++ .../_CP14/LockCategories/LockCategory.yml | 7 + .../Roles/Jobs/Mercenary/adventurer.yml | 0 .../Roles/Jobs/departments.yml | 0 .../Roles/play_time_tracker.yml | 0 .../{CrystallPunk => _CP14}/Tiles/natural.yml | 0 Resources/Prototypes/_CP14/tags.yml | 2 + .../CrystallPunk/Objects/keys.rsi/base.png | Bin 272 -> 0 bytes .../CrystallPunk/Objects/keys.rsi/key1.png | Bin 0 -> 259 bytes .../CrystallPunk/Objects/keys.rsi/key10.png | Bin 0 -> 248 bytes .../CrystallPunk/Objects/keys.rsi/key11.png | Bin 0 -> 236 bytes .../CrystallPunk/Objects/keys.rsi/key12.png | Bin 0 -> 235 bytes .../CrystallPunk/Objects/keys.rsi/key13.png | Bin 0 -> 276 bytes .../CrystallPunk/Objects/keys.rsi/key14.png | Bin 0 -> 247 bytes .../CrystallPunk/Objects/keys.rsi/key15.png | Bin 0 -> 251 bytes .../CrystallPunk/Objects/keys.rsi/key16.png | Bin 0 -> 245 bytes .../CrystallPunk/Objects/keys.rsi/key17.png | Bin 0 -> 230 bytes .../CrystallPunk/Objects/keys.rsi/key18.png | Bin 0 -> 261 bytes .../CrystallPunk/Objects/keys.rsi/key2.png | Bin 0 -> 260 bytes .../CrystallPunk/Objects/keys.rsi/key3.png | Bin 0 -> 257 bytes .../CrystallPunk/Objects/keys.rsi/key4.png | Bin 0 -> 263 bytes .../CrystallPunk/Objects/keys.rsi/key5.png | Bin 0 -> 257 bytes .../CrystallPunk/Objects/keys.rsi/key6.png | Bin 0 -> 247 bytes .../CrystallPunk/Objects/keys.rsi/key7.png | Bin 0 -> 254 bytes .../CrystallPunk/Objects/keys.rsi/key8.png | Bin 0 -> 235 bytes .../CrystallPunk/Objects/keys.rsi/key9.png | Bin 0 -> 249 bytes .../CrystallPunk/Objects/keys.rsi/keyring.png | Bin 0 -> 225 bytes .../CrystallPunk/Objects/keys.rsi/lock.png | Bin 0 -> 332 bytes .../Objects/keys.rsi/lockpick.png | Bin 0 -> 255 bytes .../CrystallPunk/Objects/keys.rsi/meta.json | 74 +++- .../CrystallPunk/Objects/keys.rsi/ring-0.png | Bin 0 -> 96 bytes .../CrystallPunk/Objects/keys.rsi/ring-1.png | Bin 0 -> 167 bytes .../CrystallPunk/Objects/keys.rsi/ring-2.png | Bin 0 -> 223 bytes .../CrystallPunk/Objects/keys.rsi/ring-3.png | Bin 0 -> 261 bytes .../Walls/TEMPLATE_LONG.rsi/full.png | Bin 0 -> 213 bytes .../Walls/TEMPLATE_LONG.rsi/meta.json | 46 +++ .../Walls/TEMPLATE_LONG.rsi/wood0.png | Bin 0 -> 457 bytes .../Walls/TEMPLATE_LONG.rsi/wood1.png | Bin 0 -> 415 bytes .../Walls/TEMPLATE_LONG.rsi/wood2.png | Bin 0 -> 457 bytes .../Walls/TEMPLATE_LONG.rsi/wood3.png | Bin 0 -> 415 bytes .../Walls/TEMPLATE_LONG.rsi/wood4.png | Bin 0 -> 417 bytes .../Walls/TEMPLATE_LONG.rsi/wood5.png | Bin 0 -> 420 bytes .../Walls/TEMPLATE_LONG.rsi/wood6.png | Bin 0 -> 417 bytes .../Walls/TEMPLATE_LONG.rsi/wood7.png | Bin 0 -> 317 bytes .../Structures/Walls/cave_stone.rsi/full.png | Bin 0 -> 1039 bytes .../Structures/Walls/cave_stone.rsi/meta.json | 46 +++ .../Walls/cave_stone.rsi/stone0.png | Bin 0 -> 1360 bytes .../Walls/cave_stone.rsi/stone1.png | Bin 0 -> 1252 bytes .../Walls/cave_stone.rsi/stone2.png | Bin 0 -> 1360 bytes .../Walls/cave_stone.rsi/stone3.png | Bin 0 -> 1252 bytes .../Walls/cave_stone.rsi/stone4.png | Bin 0 -> 1176 bytes .../Walls/cave_stone.rsi/stone5.png | Bin 0 -> 927 bytes .../Walls/cave_stone.rsi/stone6.png | Bin 0 -> 1176 bytes .../Walls/cave_stone.rsi/stone7.png | Bin 0 -> 265 bytes 81 files changed, 1077 insertions(+), 39 deletions(-) create mode 100644 Content.Server/CrystallPunk/LockKey/KeyholeGenerationSystem.cs rename Content.Server/CrystallPunk/{SpawnMapBiome => StationBiome}/StationBiomeComponent.cs (88%) rename Content.Server/CrystallPunk/{SpawnMapBiome => StationBiome}/StationBiomeSystem.cs (95%) create mode 100644 Content.Shared/CrystallPunk/LockKey/CPLockCategoryPrototype.cs create mode 100644 Content.Shared/CrystallPunk/LockKey/Components/CPKeyComponent.cs create mode 100644 Content.Shared/CrystallPunk/LockKey/Components/CPKeyRingComponent.cs create mode 100644 Content.Shared/CrystallPunk/LockKey/Components/CPLockComponent.cs create mode 100644 Content.Shared/CrystallPunk/LockKey/Components/CPLockpickComponent.cs create mode 100644 Content.Shared/CrystallPunk/LockKey/SharedCPLockKeySystem.cs create mode 100644 Resources/Audio/_CP14/Items/attributions.yml create mode 100644 Resources/Audio/_CP14/Items/key_drop.ogg create mode 100644 Resources/Audio/_CP14/Items/lockpick_fail.ogg create mode 100644 Resources/Audio/_CP14/Items/lockpick_use.ogg create mode 100644 Resources/Locale/ru-RU/lock/lock-component.ftl create mode 100644 Resources/Locale/ru-RU/lock/lock-crystall-punk.ftl rename Resources/Prototypes/{CrystallPunk => _CP14}/Entities/Markers/Spawners/jobs.yml (100%) create mode 100644 Resources/Prototypes/_CP14/Entities/Structures/Doors/wooden_doors.yml rename Resources/Prototypes/{CrystallPunk => _CP14}/Entities/Structures/Furniture/chairs.yml (100%) rename Resources/Prototypes/{CrystallPunk => _CP14}/Entities/Structures/Furniture/tables.yml (100%) rename Resources/Prototypes/{CrystallPunk => _CP14}/Entities/Structures/Walls/walls.yml (79%) create mode 100644 Resources/Prototypes/_CP14/Entities/keyrings.yml create mode 100644 Resources/Prototypes/_CP14/Entities/keys.yml create mode 100644 Resources/Prototypes/_CP14/Entities/locks.yml create mode 100644 Resources/Prototypes/_CP14/LockCategories/LockCategory.yml rename Resources/Prototypes/{CrystallPunk => _CP14}/Roles/Jobs/Mercenary/adventurer.yml (100%) rename Resources/Prototypes/{CrystallPunk => _CP14}/Roles/Jobs/departments.yml (100%) rename Resources/Prototypes/{CrystallPunk => _CP14}/Roles/play_time_tracker.yml (100%) rename Resources/Prototypes/{CrystallPunk => _CP14}/Tiles/natural.yml (100%) create mode 100644 Resources/Prototypes/_CP14/tags.yml delete mode 100644 Resources/Textures/CrystallPunk/Objects/keys.rsi/base.png create mode 100644 Resources/Textures/CrystallPunk/Objects/keys.rsi/key1.png create mode 100644 Resources/Textures/CrystallPunk/Objects/keys.rsi/key10.png create mode 100644 Resources/Textures/CrystallPunk/Objects/keys.rsi/key11.png create mode 100644 Resources/Textures/CrystallPunk/Objects/keys.rsi/key12.png create mode 100644 Resources/Textures/CrystallPunk/Objects/keys.rsi/key13.png create mode 100644 Resources/Textures/CrystallPunk/Objects/keys.rsi/key14.png create mode 100644 Resources/Textures/CrystallPunk/Objects/keys.rsi/key15.png create mode 100644 Resources/Textures/CrystallPunk/Objects/keys.rsi/key16.png create mode 100644 Resources/Textures/CrystallPunk/Objects/keys.rsi/key17.png create mode 100644 Resources/Textures/CrystallPunk/Objects/keys.rsi/key18.png create mode 100644 Resources/Textures/CrystallPunk/Objects/keys.rsi/key2.png create mode 100644 Resources/Textures/CrystallPunk/Objects/keys.rsi/key3.png create mode 100644 Resources/Textures/CrystallPunk/Objects/keys.rsi/key4.png create mode 100644 Resources/Textures/CrystallPunk/Objects/keys.rsi/key5.png create mode 100644 Resources/Textures/CrystallPunk/Objects/keys.rsi/key6.png create mode 100644 Resources/Textures/CrystallPunk/Objects/keys.rsi/key7.png create mode 100644 Resources/Textures/CrystallPunk/Objects/keys.rsi/key8.png create mode 100644 Resources/Textures/CrystallPunk/Objects/keys.rsi/key9.png create mode 100644 Resources/Textures/CrystallPunk/Objects/keys.rsi/keyring.png create mode 100644 Resources/Textures/CrystallPunk/Objects/keys.rsi/lock.png create mode 100644 Resources/Textures/CrystallPunk/Objects/keys.rsi/lockpick.png create mode 100644 Resources/Textures/CrystallPunk/Objects/keys.rsi/ring-0.png create mode 100644 Resources/Textures/CrystallPunk/Objects/keys.rsi/ring-1.png create mode 100644 Resources/Textures/CrystallPunk/Objects/keys.rsi/ring-2.png create mode 100644 Resources/Textures/CrystallPunk/Objects/keys.rsi/ring-3.png create mode 100644 Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/full.png create mode 100644 Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/meta.json create mode 100644 Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/wood0.png create mode 100644 Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/wood1.png create mode 100644 Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/wood2.png create mode 100644 Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/wood3.png create mode 100644 Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/wood4.png create mode 100644 Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/wood5.png create mode 100644 Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/wood6.png create mode 100644 Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/wood7.png create mode 100644 Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/full.png create mode 100644 Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/meta.json create mode 100644 Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/stone0.png create mode 100644 Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/stone1.png create mode 100644 Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/stone2.png create mode 100644 Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/stone3.png create mode 100644 Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/stone4.png create mode 100644 Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/stone5.png create mode 100644 Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/stone6.png create mode 100644 Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/stone7.png diff --git a/Content.Server/CrystallPunk/LockKey/KeyholeGenerationSystem.cs b/Content.Server/CrystallPunk/LockKey/KeyholeGenerationSystem.cs new file mode 100644 index 0000000000..2266663f02 --- /dev/null +++ b/Content.Server/CrystallPunk/LockKey/KeyholeGenerationSystem.cs @@ -0,0 +1,136 @@ + +using Content.Server.GameTicking.Events; +using Content.Shared.Containers.ItemSlots; +using Content.Shared.CrystallPunk.LockKey; +using Content.Shared.Examine; +using Content.Shared.Interaction; +using Content.Shared.Popups; +using Content.Shared.Lock; +using Content.Shared.Verbs; +using Robust.Shared.Prototypes; +using Robust.Shared.Random; +using System.Diagnostics.CodeAnalysis; +using System.Linq; + +namespace Content.Server.CrystallPunk.LockKey; + + +public sealed partial class KeyholeGenerationSystem : EntitySystem +{ + [Dependency] private readonly IPrototypeManager _proto = default!; + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; + [Dependency] private readonly ItemSlotsSystem _itemSlots = default!; + [Dependency] private readonly LockSystem _lock = default!; + + private Dictionary, List> _roundKeyData = new(); + + private const int DepthCompexity = 2; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnRoundStart); + + SubscribeLocalEvent(OnLockInit); + SubscribeLocalEvent(OnKeyInit); + + SubscribeLocalEvent(OnKeyExamine); + } + + #region Init + private void OnRoundStart(RoundStartingEvent ev) + { + _roundKeyData = new(); + } + + private void OnKeyInit(Entity keyEnt, ref MapInitEvent args) + { + if (keyEnt.Comp.AutoGenerateShape != null) + { + keyEnt.Comp.LockShape = GetKeyLockData(keyEnt.Comp.AutoGenerateShape.Value); + } + } + + private void OnLockInit(Entity lockEnt, ref MapInitEvent args) + { + if (lockEnt.Comp.AutoGenerateShape != null) + { + lockEnt.Comp.LockShape = GetKeyLockData(lockEnt.Comp.AutoGenerateShape.Value); + } + } + #endregion + + private void OnKeyExamine(Entity key, ref ExaminedEvent args) + { + var parent = Transform(key).ParentUid; + if (parent != args.Examiner) + return; + + if (key.Comp.LockShape == null) + return; + + var markup = Loc.GetString("cp-lock-examine-key", ("item", MetaData(key).EntityName)); + markup += " ("; + foreach (var item in key.Comp.LockShape) + { + markup += $"{item} "; + } + markup += ")"; + args.PushMarkup(markup); + } + + private List GetKeyLockData(ProtoId category) + { + if (_roundKeyData.ContainsKey(category)) + return _roundKeyData[category]; + else + { + var newData = GenerateNewUniqueLockData(category); + _roundKeyData[category] = newData; + return newData; + } + } + + private List GenerateNewUniqueLockData(ProtoId category) + { + List newKeyData = new List(); + var categoryData = _proto.Index(category); + var ready = false; + var iteration = 0; + + while (!ready) + { + //Generate try + newKeyData = new List(); + for (int i = 0; i < categoryData.Complexity; i++) + { + newKeyData.Add(_random.Next(-DepthCompexity, DepthCompexity)); + } + + //Identity Check shitcode + // На текущий момент он пытается сгенерировать уникальный код. Если он 100 раз не смог сгенерировать уникальный код, он выдаст последний сгенерированный неуникальный. + var unique = true; + foreach (var pair in _roundKeyData) + { + if (newKeyData.SequenceEqual(pair.Value)) + { + unique = false; + break; + } + } + if (unique) + return newKeyData; + else + iteration++; + + if (iteration > 100) + { + break; + } + } + Log.Error("The unique key for CPLockSystem could not be generated!"); + return newKeyData; //FUCK + } +} diff --git a/Content.Server/CrystallPunk/SpawnMapBiome/StationBiomeComponent.cs b/Content.Server/CrystallPunk/StationBiome/StationBiomeComponent.cs similarity index 88% rename from Content.Server/CrystallPunk/SpawnMapBiome/StationBiomeComponent.cs rename to Content.Server/CrystallPunk/StationBiome/StationBiomeComponent.cs index a61f30b370..f52330c8c8 100644 --- a/Content.Server/CrystallPunk/SpawnMapBiome/StationBiomeComponent.cs +++ b/Content.Server/CrystallPunk/StationBiome/StationBiomeComponent.cs @@ -1,7 +1,7 @@ using Content.Shared.Parallax.Biomes; using Robust.Shared.Prototypes; -namespace Content.Server.Corvax.CrystallPunk.SpawnMapBiome; +namespace Content.Server.CrystallPunk.SpawnMapBiome; /// /// allows you to initialize a planet on a specific map at initialization time. diff --git a/Content.Server/CrystallPunk/SpawnMapBiome/StationBiomeSystem.cs b/Content.Server/CrystallPunk/StationBiome/StationBiomeSystem.cs similarity index 95% rename from Content.Server/CrystallPunk/SpawnMapBiome/StationBiomeSystem.cs rename to Content.Server/CrystallPunk/StationBiome/StationBiomeSystem.cs index c794474e95..13aea7b18c 100644 --- a/Content.Server/CrystallPunk/SpawnMapBiome/StationBiomeSystem.cs +++ b/Content.Server/CrystallPunk/StationBiome/StationBiomeSystem.cs @@ -5,7 +5,7 @@ using Content.Server.Station.Systems; using Robust.Shared.Map; using Robust.Shared.Prototypes; -namespace Content.Server.Corvax.CrystallPunk.SpawnMapBiome; +namespace Content.Server.CrystallPunk.SpawnMapBiome; public sealed partial class StationBiomeSystem : EntitySystem { [Dependency] private readonly BiomeSystem _biome = default!; diff --git a/Content.Server/Storage/EntitySystems/EntityStorageSystem.cs b/Content.Server/Storage/EntitySystems/EntityStorageSystem.cs index 8b31f598d0..7c9d7b91a7 100644 --- a/Content.Server/Storage/EntitySystems/EntityStorageSystem.cs +++ b/Content.Server/Storage/EntitySystems/EntityStorageSystem.cs @@ -3,6 +3,7 @@ using Content.Server.Atmos.EntitySystems; using Content.Server.Body.Systems; using Content.Server.Construction; using Content.Server.Construction.Components; +using Content.Server.CrystallPunk.LockKey; using Content.Server.Storage.Components; using Content.Shared.Destructible; using Content.Shared.Explosion; @@ -36,7 +37,7 @@ public sealed class EntityStorageSystem : SharedEntityStorageSystem SubscribeLocalEvent(OnEntityUnpausedEvent); SubscribeLocalEvent(OnComponentInit); SubscribeLocalEvent(OnComponentStartup); - SubscribeLocalEvent(OnInteract, after: new[] { typeof(LockSystem) }); + SubscribeLocalEvent(OnInteract, after: new[] { typeof(LockSystem), typeof(KeyholeGenerationSystem) }); SubscribeLocalEvent(OnLockToggleAttempt); SubscribeLocalEvent(OnDestruction); SubscribeLocalEvent>(AddToggleOpenVerb); diff --git a/Content.Shared/CrystallPunk/LockKey/CPLockCategoryPrototype.cs b/Content.Shared/CrystallPunk/LockKey/CPLockCategoryPrototype.cs new file mode 100644 index 0000000000..55fedbe817 --- /dev/null +++ b/Content.Shared/CrystallPunk/LockKey/CPLockCategoryPrototype.cs @@ -0,0 +1,19 @@ +using Robust.Shared.Prototypes; + +namespace Content.Shared.CrystallPunk.LockKey; + +/// +/// A prototype of the lock category. Need a roundstart mapping to ensure that keys and locks will fit together despite randomization. +/// +[Prototype("CPLockCategory")] +public sealed partial class CPLockCategoryPrototype : IPrototype +{ + [ViewVariables] + [IdDataField] + public string ID { get; private set; } = default!; + + /// + /// The number of elements that will be generated for the category. + /// + [DataField] public int Complexity = 3; +} diff --git a/Content.Shared/CrystallPunk/LockKey/Components/CPKeyComponent.cs b/Content.Shared/CrystallPunk/LockKey/Components/CPKeyComponent.cs new file mode 100644 index 0000000000..83c1e4e26d --- /dev/null +++ b/Content.Shared/CrystallPunk/LockKey/Components/CPKeyComponent.cs @@ -0,0 +1,19 @@ +using Robust.Shared.Prototypes; + +namespace Content.Shared.CrystallPunk.LockKey; + +/// +/// a key component that can be used to unlock and lock locks from CPLockComponent +/// +[RegisterComponent] +public sealed partial class CPKeyComponent : Component +{ + [DataField] + public List? LockShape = null; + + /// + /// If not null, automatically generates a key for the specified category on initialization. This ensures that the lock will be opened with a key of the same category. + /// + [DataField] + public ProtoId? AutoGenerateShape = null; +} diff --git a/Content.Shared/CrystallPunk/LockKey/Components/CPKeyRingComponent.cs b/Content.Shared/CrystallPunk/LockKey/Components/CPKeyRingComponent.cs new file mode 100644 index 0000000000..72a8eab3bc --- /dev/null +++ b/Content.Shared/CrystallPunk/LockKey/Components/CPKeyRingComponent.cs @@ -0,0 +1,9 @@ +namespace Content.Shared.CrystallPunk.LockKey; + +/// +/// A component that allows you to track a ring of keys to quickly open and lock doors with the entire bunch. +/// +[RegisterComponent] +public sealed partial class CPKeyRingComponent : Component +{ +} diff --git a/Content.Shared/CrystallPunk/LockKey/Components/CPLockComponent.cs b/Content.Shared/CrystallPunk/LockKey/Components/CPLockComponent.cs new file mode 100644 index 0000000000..ff17524368 --- /dev/null +++ b/Content.Shared/CrystallPunk/LockKey/Components/CPLockComponent.cs @@ -0,0 +1,37 @@ +using Content.Shared.CrystallPunk.LockKey; +using Content.Shared.Damage; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared.CrystallPunk.LockKey; + +/// +/// A component of a lock that stores its keyhole shape, complexity, and current state. +/// +[RegisterComponent] +public sealed partial class CPLockComponent : Component +{ + [DataField] + public List? LockShape = null; + + [DataField] + public float LockPickDamageChance = 0.2f; + + /// + /// On which element of the shape sequence the lock is now located. It's necessary for the mechanics of breaking and entering. + /// + [DataField] + public int LockpickStatus = 0; + + /// + /// after a lock is broken into, it leaves a description on it that it's been tampered with. + /// + [DataField] + public bool LockpickeddFailMarkup = false; + + /// + /// If not null, automatically generates a lock for the specified category on initialization. This ensures that the lock will be opened with a key of the same category. + /// + [DataField] + public ProtoId? AutoGenerateShape = null; +} diff --git a/Content.Shared/CrystallPunk/LockKey/Components/CPLockpickComponent.cs b/Content.Shared/CrystallPunk/LockKey/Components/CPLockpickComponent.cs new file mode 100644 index 0000000000..153e681ca6 --- /dev/null +++ b/Content.Shared/CrystallPunk/LockKey/Components/CPLockpickComponent.cs @@ -0,0 +1,32 @@ +using Content.Shared.CrystallPunk.LockKey; +using Robust.Shared.Audio; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared.CrystallPunk.LockKey; + +/// +/// A component of a lock that stores its keyhole shape, complexity, and current state. +/// +[RegisterComponent] +public sealed partial class CPLockpickComponent : Component +{ + [DataField] + public int Health = 3; + + [DataField] + public SoundSpecifier SuccessSound = new SoundPathSpecifier("/Audio/_CP14/Items/lockpick_use.ogg") + { + Params = AudioParams.Default + .WithVariation(0.05f) + .WithVolume(0.5f) + }; + + [DataField] + public SoundSpecifier FailSound = new SoundPathSpecifier("/Audio/_CP14/Items/lockpick_fail.ogg") + { + Params = AudioParams.Default + .WithVariation(0.05f) + .WithVolume(0.5f) + }; +} diff --git a/Content.Shared/CrystallPunk/LockKey/SharedCPLockKeySystem.cs b/Content.Shared/CrystallPunk/LockKey/SharedCPLockKeySystem.cs new file mode 100644 index 0000000000..2e9e1ae874 --- /dev/null +++ b/Content.Shared/CrystallPunk/LockKey/SharedCPLockKeySystem.cs @@ -0,0 +1,334 @@ + +using Content.Shared.Containers.ItemSlots; +using Content.Shared.Interaction; +using Content.Shared.Lock; +using Content.Shared.Popups; +using Robust.Shared.Containers; +using Robust.Shared.Serialization; +using System.Diagnostics.CodeAnalysis; +using Content.Shared.Verbs; +using Content.Shared.Storage.EntitySystems; +using Content.Shared.Storage; +using Robust.Shared.Random; +using Robust.Shared.Audio.Systems; + +namespace Content.Shared.CrystallPunk.LockKey; + +/// +/// +/// +public sealed class SharedCPLockKeySystem : EntitySystem +{ + + [Dependency] private readonly ItemSlotsSystem _itemSlots = default!; + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; + [Dependency] private readonly LockSystem _lock = default!; + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + + private const int DepthCompexity = 2; //TODO - fix this constant duplication from KeyholeGenerationSystem.cs + + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnLockInsertAttempt); + + SubscribeLocalEvent(OnLockInserted); + SubscribeLocalEvent(OnLockRemoved); + + SubscribeLocalEvent(OnKeyInteract); + SubscribeLocalEvent(OnKeyRingInteract); + SubscribeLocalEvent>(OnKeyToLockVerb); + SubscribeLocalEvent>(OnLockpickToLockVerb); + } + private void OnKeyRingInteract(Entity keyring, ref AfterInteractEvent args) + { + if (args.Handled) + return; + + if (!args.CanReach || args.Target is not { Valid: true } target) + return; + + if (!TryComp(keyring, out var storageComp)) + return; + + + if (TryComp(args.Target, out var lockComp) && + TryGetLockFromSlot(args.Target.Value, out var lockEnt)) + { + + foreach (var item in storageComp.StoredItems) + { + if (!TryComp(item.Key, out var keyComp)) + continue; + + if (keyComp.LockShape != lockEnt.Value.Comp.LockShape) + continue; + + TryUseKeyOnLock(args.User, args.Target.Value, new Entity(item.Key, keyComp), lockEnt.Value); + args.Handled = true; + return; + } + _popup.PopupEntity(Loc.GetString("cp-lock-keyring-use-nofit"), args.Target.Value, args.User); + } + } + + private void OnKeyInteract(Entity key, ref AfterInteractEvent args) + { + if (args.Handled) + return; + + if (!args.CanReach || args.Target is not { Valid: true } target) + return; + + if (TryComp(args.Target, out var lockComp) && + TryGetLockFromSlot(args.Target.Value, out var lockEnt)) + { + TryUseKeyOnLock(args.User, args.Target.Value, key, new Entity(lockEnt.Value.Owner, lockEnt.Value.Comp)); + args.Handled = true; + } + } + + private void OnLockpickToLockVerb(Entity lockpick, ref GetVerbsEvent args) + { + if (!args.CanInteract || !args.CanAccess) + return; + + if (!TryComp(args.Target, out var lockComp) || !lockComp.Locked) + return; + + if (!TryGetLockFromSlot(args.Target, out var lockItem)) + return; + + if (!TryComp(lockItem, out var lockItemComp)) + return; + + var target = args.Target; + var user = args.User; + + for (int i = DepthCompexity; i >= -DepthCompexity; i--) + { + var height = i; + var verb = new UtilityVerb() + { + Act = () => + { + TryHackDoorElement(user, target, lockpick, lockItemComp, lockComp, height); + }, + Text = Loc.GetString("cp-lock-verb-lockpick-use-text") + $" {height}", + Message = Loc.GetString("cp-lock-verb-lockpick-use-message"), + Category = VerbCategory.Lockpick, + Priority = height, + }; + + args.Verbs.Add(verb); + } + } + + private bool TryHackDoorElement(EntityUid user, EntityUid target, Entity lockpick, CPLockComponent lockEnt, LockComponent lockComp, int height) + { + if (lockEnt.LockShape == null) + return true; + + if (height == lockEnt.LockShape[lockEnt.LockpickStatus]) //Success + { + _audio.PlayPvs(lockpick.Comp.SuccessSound, target); + lockEnt.LockpickStatus++; + if (lockEnt.LockpickStatus >= lockEnt.LockShape.Count) // Final success + { + if (lockComp.Locked) + { + _lock.TryUnlock(target, user, lockComp); + _popup.PopupEntity(Loc.GetString("cp-lock-unlock-lock", ("lock", MetaData(lockEnt.Owner).EntityName)), target, user); + lockEnt.LockpickStatus = 0; + return true; + } + else + { + _lock.TryLock(target, user, lockComp); + _popup.PopupEntity(Loc.GetString("cp-lock-lock-lock", ("lock", MetaData(lockEnt.Owner).EntityName)), target, user); + lockEnt.LockpickStatus = 0; + return true; + } + } + _popup.PopupEntity(Loc.GetString("cp-lock-lockpick-success"), target, user); + return true; + } + else //Fail + { + _audio.PlayPvs(lockpick.Comp.FailSound, target); + if (_random.Prob(lockEnt.LockPickDamageChance)) // Damage lockpick + { + lockpick.Comp.Health--; + if (lockpick.Comp.Health > 0) + { + _popup.PopupEntity(Loc.GetString("cp-lock-lockpick-failed-damage", ("lock", MetaData(lockEnt.Owner).EntityName)), target, user); + } else + { + _popup.PopupEntity(Loc.GetString("cp-lock-lockpick-failed-break", ("lock", MetaData(lockEnt.Owner).EntityName)), target, user); + QueueDel(lockpick); + } + } + else + { + _popup.PopupEntity(Loc.GetString("cp-lock-lockpick-failed", ("lock", MetaData(lockEnt.Owner).EntityName)), target, user); + } + lockEnt.LockpickeddFailMarkup = true; + lockEnt.LockpickStatus = 0; + return false; + } + } + + private void OnKeyToLockVerb(Entity key, ref GetVerbsEvent args) + { + if (!args.CanInteract || !args.CanAccess) + return; + + if (!TryComp(args.Target, out var lockComp)) + return; + + if (!TryGetLockFromSlot(args.Target, out var lockItem)) + return; + + if (!TryComp(lockItem, out var lockItemComp)) + return; + + var target = args.Target; + var user = args.User; + + var verb = new UtilityVerb() + { + Act = () => + { + TryUseKeyOnLock(user, target, key, new Entity(target, lockItemComp)); + }, + IconEntity = GetNetEntity(key), + Text = Loc.GetString(lockComp.Locked ? "cp-lock-verb-use-key-text-open" : "cp-lock-verb-use-key-text-close", ("item", MetaData(args.Target).EntityName)), + Message = Loc.GetString("cp-lock-verb-use-key-message", ("item", MetaData(args.Target).EntityName)) + }; + + args.Verbs.Add(verb); + } + + private void OnLockInsertAttempt(Entity lockSlot, ref ContainerIsInsertingAttemptEvent args) + { + if (!lockSlot.Comp.Initialized) + return; + + if (args.Container.ID != lockSlot.Comp.LockSlotId) + return; + + if (!TryComp(args.EntityUid, out var lockComp)) + { + args.Cancel(); + return; + } + + if (lockComp == null) + return; + + //if (lockComp.Locked) + //{ + // _popup.PopupEntity(Loc.GetString( + // "cp-lock-lock-insert-fail-locked", + // ("lock", MetaData(args.EntityUid).EntityName), + // ("target", MetaData(lockSlot).EntityName)), lockSlot); + // args.Cancel(); + //} + } + + private void OnLockInserted(Entity lockSlot, ref EntInsertedIntoContainerMessage args) + { + if (!lockSlot.Comp.Initialized) + return; + + if (args.Container.ID != lockSlot.Comp.LockSlotId) + return; + + if (!TryComp(args.Entity, out var lockComp)) + return; + + _appearance.SetData(lockSlot, LockSlotVisuals.LockExist, true); + } + + private void OnLockRemoved(Entity lockSlot, ref EntRemovedFromContainerMessage args) + { + if (args.Container.ID != lockSlot.Comp.LockSlotId) + return; + _appearance.SetData(lockSlot, LockSlotVisuals.LockExist, false); + } + + public bool TryGetLockFromSlot(EntityUid uid, + [NotNullWhen(true)] out Entity? lockEnt, + LockComponent? component = null) + { + if (!Resolve(uid, ref component, false)) + { + lockEnt = null; + return false; + } + + if (component.LockSlotId == null) + { + lockEnt = null; + return false; + } + + if (_itemSlots.TryGetSlot(uid, component.LockSlotId, out ItemSlot? slot)) + { + if (TryComp(slot.Item, out var lockComp)) + { + lockEnt = new Entity(slot.Item.Value, lockComp); + return true; + } + else + { + lockEnt = null; + return false; + } + } + + lockEnt = null; + return false; + } + private bool TryUseKeyOnLock(EntityUid user, EntityUid target, Entity keyEnt, Entity lockEnt) + { + if (!TryComp(target, out var lockComp)) + return false; + + var keyShape = keyEnt.Comp.LockShape; + var lockShape = lockEnt.Comp.LockShape; + + if (keyShape == null || lockShape == null) + return false; + + if (keyShape == lockShape) + { + if (lockComp.Locked) + { + if(_lock.TryUnlock(target, user)) + _popup.PopupEntity(Loc.GetString("cp-lock-unlock-lock", ("lock", MetaData(lockEnt).EntityName)), lockEnt, user); + } + else + { + if (_lock.TryLock(target, user)) + _popup.PopupEntity(Loc.GetString("cp-lock-lock-lock", ("lock", MetaData(lockEnt).EntityName)), lockEnt, user); + } + return true; + } + else + { + _popup.PopupEntity(Loc.GetString("cp-lock-key-use-nofit"), lockEnt, user); + } + return false; + } +} + +[Serializable, NetSerializable] +public enum LockSlotVisuals : byte +{ + LockExist +} diff --git a/Content.Shared/Lock/LockComponent.cs b/Content.Shared/Lock/LockComponent.cs index 5587fc2698..221b2857a7 100644 --- a/Content.Shared/Lock/LockComponent.cs +++ b/Content.Shared/Lock/LockComponent.cs @@ -18,7 +18,7 @@ public sealed partial class LockComponent : Component /// [DataField("locked"), ViewVariables(VVAccess.ReadWrite)] [AutoNetworkedField] - public bool Locked = true; + public bool Locked = true; /// /// Whether or not the lock is toggled by simply clicking. @@ -71,6 +71,12 @@ public sealed partial class LockComponent : Component [DataField] [AutoNetworkedField] public TimeSpan UnlockTime; + + /// + /// CrystallPunk LockSystem Adapt: we need LockEntity in object, in slotId. + /// + [DataField] + public string? LockSlotId = string.Empty; } /// diff --git a/Content.Shared/Lock/LockSystem.cs b/Content.Shared/Lock/LockSystem.cs index 74cf5496d9..6f7769e708 100644 --- a/Content.Shared/Lock/LockSystem.cs +++ b/Content.Shared/Lock/LockSystem.cs @@ -1,6 +1,8 @@ using Content.Shared.Access.Components; using Content.Shared.Access.Systems; +using Content.Shared.CrystallPunk.LockKey; using Content.Shared.DoAfter; +using Content.Shared.Doors; using Content.Shared.Emag.Systems; using Content.Shared.Examine; using Content.Shared.Hands.Components; @@ -26,6 +28,7 @@ public sealed class LockSystem : EntitySystem [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly SharedPopupSystem _sharedPopupSystem = default!; [Dependency] private readonly SharedDoAfterSystem _doAfter = default!; + [Dependency] private readonly SharedCPLockKeySystem _lockCP = default!; //CrystallPunk Lock System Adapt /// public override void Initialize() @@ -40,6 +43,7 @@ public sealed class LockSystem : EntitySystem SubscribeLocalEvent(OnEmagged); SubscribeLocalEvent(OnDoAfterLock); SubscribeLocalEvent(OnDoAfterUnlock); + SubscribeLocalEvent(OnBeforeDoorOpened); //CrystallPunk Lock System Adapt } private void OnStartup(EntityUid uid, LockComponent lockComp, ComponentStartup args) @@ -52,17 +56,28 @@ public sealed class LockSystem : EntitySystem if (args.Handled) return; + //CrystallPunk LockSystem Adapt + // Only attempt an unlock by default on Activate - if (lockComp.Locked) - { - TryUnlock(uid, args.User, lockComp); - args.Handled = true; - } - else if (lockComp.LockOnClick) - { - TryLock(uid, args.User, lockComp); - args.Handled = true; - } + //if (lockComp.Locked) + //{ + // TryUnlock(uid, args.User, lockComp); + // args.Handled = true; + //} + //else if (lockComp.LockOnClick) + //{ + // TryLock(uid, args.User, lockComp); + // args.Handled = true; + //} + + //CrystallPunk LockSystem Adapt End + } + private void OnBeforeDoorOpened(EntityUid uid, LockComponent component, BeforeDoorOpenedEvent args) + { + if (!component.Locked) + return; + + args.Cancel(); } private void OnStorageOpenAttempt(EntityUid uid, LockComponent component, ref StorageOpenAttemptEvent args) @@ -78,10 +93,22 @@ public sealed class LockSystem : EntitySystem private void OnExamined(EntityUid uid, LockComponent lockComp, ExaminedEvent args) { - args.PushText(Loc.GetString(lockComp.Locked - ? "lock-comp-on-examined-is-locked" - : "lock-comp-on-examined-is-unlocked", - ("entityName", Identity.Name(uid, EntityManager)))); + //CrystallPunk Lock System Adapt Start + if (lockComp.LockSlotId != null && _lockCP.TryGetLockFromSlot(uid, out var lockEnt)) + { + args.PushText(Loc.GetString("cp-lock-examine-lock-slot", ("lock", MetaData(lockEnt.Value).EntityName))); + + args.PushMarkup(Loc.GetString(lockComp.Locked + ? "lock-comp-on-examined-is-locked" + : "lock-comp-on-examined-is-unlocked", + ("entityName", Identity.Name(uid, EntityManager)))); + if (lockEnt.Value.Comp.LockpickeddFailMarkup) + args.PushMarkup(Loc.GetString("cp-lock-examine-lock-lockpicked", ("lock", MetaData(lockEnt.Value).EntityName))); + } else + { + args.PushText(Loc.GetString("cp-lock-examine-lock-null")); + } + //CrystallPunk Lock System Adapt End } /// @@ -226,20 +253,24 @@ public sealed class LockSystem : EntitySystem private void AddToggleLockVerb(EntityUid uid, LockComponent component, GetVerbsEvent args) { - if (!args.CanAccess || !args.CanInteract || !CanToggleLock(uid, args.User)) - return; + //CrystallPunk Lock System Adapt - AlternativeVerb verb = new() - { - Act = component.Locked ? - () => TryUnlock(uid, args.User, component) : - () => TryLock(uid, args.User, component), - Text = Loc.GetString(component.Locked ? "toggle-lock-verb-unlock" : "toggle-lock-verb-lock"), - Icon = component.Locked ? - new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/unlock.svg.192dpi.png")) : - new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/lock.svg.192dpi.png")), - }; - args.Verbs.Add(verb); + //if (!args.CanAccess || !args.CanInteract || !CanToggleLock(uid, args.User)) + // return; + // + //AlternativeVerb verb = new() + //{ + // Act = component.Locked ? + // () => TryUnlock(uid, args.User, component) : + // () => TryLock(uid, args.User, component), + // Text = Loc.GetString(component.Locked ? "toggle-lock-verb-unlock" : "toggle-lock-verb-lock"), + // Icon = component.Locked ? + // new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/unlock.svg.192dpi.png")) : + // new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/lock.svg.192dpi.png")), + //}; + //args.Verbs.Add(verb); + + //CrystallPunk Lock System Adapt End } private void OnEmagged(EntityUid uid, LockComponent component, ref GotEmaggedEvent args) diff --git a/Content.Shared/Verbs/VerbCategory.cs b/Content.Shared/Verbs/VerbCategory.cs index d22041396f..31cbe58abe 100644 --- a/Content.Shared/Verbs/VerbCategory.cs +++ b/Content.Shared/Verbs/VerbCategory.cs @@ -76,6 +76,9 @@ namespace Content.Shared.Verbs public static readonly VerbCategory InstrumentStyle = new("verb-categories-instrument-style", null); + public static readonly VerbCategory Lockpick = + new("verb-categories-lockpick", "/Textures/Interface/VerbIcons/lock.svg.192dpi.png"); + public static readonly VerbCategory ChannelSelect = new("verb-categories-channel-select", null); public static readonly VerbCategory SetSensor = new("verb-categories-set-sensor", null); diff --git a/Resources/Audio/_CP14/Items/attributions.yml b/Resources/Audio/_CP14/Items/attributions.yml new file mode 100644 index 0000000000..c8bc529a55 --- /dev/null +++ b/Resources/Audio/_CP14/Items/attributions.yml @@ -0,0 +1,14 @@ +- files: ["key_drop.ogg"] + license: "CC0-1.0" + copyright: 'Kyanite_ of Freesound.org. Mixed from stereo to mono.' + source: "https://freesound.org/people/Kyanite_/sounds/432913/" + +- files: ["lockpick_use.ogg"] + license: "CC0-1.0" + copyright: 'by Fugeni of Freesound.org. Mixed from stereo to mono.' + source: "https://freesound.org/people/Fugeni/sounds/416286/" + +- files: ["lockpick_fail.ogg"] + license: "CC0-1.0" + copyright: 'by SinusPi of Freesound.org. Cropped and mixed from stereo to mono.' + source: "https://freesound.org/people/SinusPi/sounds/545044/" \ No newline at end of file diff --git a/Resources/Audio/_CP14/Items/key_drop.ogg b/Resources/Audio/_CP14/Items/key_drop.ogg new file mode 100644 index 0000000000000000000000000000000000000000..72707cce764d874f8afb4047d8fb6683179d33e6 GIT binary patch literal 14874 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 Q5|?Q_!p>?JqQWQqe<7QdhyVZp literal 0 HcmV?d00001 diff --git a/Resources/Audio/_CP14/Items/lockpick_fail.ogg b/Resources/Audio/_CP14/Items/lockpick_fail.ogg new file mode 100644 index 0000000000000000000000000000000000000000..c2177b04a485f3014cd809ac944997a189b43214 GIT binary patch literal 9735 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 AF8}}l literal 0 HcmV?d00001 diff --git a/Resources/Audio/_CP14/Items/lockpick_use.ogg b/Resources/Audio/_CP14/Items/lockpick_use.ogg new file mode 100644 index 0000000000000000000000000000000000000000..04b5b58306b3433e4aa8777632f5725b782afba7 GIT binary patch literal 30898 zcmafabwE^4*YI7srCCzCLApVjrD0)-rMpAAU4aFpyHP+uL_k_VKtPa??nVS@6_rp# z{4V}}&-1?TU*GKP-MMGZoS8XOXU;jR@8V(vU;zIH1&5l2o8&hQ33CV&B*@3l-p&68 z00Dv_H^0CiFx>pML-cP-{x{r|yupwgbCM@L zcO3rdEET272^QQBrqU6>O@Vl&5X#s@B|Mf`4tcZ87%q7*l^_km+-_i`%Kv$&NxOo% zN_dR1+d@)AF(0LVFvO}!n~{RBedgF(%I$?QwbCFmyEx1s21k0IA-12NJ284dsGT|% zOPo77dPit@E{0G!p)f{M{0CjEi&6;nKXtGx!O~-Jl!l?P>Plb>aHQKQW8W!N)5Y>i z5QB6Gn@n=Oj?}3;{Y}TMV2Tu zfcg)UQBWMrp=kSZiozQDTSmUa|kg$ZoOl1ehu>HYX|s@%D-b zO3exWNpUrXP8IUr!0t^P*cOw$1yh`Lq3MMwtzZhf&Mmc2yAe#mIzr(^+BY!&8&ZEC zhl2+U#S}NM)!iMrMN@-dO8@P_MltDsQU2onWir@bMbfwwyEPuXnLSr#buxQ8kprcR zeIb0hm}2F_>3!FVY#BU`oO^IBu74Pg0Vv|Jpef<7|2*sySmL05qdZSbqqTUSRhK7= zyyI^k`}>eNu5BifB@!MWRpF}}fE#&*|6NR$>18P4G%IdpBw>Xx@iNWzvSKGTAjVIovW`LUXGN z3J(e%@z(rB0Z4C9ZbD*JNaC}Q#OjdL{e(={g52t7g?yt`$DQ>@|G!B1cY?En8w|UK zAG-#eT@4N<{&E*Zbi-YSH^S^{e*Eud#Qy2yG=)6KP}6{aHjRG=004+a8YtgQGw70Y z%)@ME2^tYi7=v2Lr@`%a&-}{PLpC@ z%f^UxYQ%h-lf`+YX>Q=UsP6L3E0`MyzFM_;t>^uh6k^dBu_^)PiW>%486up_LCQf^ z=8Fi^g-DR{ypirQ6#|iqSe|!6}x0E-18a?v&*-XeM{)O(%gks%^*J=@9#EJovPBe~M!E%(C9VO62&1sjn@ zPXoWzszhgxZhqkUKE2A8WSrP+ix)_5J;2H)FL2%UsMEk0VP)#He1R}Mj|3aBbso71 zMJ!%`ERUPdEwQ_Zto%%vgJ?s8E!fNVvNDU>-oNS*2?(?R%QlYn)XTlP7Z9fau6Y~= z0Km}U#ze=};sGD90BCHnijGnOWem6#@WiIW2cWTI(mb^OaAlrnXgE9x8j~)~$>Fc3 z#a&iupru_FyP(X|h=wCQ>*foQN#e0HNbbs31FfWIm2?&!;_Ast!^K&d(p;629U zc}rrzEfn17ko-J@X3|_7F{xU(ER~sBIvkZy72d|2Y$+1(G6B)&fZxX@RY>=i`|-({gVF zNofl&7{HUj3~eo8kd$}h#|0%ft(2R} zQ#!!yP_OZ0A+ok(aLL1~RBt&NT=hbRUO#o{-3*Jrof&L8fYcgwIVH&rQ`pt zJh2rd<Jdf9k}i>Zq_}$7zZ^jxNJFqbOONEm*L$vIYTkTauEN>chzYzaAh(6g@CKi z>)k()z`*stIEX+is|!^_ac}~I6I>oF1wzcvBWI2OLfX(aVhB?ZlIyf-W_5$p7H9!A znZJQ}SxClNEC#M$pzWk(UV0yOe)-k^RdxsfPOxx+QVe<%4JjTvLjJ$40tGj4Y?WXv zF{I#8T1g7m0{2F!FDRA>l@U?WHIV}e;9SMa0FTI&?3;7)CRLeD{$JVbf26eklfnjm z=t}`V?k<(`G)gI!vG74qAkkiEWxgMg3_g!|vNTRvb~eZ_NbL!V$gCEcx&cA(S4B)_Yht{`hV%pTd=Pc z-&>0z?QfxUsP8y`AO3}>4e2p1|ART!pm84Qe{v&CCJA4x#hicwre(799#iZ|AFdq$ z1jk?ks?jN;wd^HSsW>z@y~V=^m`Uxy0WJpDA=qsYn*ltWxjEo}VI<0U9FG5iRc0su zgNI+4o%t^wC`X9wm4anK7+mXbS-hLn!GB>qHh=2vn;-AQZQ8s9zJqRA`q*wqR$O0in1MsduL_(^7tHh<~ z+X70r%8qd`F@CIg+#G;Rm8i~ zzUi&65OPpR`8Qx;Vf{^k^ANzo`sWIy81|PaaB~H^f#>y$u)m_Px3#meuywGpcCxd# zw6d_au(!6gwYGPnpd<$)IUTKwr?stxCDO{u&cfD?f|8nwl9tZh){%;i4orC6qoky! zrKP8%0^ez&^t9AqJ{2_`9h8O&N(qHJI#E(kQqa&*(?Y4hUuqg!PbWtUJ9}3ODsmbq z)W-&_gNl-p7V2(q?_g`~;9%om>Fh-grK5MCpr)arrn7@WX(*x8-d=Xjo|F_6ARRXc zdsjzmJ4)mKo#(`|0<1-g>F(GK7m&HvWGcfA4%eU$XX6sQ|XhDXReLALLvz3}Kx{t&s> zT|o8ay`4)9eemLs1@}IS4;4+n%haEwa-9jsw>|j4Fd~egYItz#LRZKjYtKFMAkg#vGS%ru<@aCo*z6JjmGh*wT;A^cjMa z;z&74=Z@FGq>#@bA%?l@Om|kZLl#qV%KKUU!P#5G=tq4Vt#p~+ByO9 z-4-V;*a1&vqopGWDk7rEK_@kPOh+OasZ0)6yzh_Ql&|Z03u%92y2XSKvpO5!o|7I5 zOjP1r30!25=?s(*jP&0rHn?r6TwLHJP1*5_{1{7|=vyX*MrvkTW)Nq3kasfO2D%nL zE4)}%{$NWwXF8BLX~2l`Fm&}`)W?r$MCYmO-PPBl)(7Jc{`8Fs{Cq#JOi*?^zfC{Y z+K>9>{9zHhPJ>aP%ZD@O_X+O(T#85|=bxm$Ee6+z%T)^mJ!qX7;G2xGn2;PzC;?V! zY^t)=sKTr32H>CSW zcAT_}+Qy_$e>MaqrGKdwZqknC8_Vzd@{mj&Qz4F_MBTPt_HP9aesL@fj__THR7?SU zv$OTWqE%;+Hg}%*6Bdf^xgV%MkmK$~9~HGMqz}pKH@Nf_BOm9|JX4&*BYlz9JTwIp zZtWEd@M3vTyqBz8wY5xE3wsjC17V8uTp`Ur;=EzLnmN}}BeO$=*@68s(}h{=+1u}G z@cJ|BrAh0whkmTcMowUH!D+1{G%NWz%N;JVm-DmFG7=(=^YyI87(!E|l#y?qWKNNZ z?A+Z%OY>RccvWL=ppW6D5>|`Vu5h6>nhs6xL@bVqgjL6RCBLA?L00~a3kGANYZ3pt zG#L$sNF_&ot3IzP!PgHs$!Nl{bE57S9`yA!6-9;PxE53HKAh1pWl{C{v^7JgXLb9w z008p;?bMcxSfefU5uwGq)(l(igtHFl;`p@xvp+HxE?rj@+)2#nq=MT5k@cDL{uB+Z-96mt$U| zYbOkR8F}fTpOYq@;*dM4H@@B0Z(;E-dnG0pl~+jCMj`flV#JOruJAf2NQc$_wD9td zP{QiF>hy1xI^9p4Rv(-`33i|H$=mnlwd^^|$LBL{;**U}EI1uESgC~EEZ~(=-}S18 z-~_!O<&(7?NzTytc-%MS>-43KkEIa4G*Yr}0??$B`LAy?$kGhe>9SoA6qv^;z4%O6 zbT8z&Q=|Pxr=MwO{5IAy&2ZE0D?UhzVOq6MxcFI4gV*=~23P}L*825JYu?VCKn(^vCQtUAj|INdJ4dy@@k00qbBA5p&Hd{nvNF^rhvpAl2I~h zTnsA7Q6D1iFS$!dD2K_z@2S7^R-S~dV+{R4>z8~pQXYM)Z-f`b@&xpVJjna7~Y$b{HFQiOy z$+2(H*8bJWw(WPCV8;afJoq+$+Pd0PkKIJR7rqS-cQtluZ5o=yp zvs=r-|Ebgc&(Rv6y5vEN#pb&wp$`%#1AI&QG-#=BO;%_4FW~8|ieIC3rYOKMZDJAW zqW(y#i8XaV2EBZG@GZDYZbIZm-278+Y}R<7BKuV%Qvzm?zwCiuX@C@rmDyFVFhIt%<{ za|LmoteUYMHLBt^XePM(%Vnn|ldAG% zRf8}x>eEkNsY3V5DIL2tFy;FURlKTm+d^@826`gSW}C1vT$=&z$nKfwf?{U5WhQ6S z+U3kdw?vVgmgP@sWn#kZueiO<_5+|=9+1zwQp~F?b+)VO^?@-Ub*x^(;B2W#Em|V$Y_?|-@mRIxzYl})*$$M_RCBd@z{^Z+7gN3U6miC`gp4cKH>2Ke^ zUl~G@p5AU))t%SRR*Pf72gmjp?8VQhkAz}z9Ed@(VQ}~Zze{!i*u0&?Rhq#$4OGDL zwTgp+r~v?$yMYxQ4xkIxib3Rj3+Qd-Xl8@!`iqmu z48W)$j`ggdu6+sK+`ZP(b1;ZG218)X9Ww&&HQP6m6vh=b`9TP`-(>^@_=7EzdS6`| z3Tc5MwCt3E3+)7cWdfOu&nAU(if1c=b8!C5sXLhruVtYG$bpk>hRxeG0^-f7oMszX zo#>VjU9Q_o=LGV~ex@B~v7s024~`Y2?pe#zyb8AFKb#Mcc~DZZz;a8tE25DRzfg2% zF(X!ksQU3Eg_1r^8>%n@q*dba_qLX8pJmDr{8wS|WCsP*y@xfO_vBGQC@dKB-XDqm zYjkXcs=O6lLX@Nfb5f_CL=aZGTQPlPOV6m^OIU)&imwGp>Hfz^Ew0hIZ})i#=UHgf zxmL_@E1iD)*0qEi9%&Ddc#xwU_fO}|*Zfl^?ee~rmF>CX1MKZHr^I#>SL*Ew4-Br z1GrV7wvcnpbm6D=xs0r@ovyw&Wd(>z8T-0Vo|)K7Kg{tYyXXD6rT2Vw#Qr5d-jamd zaCFB3sc#heBEj`5uKXF(dZr`Q%Vw$i$4W*T&-wI^9C?bm;sgMuxa=ji22)P#USFM$ znx$+?HBTVoa^HJ~yM=Ab86}7Z1N=Nbu?8>SsdRTe+i6{E4!40Y(#;49QqOKg7qPy# zFxCc&hyHlT-p2gCU&;7FH0$R$8av1O#XIaC^gt)na$Lq5 z4yT$}s3oG4VI0*N9b>$h%n+(!)~^{Tcn)!6YVtOE`T1drubA_(yw#JJELo8Sk*k<3 zOnZuuaRJw$bKXdaoNQvIxH&P1Wit<6+^-K>OP-37#!^vV1bn?bau}wc&%7bvDkxAJ zQT(B#=D|Oqnu?6*@RX^s68N@y`{~C>kp-#Ji8?*S1+2av7PEKGU+%>E%=uLX-bDo^ zD?-5CjroJ`c&SMARu4BTol5k01yOL?-F;#NYsj^?kT&HIw9WG|bZ;WXDe7LA4&fxG z@cNfW7ewW`i|4PuEaZ4(A2oNO>=UMoxmyxyEVQYbsUzNb*=6F$`jLThLPa}^<%=Rp z%r}vf)A>hiC>gElZDh{2m-fq(a#QxFS`tnxqodJ?7tbSfR6zJJ1(wcOb@pklte13-zRv`VfXoddJ^*qiqaWA=3E`PTh~qL zb2s$~Q`pns*-2Hqi~NAMsUrH-IJ*t&zow-X=WlWSSgw6l{jd@Bgu?5xxGrBH^^BBO zA-G5;Y#jULt+>PxCUCBBlkex~)&X%2hDmzFcm?D|FE&>*g+G(?RXlb{aqA~*e0k@g z9W&>h3@$lo;g6mlAO?lO_U_@?LkmE_Ht}tdk>jf`7iK|hMRcCPia`z&YHjhXlbVq+ zuB?sZW>0P()!L;y;wB9fps!cE_uOx3wjQGEin|;YEWNuj`yS_um8_jC_Lht6fRHB- z!p0n{YFzeyLvZ+)c9d;dXZ&g;MC3R);vuS*3+5KjTRjdPVBa^Vy&jhI3zL+8OLsz=`%}n_c+@Ro&OX|4tym)xT zW4|;y4^2(=@~A^12q&En^~)5XJrhm2;J#he%_Y*?+SBMH28n-F6So-j6NB@E#4QUQ zk8M$8WMzuU+CdSis8t=rH6kJcFQoV)t!HofHmImNB&>f6$lb=j4K(9lqX){T+PikA z3?SO#mPw3BRb&-+ielW{KPPSPUb|&l7G$lweuQ12FUd%{O?w&BbpO(MK{*bkpv@8{ z(8w$;7Udzsg>hm%l_y0Rn4S{q)j$C}SWxEu7N)T@R-TQ&fX?p!o?#P{n@Hv-VtMiS z=hJa^K+ysJfP#PjHGY}N`gx)Ag?H#>`Bu_=o7~CWL-U!f_dOqMD{s#q7kk-bQ(*8P zwR!hOgc1X7HObv7LgBaiS5f#SV-R2Ccv-_VxnV_&Vwjq!$n#rxKyOi<-^g)n;;mu?*hRCL&GnA}suY0+xE^U(34 zY6hhX5Eh2tel-6J`#e0v&==@LGvEn(h_VY_I^i!#YJ)f=|7tlM1wu@80FfCj~RdUA7b^$%5rINa}0aIexrC*0{2o8*5p=8W6uH4?8pTZ_b4(`o&J8Ns>Q22e8$ ztn2gLy-mQmIPdLcqCqR0`oYYqMThX#KsOG5q9{ z2K_qFqL&{@;j~Ktm;+|*FQg+rZj`^|JkIxRRqWDf#TXl-B0j0Jhh#{u5gwI zG5{4?@V4k(0JU4UrH`+)8|r?N2@Gh#t$|9(>2x!II+tdXne0WzamUGnp{P~d zIrUZ=jDU5(?8mR|R5uEnOblzSm@a4`Fa|Rh*Iz-91HH52S_G_Sbrp}y@8fjAmU(Oo z5e1O+36*Z;(GR2!vFHopT39Phzu>wX1|BeF5zG}d$CD=lnFEE!^rc1srj!6j9_}UB zI`@dSz_<Q%Lo&D&NoWi@bz^c^&ICAnR zFntjiC~TB#3+0S4g9bT2V=WAhRMsI<%mV;ppqM_Q?U%cAf~;!_-{vY*>Ee z^n{mSLkTc5no&a>ibN1ZN@nGH$&>|W{jV;tk>X*h3` z=k}OehAHQ*OSklyq8Yo__mwO@cB$Ort|LvXrNqMKUZ?TS0mpWq+E36K-~jSlsiM!3 zDQbq0a16HpnZF8%n2M0Y z)&40;fJ=-EvP*)r85fv2*1x=ei2QV0-fW5!ADn@3XGp{%6)`@4$mE>vYwM()-K?i0 zYD~Zmc#*;CEXPr-X?ZDjy!2G%>>!PsXiPo74rMlt*W3S44`IP1Ks+6ycNj_^fHeR^ z1gR`Nr@noT|5)E5_0TW)`i=jZyUY3aOpUYLoUQlEJWb0X2(3 z_~&=oG~S-~f$)dWWvloH%Rp!4T7|A>vD~}HoX!utEmE`>v--QNB&5TRDt%4?oA3Ti zN~(w74}Z{;2sQatZfPKWwEg4YP(H1Qh-zWYL-uWE>+{ye*UPT@aF4)1?;VcuD09U9 z3Uh;7*YeHyK=)RunV$^SX|ImcUICLr{Maomb~8+4(mT7B$y@*%=kxgWoE^((?T3+h z$)(j)Iv00BI6_luXgesn2Opy=wd??-R*n%Z63zTPoFmjzQ;zXLVNdH}I;KYLD zBv0m~n0+myi~WfG)6Odi<6qJ}^BCtbvPKdI-}&}VUZ ztej;XXFR8FD@cj;nnk=<0iVzxC}^so6W1#0@ll)4+>}I%<7Q>$*c*Q{{Nzw^`SX6q z>p_|4BL?%XWcVX$`j5Pxheg|_)SAIHiuRsR&Xnz@jL$xt zQC{zMqf!f*PLd#Z%(G4KDm?O0pg=B(Pt6pr;Iz_53!79OVPf~WZ=jBpgHV+I7^A;j zCGoBB+xI*cNPb%{MJ`SBFq$m11>9cBJC%IV-L;6ibH0+TVg1_`D+nFiKJ_w?m_RFb ztHUR%VRDqMxzB)(Xvq5KP*bdAO}N?Jg4$7j+zGeUF@HnSCbj7?&bdRj3n%hRweU2G z;P@9JJ$L)&`6m^m%(RoXn&BeNVd7o>qH!`Xjf8P?jF?)n>9)ul33Q9cHmnc={D3cJ zW@_deGec@&?vH3Fuz?0FF}}PU+qWWaaygu}u&_dfE$}Q%k2{JDq3HRDSqrP0EI2rT zpu{p~*fJLJAGfxCon{BJVXb%i6I7n#L72zuLrLrO@9MEWdvW|bLyu7o>VSUAxAiT|AfeZ% z->SmD;49Kl`vv0x!0*W{93U618tce<2Y9U*`qgi@MFpuy{g$?uqBN=U@`umol;yiv zfO|cw;#N2o%L^Z4Hu}EXX`Ov_MCBzmS80Q-&uU-he2#f(E7WTJG(5s~D$|{hzYX!N z+eX8_UkO7|5~B;&Gw#M}gbDbP2A0&ll{Nf@l?;0(=|f?H17vE2Vucq;m|8@EEdG3p z%t{^rKC)7zezU@UC|Ut?5)15H!2(b&XX>SDyPYPNtl*vDVNr1u1yEsSh-p1uX(3W4 z4@7`x_v{V1_n~@oR=+;;=9Pf5)3dzx!u55G2H)Js+3Pb z4jd%Ni|>3tD36@H*2n`7wz2Jr$n}@ZmqaD4(*}OALKo-%xW)q)#hL+9v>@CuUEJeDS?jrvFi`-|%&ec6$nW z9UPkURjc76o@kUUX<`#AB=x`EFvr z=iGC>&6zkBNv&3;9QD;y^hx`RmDwuoDydI zxf~_$g8}4!ysZHmUt*W0p@KR(ugQjSmK<`K9}oeulfdYClm4>s3NxWPav+CX^d(@> z=mPy<-i&dcyjn!FVH-mCqifpp*Oa??w@eEwko;pdsp5HW#k#WSW6!=#!%~uSg)MbX zlG0>MKp}3&V8}n*t^ZQikly!eh4nCOzXw|HqTq6T5VG9zP2MR=p-n%7aNy&Bvx@er{*; z7^AM|eO(QEWVH&Kdak72tFJ>86It_53ho-+jI!~QpYv!g_?6le-yLs^unnvtfnGty z6FiUlfXI@Mzt`V7VTPPFT-h1MZ^anRfQ$-Da>Q%a(ufKeL)kyN^*wI4TyrrcpoX;G zrL)5VD9JJ#>*TO#zqHd*mYl9={fZMK+{(@ng9NYa3YRl&$3Oh6qE?IM{a|o)y%^*D zD}(K{^HK?9l9=kiR}VS_8PQ~96QMhbE57&@JZvS;Oq=|(i+%%PV&XWp zWn#HfwG}LsJ{Xx&g$c_OlKNA!=aywdM*Nz981pU3LqD~6qe8d1SaD?h`&yb5oAs~& z@p~E9jJiMmv~>n|{q%o%hb)p5OGDt-k`han@WVLOz?q8b_4}!}vBQ?(9cO0CI01g>*#-LwyLO0sV)!g4q(vS0NZ3RVA?7b; z8p#~}rK~!^5;S(JG6*~c^AV8E5IhS*|SdTr1Oadn55P^m%tgvZ03?jd@YLO00<_qEiJwb5oI! z79lqOl4FD3H%g9#c)vu>+(R6w23_0>3T{6sarhmx>Ub4twie)_P1aS8~uP|JWd1iwb$~6OVf}Y|b|# z(D2@+Ips~L#XKkb8|XrpJLGtHdHlfbqae!o%^nAS-tgLNplA(*XmVLAaS)4wuHil5 zL+0^~Yg6sj4tS#;3GfZQ)^3-RBd0<+L*5pZ3Tqg?TM+zc55_#p+;WK&37;f1{?#-0 z>G4DRkabp!PknkthKw~fr&!jCr~613gJ(hWkZXK4loR6k)(_N4d0sRG5DSi@Tk@~| z5TFB$t&7aT5d6na{c#jK@AZhmT)8JF7Mh4&A|c>Sfp@^jL=c!!$jyZjzpjse^`vlb z5N8bLgf?hqQ^b5zWw$WIoZ=_rP*4KEXw9s#}4 z)DsPfcN#|(k6)0(1T=1eDuJBFq8{+C2FAIP?z{=JuiFg@Ny5-$x9EhNvE(Y48`oPe z4^-R8@U^_`PmwR9sB)!MIgDRXU*5$tsaaaEr!S!9dsXROza4TC`M7nx-Zf&-v|wgE zg;MsXoORVRsG1A^!U(1NRMwlUBcCI2>J&2IkF+OxD)pGoM;jW_no_o=5Jyz|aA}xu zyZn1m>l`YHOl8kg%wX}L{RqmtCOJ2@_L@d3C32lef9OfpfxpBVi+|W?^BwcG!|*0y zdJen5!vO1^b3}_-G-oTtSKu?_U z2xhg%)Mtub-(v?yQl3($fZ7Eljeb`BLPpwTP}PGYonQ$Gwnpi|BoDjCbu;u|TmwG2 z=UjOzIxhAo+Y}i1JJ9#o{ytuexogJS7vXj%UziD%A}2>~$d>JX%nS6Ou_7R2;;z`X z?bKBEDq+s0jq;6e1J2!)MdDqh)6#1;3dJNQu}%3iRbX@JR-!t$zY2?2vnyT5Ex)c- z+!vF6OrU0ZaTktr!QHs!sqHcm$Nw+)(63dej>(eL}?A*i{&VOb(qeL>Wj4$X|=$@L@{Td zkO3jC!IS+&oQ{=n%r4jv$Z-+8DN#-h`eJhFJ(ZTPUHn?Z{?psT@aT1l!>I(F9M4HS9KV?Yg?~)7QT;(}^s1)00L z>vhOe{km&K`MGWNbIs)Y_^r|Lii<^$A=(YhGyOej!BZ^qu)X2x$1!PL6t(F+JDiWg zzYI8-CrCJc%*>X>Vz43x#W+>VH~#+P2Cp!LER#f#_I;yfq+dSS&p5?W`yW`Fv<|<| zw@DcKog^s$Q87Gv_*QUwezucSL0gM( z)=%1(F|;->5|%3xN11rLw)6NL@<{r5HJAlci}lARUu?0&*iN~V@C;CY=jHlsD2tpk zF1meBkGT%(QQX)!(ZWUSww*lj(WHR6bpEDQb$5A}@A{&)Rg)@`*~ZSjw9rS~k1y3m*kernc|Wh-tOJ@`JITH*WAXypo3FI{>I zh5NM$bO2y)f0*k(KE=xl{VbanDgYY}AbK|-U3nS)D4`}Y5?XCF(mF^dv!nG1o82Dr zys|sQmyl4?MB`JojtO;i#Yl~+|7X{8{cN95xoGIq47GP;E{bA{Z~1kX5vrj1f1qLZ zSMg46Md#ny`ZTA?pi(8Yv{;la%uE}e$%Lg+1IB%`%{ffE-FVY;Sl(CLP z-c3%dLt09Ih>KKOGkquiFLo|Eq18!=Ixp1Ftto!OpCnoUWPZw$bB+ ziM#mou(S(U@qC7W`fyDBmw7CbY@M+S8mCu5ViQkNXG+_eF_|x38KS}2V>85J1? z6)mj~=)Oq}b+UDI1~JL0sU2+`tw8b=Qr!AfX7?Z7MCJ+9+j_(9yOD?MLg#|(X(VH}oaLn(jz znD~k7Cp4eUP5XH48&`<#Dm4e2Yo7`CTD$1IVOSfn`4XM=^-kyG5r%}6DHe?)Vf7r$ z9?p9N^hJduc1^@8KB6BaW+eAPtLA`ee`PmZQ27^Q;{(CDdjTm}{r#SUrvlsSMjT`% zTbG;2+y@>Th_=3>4?888lPwJ;qt1+n&lu}IM$`K0$D2ep3&S;3p7CLF$mpHy z(XTJcrY&f(CPN?^R+Vg^@sSzh8v$ryH{01K9uv(^f|qa1Btc)Am46Nv{My4R>+Pl{ zZ}_sx?H%ddM{CPC!@0YR4vn{tHUuLW7*sN!L=6R6h~l51-?|o@ksDjfRrKwz)lP)Z zY3dTMuB58Er-RbBs-w!zhtUvMEOlt=;ILv6)=buk&7cePIhV7R@~^=mK7YSiQE5Cr z!r~<3wO-nfOnMe%-lr=Y`t>RHGJ)Kc-|A=}ukTTiFSg7~3my*n{83m@u(xRX`SRgC z`LF_dZCudjL90x}zY-riTbM!i^UG;zR6sp%Q5I9t+@*ws{{8PEbsLB2t-EC=UA3$l zSGr3)OB1Pi@i|4_BMePE1eo3P4&D>fE_<$=uQMu#@~)WOv)PF;Pc1B5eq1(-Q&c^a zP+$jDB(ZZ1f}bk=#ILHNAMkTdMjhF;VrvQzi8R(|Dm|9>+ zKItMl0B&;7l33#T=z%X^E$k9WJv)y9gv9QnU*|t2opytC!OUrDW{ofvwLaa?waQcp zsc+YeCj?a*Oqe((Jn6mt2QBC5f$;l2!F`kZoRP$rXa zPNHY#kIbLrvt!WM>+L@xCb4az8Pp%ub-UK@cEM6TOGt}Ng@%HA{;accWp9tsx4G~7 zMpN*K)!Yw05SC&6{kUwF+8+yG7M1f6Qv8L24a(joRf!Iv2NV)oY7;GrJX}qT%e;2Z z8!+reS$3QwGFDChJV_k?zU;cc2H`NhP_->4v1`7d;I>{C*lXC0M z%yxe(u~%DN_{0)MLg%wbo?~76%34|EcTYy##0rJR;+?BZ=7PxHN6#Pp`6L$+GpD#7 z-`cE0024%`oWfRc%P+cAFyN{|$ULwIagNMnnlF+O5Fv(NOG`pokeMt;Q!C4$O%HcR zS68h}QB2a@w?#U0i(Y{th9%$SG~Q($*Hi6|hC+2;RfldomLYiGwb%C{t0@Y_ZJAoM zz^mHBdkh0MnRz8+$RzLhVS*O<+6metI(0&#$Q9^k!r+oe^kq0QS;`@tU1!4{uWOKd z_bDVdVl}ev^VjLM?3hM!DGm$e$gaY$3x9E1uQ7%evnFV`@N1|>*Od7POvrw>5aXL@ zj*Iqsj2fa(9Ixjn<=3REg*{iEc>0tdG_0p+sHO5I5R3=~kcE z@78I>4?GYo5#D)VrzdgHRZKnp%aiK7^pY22*fp4JsQ>;sVcr#@W73Cij=voz3P!;D6rSx^l?OmA@lM)eIlWQb+k|QG zb^qW^PpSJogH5Kfdi(d>(3z20OqS2CM8n^t2f*MxilSEYf++0exX>y$-8y0X1x+RV z02pwfjwvGd4!m-SymnVsh9R6F_{FgN?*2@I-rqxR5^q@^>(o3aNCxdjSP`{!yQ0CVrD((A#ZDT32s?6PLP%}6tV@LljNfg=F{-W(S}@pK55e(OSMLlP}JjC1I4 zaeRtq_;s<)D8w&r>=ulb>kVeom~w+uqJCtJ-=l)Q;%?l!+%}|!g!D`GaE%^L0oOPD zN#$vco#^&e&G6ak(q(N$17+k0Dw`^jnEC1mN+y%9%@h&Qz_hqbOFJ-;TM zYzIC#>pZBLShTAOh<7&g7Vm<=7)pqowLq=7Pg%tZ?*nT9w5;A~e7rFQYG;r8(P5oV zCiP)d(>2gz}H%xY^=I!eC?KK&@oIipMPKpBu%68+pw<&*_t_jP6n?T=2!msmc;~ z{=kK-ihk4-sc2XI@bjruTY*$6cJDK{v%VjIku)Qyfq)z2pU?wf8cv z_*8_a2QmO~S6tUx<*N$cDRwPvP|Z<7nhgup`IzcRW~;4(&wd^Wq23=ei5lBc8fZK_q2chdI~h>Vt>IcAk7 z!5SM!Nkog^nnaAp?h8R6ZTDik~_!Ds{(>Wt)(T! z%xPr$xr|0i^iPzZibE2e&D2{wzZ%kRpxHyz_w1k8{Q%J27Dtu%usezCOQA6u?;0w@ zi%}1o7Xz%yCJMj2Sc-&KxNUgpg>{|XlH5c_iEef{m&t}HenD&1ywG6&CNF2QP3A>x zzU`~*g8WLndY@obzu*hXLI=EN>@*I=Kd(z^idZRc*^iaMGJsR=Mol7(a=4|DPR>`A zY?sCU*|a9A8cmtl)`4`@rq0iEA}aAVoq~y;0E5^v5plNp`}dINFF6~HIa4zXe#m~6 zMh0qHVFO1HtSd%{LR|J7UL;mK)(4*uV#mh7a<|f7_R4#*s*~$^?q^hn@+w_XKSYCB zTAeGhk@Q1*>L1x}NhjVr+>y#Eo@!*Vkt8axlqeY=5uNPHO~0Cu^&ASw)%DJIQvkkA zrh<~Cqg1)0DGmZ43fPk%Q&x;m8Myr2Hgnq5jJvb`!V|z2CZ27z+I@aWI~s4EL$}k* z|5STq2g4->H^u&-Xu}exX+2A|F8k|5)-(8So2eh)&W5@EN?qJH@(^jcStH9 zzW3Kc!VbchpFTOyVR&wiABi|C`IGCeOB+hp>^<$eo9#y6_3V>&2vznVlZ<8s43=G7 z0=oE;3k33%C%IpNE9$d=ZBP~f3p%Bya9jT23_k?0jX z7v=4G!9{M(pt^A=euYPcL3>L3VyUu_G~6NdoBk86UL30Zh^|W&XJNZUu4T25hOu@m z)2Yxc$M7Q$OjBEDr_6iARA;Oal$G=Fraz?BYtM_JZnO#N;{a*07>q}VdibPly6yDJ zSDsMYEq9lXL_7$hcXWRZeHa98uSGvUrho$qDTip?f^hkP9~FlMMqEo{!*Z(Srh z-JsNih&`j=dXn(-Hb|M4C{R{hB%jn|;lIWIhBI`QuVimPYk-_j^xVt?aW|+8CkxQt zYu0M^c0j@4N>qTW=YlMhQEzgbr!TkCRO}LNYgf=eWus%L&<3uk6@Wi^N8+KPz+#<; zbpHMs0elYkFr_J~&5>mvdUP5d-11pDD_~7NTp|T<1iTzvNTd1 z?=t@Gb7vMSI@aZ(=al>zk^AfM9K1#~D||oz+_y!XRXKWq3N}+eDWH;9I~%T8O7Rl* zUy~UuKIgQP6#YO_1+Ohn&+lP8fZI?r8dy~WZy^A7(rAlc$S#EWu?wr1?9Y! zZ{uRt_6S=k$P-gFoR44{oKbnwrX~!`D!uV8&wWHr1xfS2r2kEYtOtJm< zpCSX*;`RLQo1I27K1->`DkoQdg6-h$_T>@f)$N~wuAh*1# zYxV&FFe0~-MU;F;vI5>lyl?!*pp+FZXSy`9A}GYuhL0ZPuTPBnN}(uM?#e+I@ynO{#c0kXar!`w$%nGtSPXP$6K8}Dm z7WTAX6x-PSrhrrv?9_)~gkicJcMJ1Qtwc&YhaSq5jc(_f`fuz$2&k4Sqk*2oF9 z8qz>%K~eR)1x>4Dt60(N>WQB1ls;}_xU8GV^*QbS9bcee_+R|*V=F601-!@o$H&Kh zGHI|1VSl8Eu?ag2gxc@Opgw3#lDjN8 z+iGH%gq=`j3RBv;DTREuYEAhxzvERN8_pr2T3c-|c`HjE`Fr%TSfAGMrdxL_ycQk0^RZ>Z z8ix=^d_1#Hfp(4wdhMSC_;9y37r!=Jj$gFSe zmVyUz5`K@^5{Z+J!92JxF{$~=6`5l1e9TBOz8tn1jx}F;s*T;Jh&ax05*^T`L}6@% z2%?)PVh@DvJNgW+lObU>;-UV%6U*T5U%Uw6oFMhQGN8K)RS*15IEa$-39sUyVOTBI#Jb?LqK(_}PVOfq)U0B<=yF z{K0p?-uQ}Vuh;t`(baC=YJIg;hOX-Ia8Ebby-B#0uOE4-pdk6t`@A#Wa*ow<=Ni7i z&FIRvpbcCg;JPpbZS&=qyjmL4_%NIf^*B8Mbn#5G*4p6aR*{2^!-_{OD6avMzf@m( z@%NNLfmf#sJ`#WeT&*#Aeq+}cQA2?k8gE_E5Qtk{g~{CabwL+a`PYRk5h_YRQ-&m&X;Kxjs$+%<{|T38;F0Z(yG(K)`!5?BAgDFj*aNRh_1>JPc0{( z&^f_x-8;epd&7(<%ocp0HL8hMGvV?E$$|-kid@Q~;=%*r}4$Gc`v9J19K; zVo{%ypz^{O3x&OXAtN6)C~%os$_;U4!lwmtQa-Df;Fm{`Q+UGogrLGpS!5YfegC3` z2=i$@YdqTY9B;aiL<~*m%lFN{1X^!zn5FVWRqT8!7|(uWRGc=qd7^InTaKgn;~9EW zod(|T{QA6REyU_>HsC1wzVfuMlDh`B$oQvmjvqftKe428+*@0!fT&kJ=trQfGEtAy zSwol+LAZ>LA^L5xZ8q7`l+fK$MZ8vq(|M6I;fbLmng!gYuBFauhp?u?xBr?4j#FRU zH2_LyEax2@7b#iyeKosmj`?ljTnSTr$}}#mo(<4v1>*J!DOy)Ja0PL5)D=UR&ct~p z*c7_Ewl3iD?Yej3!KbUAZZ8iL*Z8l_JfNybqm#@Xl{!!Vf?&So(a*V|IRJf&K!D-a zqnVFMAeSdF=gbnsjPo^K+5`@8a|uUs;gshAWM6mq?0+FDUQb`qp+mVB0j=KE?@h+R@y@gdCUg zh$92lFJ;}wXAYtlBmZ^RhQdK6eMYTNdN)<;6iIT+@lghYPoBe_C3EZjUQ;ebM47D!#bEMu}dPB@4k6yWak2Af`8SzoO`+%DLbCH6@Sx7xF|+y8(jx zn_p0!At{e=^PuWF{1E8?PBcwUi-TNzz3Y__ScjOSm|+7}Z`D;JZR}}z$m+=_KZF-*7RP)5&8Z({s@8&S_yWJcp$jJGpJSTU^5)09GGpMKa zuxwN7yOQ8G&sEPNI2_JOk89$+36m2WkeR2>6)+M|uiglRi^nac`!%I^pKJ`uC|j59 zR)l~$l$5fyhs-}vBuxFG+wI6`#ec}8K9 z@*AyAXx1z#9%d6JH>D6A>h_7V#{dJ{0&X1(?9t4aY{%fVde|BXjZ|LTewF7fkU(+L zXq|m;S)aMizR#td@OY5zhG~;*HMQ?BSe{Qk;XeiB*!cZb7@pW8PKov5IUq?2%*6O= zkec80t@rEx6sbb?D$D@(^}z(Z(H|HPE^IJkD}p-tpc{O=P~Do1kZ<7aup)WtJK{nK zF!P8_Z87V<7n`nx0asIcj?4`(5~sS|&toF@G$x*8BE=OAH1PyVZMj55ZS{!aXX73; z>X4zCeJWqAZ?$iBW7;&8KMpL%37$-?-Feeepw4&|7w}#Q8 zi6BV~@e2@>)Q0A`W@l;V)NIn9*O7oW8vbl87AeXLfXdiMxLOV^<(|NuW%Io}5+l`L z=@YZq$w?cGdL(H-uK3ORrW>8RtN6%=OO(enk9oQkKC?mBYJX34@21h75>92*sRD0700$B@O z-+quKFMGTTCz!5acD=u=Z*nE&rW?uo@wt-JMf0l!kp>Op?>`Y}+H6j7m-H-poSTb^ zyET{#Q=552(?J$vRevVt_Mbc;a!H^DLoqHLrN_|%wdKL`$L{B-2Bcg*#fSUIi>EBe z-iu(Maip?<`Q44RMH{P1rm5tmDKiV^{-k$0TKPwgMh(46MT50u{V#&HB;R=S*xt`R zw}o>ywMX00@E+UcUF+jaZ?J$Y}{4RExN@zE*$(a6dHbptuZOs?Mr0PgxX z?<6!`=T(gJOcYp|H)K$P_PVxCK4`FeNA4KY9wZ0l6GBQz%D4x&O+aY$3`a23F>p5QNw~ z@xw2M?*@;q8xb~bF;CmZix7A4 zz}s*4CIc8ZX1?$cq&;Hq47{Hiti zzDTTu7Y@bEpy6F9QT@i#fithnYC`m( zJfwXzKS)f7{(V@;2TCp>MPILTKQXFb_U{=`73(IF5LYq8FkoG#AWb2#vZhp3#@z0N z&_Dg0|6FNy_Myti54E_wt-DaGT-OE`Jz!v;VH_=19_tK}!&~2@2vfWs4<(@0+IsX= zATdud2zn;rf5h?5C6=E*B$W6RO!QHoPl=I`SM%Dj5cZ!~*|_f*30T%mz$6YMjg5jT zfDF7drcMO{Sej?=8AoIaK@NtHCT8jy5Vcuz?M@p%(=bF%>i(zXx^vEiwtn#p&z5<6 z-j_iCLW1cGbqcY8Ia!|sgm?ibNsqZYu_?jIIk4tMn!^{<06_O3*BdHg*loj!|d2OVAeVSMbEGrIBwpgG1 zB4#WOR^KFG0sx#vQo-bj_&uAYfcFzIHk>sBsPhm!s;3)UAVA<&lp$QPMVbMC9jV21 zzncXD$Rs~XT!j2^0&r!H3D=IE0YKla<|>@8OS=&sEaG%kbLOBM^Lu17O4IuVTCjTK zAKx?r0b9Aj=fr>5&7?t4tKpgRFP`=t5EK4_&ig^D`wYCIx#YagIEeaBq zVJAxQ=5Ho7f%wzflBe1uSbpDu;&36bn90eHI|RZ7Y>BuxNuE@5oLk9P*VcuQ4l}RI z7(n}@{6K-x=}$aTvk;I)sgpP=c@feXUDjCDYW2bM!`sGX59)3Vd*ESz!L1}`p>DL) z`9Ub|5ue%ieMrERu&^}zib&{V73;7?TVi;jS<<348`4v4R)EZPJYCV!cyvYBzxB5a zR^AH{*fw0um&eYSF9AjPjm&u||AGZ)S@BE#*_u7UZsnwA2T2Jmx?$Dc5`RxU?0|pc zDEz}Y959KC&7j4~aC1Np=5)9gZhZ^-vQlK7w^e`t`K`IRHUxYOH5RAuaNM}8VF1aA zvRc=ts@r;wV|(bj5cSIM0;^0`#72Fh1jUY9?O{c*bxD^?%`v}G@X(1vE%IVbnR-&w z7Dngrjie2J5{%0s?QYg%bbeds6~eFw^_e0_#b0KVtcvQQn?iP#D5%3EgIp8G(shjE zN0CuK$OX(ygyr5u%Zhz6r|`bD`rCh zUcx#B)6(>n`{1we^bxmcj2HkW>%(LAcuf;w!09k@tD+V!0HhcO&1!UCkONT=ji$hh zQW#*QUhW&>Est?ZI@~{3GEBV<4=`JPoG0-HoiOqRG(+N{m~d#x1h%0AHH8O<3(xVR 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 L`Pv%>Ll68PK>A^t literal 0 HcmV?d00001 diff --git a/Resources/Locale/ru-RU/lock/lock-component.ftl b/Resources/Locale/ru-RU/lock/lock-component.ftl new file mode 100644 index 0000000000..cdbd46575e --- /dev/null +++ b/Resources/Locale/ru-RU/lock/lock-component.ftl @@ -0,0 +1,9 @@ +lock-comp-on-examined-is-locked = [color=#a84032]Он заперт[/color]. +lock-comp-on-examined-is-unlocked = [color=#32a834]Он открыт[/color]. +lock-comp-do-lock-success = Вы заблокировали { $entityName }. +lock-comp-do-unlock-success = Вы разблокировали { $entityName }. + +## ToggleLockVerb + +toggle-lock-verb-unlock = Разблокировать +toggle-lock-verb-lock = Заблокировать diff --git a/Resources/Locale/ru-RU/lock/lock-crystall-punk.ftl b/Resources/Locale/ru-RU/lock/lock-crystall-punk.ftl new file mode 100644 index 0000000000..424ade295c --- /dev/null +++ b/Resources/Locale/ru-RU/lock/lock-crystall-punk.ftl @@ -0,0 +1,29 @@ +cp-lock-slot-component-slot-name-default = Замок + +cp-lock-examine-key = Высота зубчиков на ключе выстраивается в следующую последовательность: +cp-lock-examine-lock-slot = Здесь висит {$lock}. +cp-lock-examine-lock-null = Сюда можно прикрепить замок. +cp-lock-examine-lock-lockpicked = [color=#b57c3c]{$lock} выглядит потрепанным, словно в нем кто-то копался.[/color] + + +cp-lock-verb-use-key-text-open = Открыть {$item} +cp-lock-verb-use-key-text-close = Закрыть {$item} +cp-lock-verb-use-key-message = Использовать ключ, чтобы попытаться открыть или закрыть {$item}. + +cp-lock-unlock-lock = Вы открыли {$lock} +cp-lock-lock-lock = Вы заблокировали {$lock} + +cp-lock-key-use-nofit = Кажется, этот ключ сюда не подходит... +cp-lock-keyring-use-nofit = Кажется, ни один из ключей отсюда не подходит... +cp-lock-lock-insert-fail-locked = Сначала разблокируйте {$lock}, чтобы повесить его на {$target} +cp-lock-lock-remove-fail-locked = Сначала разблокируйте {$lock}, чтобы снять его с {$target} +cp-lock-target-use-failed-locked = {$target} не открывается + +cp-lock-verb-lockpick-use-text = Имитировать: +cp-lock-verb-lockpick-use-message = Попытаться имитировать элемент формы ключа. +verb-categories-lockpick = Взлом + +cp-lock-lockpick-success = Что-то в замке сдвигается... +cp-lock-lockpick-failed = {$lock} с громким щелчком встает на место. +cp-lock-lockpick-failed-damage = {$lock} с громким щелчком встает на место, надломив отмчычку. +cp-lock-lockpick-failed-break = {$lock} с громким щелчком встает на место, ломая вашу отмычку. \ No newline at end of file diff --git a/Resources/Maps/CrystallPunk/dev_map.yml b/Resources/Maps/CrystallPunk/dev_map.yml index 3b9dee4fb9..b88833ef8f 100644 --- a/Resources/Maps/CrystallPunk/dev_map.yml +++ b/Resources/Maps/CrystallPunk/dev_map.yml @@ -394,25 +394,25 @@ entities: - type: DayCycle timeEntries: - startColor: "#754a4a" #Рассвет - duration: 10 + duration: 30 isNight: false - startColor: "#e0ba87" #Полдень - duration: 10 + duration: 30 isNight: false - startColor: "#bfeeff" #Полдень - duration: 10 + duration: 30 isNight: false - startColor: "#385163" #Вечер - duration: 10 + duration: 30 isNight: true - startColor: "#060d12" #Ночь - duration: 10 + duration: 30 isNight: true - startColor: "#000000" #Ночь - duration: 10 + duration: 30 isNight: true - startColor: "#120906" #Ночь - duration: 10 + duration: 30 isNight: false - proto: AirAlarm entities: diff --git a/Resources/Prototypes/CrystallPunk/Entities/Markers/Spawners/jobs.yml b/Resources/Prototypes/_CP14/Entities/Markers/Spawners/jobs.yml similarity index 100% rename from Resources/Prototypes/CrystallPunk/Entities/Markers/Spawners/jobs.yml rename to Resources/Prototypes/_CP14/Entities/Markers/Spawners/jobs.yml diff --git a/Resources/Prototypes/_CP14/Entities/Structures/Doors/wooden_doors.yml b/Resources/Prototypes/_CP14/Entities/Structures/Doors/wooden_doors.yml new file mode 100644 index 0000000000..62b4d42cc4 --- /dev/null +++ b/Resources/Prototypes/_CP14/Entities/Structures/Doors/wooden_doors.yml @@ -0,0 +1,67 @@ +- type: entity + parent: BaseMaterialDoorNavMap + id: CPBaseWoodDoor + name: деревянная дверь + description: Не самая прочная конструкция, но это лучше чем ничего. + suffix: Без замка + components: + - type: Sprite + sprite: Structures/Doors/MineralDoors/wood_door.rsi + layers: + - state: closed + map: ["enum.DoorVisualLayers.Base"] + - type: Door + bumpOpen: false + clickOpen: true + closeTimeOne: 0.2 + closeTimeTwo: 0.6 + openTimeOne: 0.6 + openTimeTwo: 0.2 + openSound: + path: /Audio/Effects/door_open.ogg + closeSound: + path: /Audio/Effects/door_close.ogg + - type: Damageable + damageContainer: Inorganic + damageModifierSet: Wood + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 100 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - type: Lock + locked: true + lockSlotId: lock_slot + - type: ItemSlots + slots: + lock_slot: + name: cp-lock-slot-component-slot-name-default + disableEject: true + insertOnInteract: false + ejectOnBreak: true + whitelist: + components: + - CPLock + - type: ContainerContainer + containers: + lock_slot: !type:ContainerSlot + +- type: entity + parent: CPBaseWoodDoor + id: CPWoodDoorTavern + suffix: Таверна + components: + - type: ItemSlots + slots: + lock_slot: + name: cp-lock-slot-component-slot-name-default + startingItem: LockTavern + disableEject: true + insertOnInteract: false + ejectOnBreak: true + whitelist: + components: + - CPLock \ No newline at end of file diff --git a/Resources/Prototypes/CrystallPunk/Entities/Structures/Furniture/chairs.yml b/Resources/Prototypes/_CP14/Entities/Structures/Furniture/chairs.yml similarity index 100% rename from Resources/Prototypes/CrystallPunk/Entities/Structures/Furniture/chairs.yml rename to Resources/Prototypes/_CP14/Entities/Structures/Furniture/chairs.yml diff --git a/Resources/Prototypes/CrystallPunk/Entities/Structures/Furniture/tables.yml b/Resources/Prototypes/_CP14/Entities/Structures/Furniture/tables.yml similarity index 100% rename from Resources/Prototypes/CrystallPunk/Entities/Structures/Furniture/tables.yml rename to Resources/Prototypes/_CP14/Entities/Structures/Furniture/tables.yml diff --git a/Resources/Prototypes/CrystallPunk/Entities/Structures/Walls/walls.yml b/Resources/Prototypes/_CP14/Entities/Structures/Walls/walls.yml similarity index 79% rename from Resources/Prototypes/CrystallPunk/Entities/Structures/Walls/walls.yml rename to Resources/Prototypes/_CP14/Entities/Structures/Walls/walls.yml index 61cf0be2da..266632c0ab 100644 --- a/Resources/Prototypes/CrystallPunk/Entities/Structures/Walls/walls.yml +++ b/Resources/Prototypes/_CP14/Entities/Structures/Walls/walls.yml @@ -37,6 +37,20 @@ key: CPwallswood base: wood +- type: entity + id: CaveStoneWall + name: каменная порода + parent: CPBaseWall + description: Прочная каменная природная стена. От нее веет пещерным холодом. + components: + - type: Sprite + sprite: CrystallPunk/Structures/Walls/cave_stone.rsi + - type: Icon + sprite: CrystallPunk/Structures/Walls/cave_stone.rsi + - type: IconSmooth + key: CPwallsbrick + base: stone + - type: entity id: StoneRuinFragment parent: BaseRock diff --git a/Resources/Prototypes/_CP14/Entities/keyrings.yml b/Resources/Prototypes/_CP14/Entities/keyrings.yml new file mode 100644 index 0000000000..1da63d30d1 --- /dev/null +++ b/Resources/Prototypes/_CP14/Entities/keyrings.yml @@ -0,0 +1,41 @@ +- type: entity + parent: BaseItem + id: BaseKeyRing + suffix: Пустое + name: кольцо для ключей + description: Позволяет комфортно хранить большое количество ключей в одном месте. + components: + - type: CPKeyRing + - type: Sprite + sprite: CrystallPunk/Objects/keys.rsi + layers: + - state: keyring + - state: ring-0 + map: ["enum.StorageFillLayers.Fill"] + - type: Appearance + - type: StorageFillVisualizer + maxFillLevels: 4 + fillBaseName: ring + - type: Storage + grid: + - 0,0,5,0 + maxItemSize: Small + whitelist: + tags: + - CPKey + - type: UserInterface + interfaces: + - key: enum.StorageUiKey.Key + type: StorageBoundUserInterface + - type: ContainerContainer + containers: + storagebase: !type:Container + +- type: entity + parent: BaseKeyRing + id: KeyRingInnkeeper + suffix: Трактирщик + components: + - type: StorageFill + contents: + - id: KeyTavern \ No newline at end of file diff --git a/Resources/Prototypes/_CP14/Entities/keys.yml b/Resources/Prototypes/_CP14/Entities/keys.yml new file mode 100644 index 0000000000..94b6d5c357 --- /dev/null +++ b/Resources/Prototypes/_CP14/Entities/keys.yml @@ -0,0 +1,42 @@ +- type: entity + parent: BaseItem + id: BaseKey + abstract: true + name: ключ + description: Небольшая заковыристая железяка, открывающая определенные замки. Не отдавайте кому попало! + components: + - type: Tag + tags: + - CPKey + - type: Item + size: Tiny + - type: Sprite + sprite: CrystallPunk/Objects/keys.rsi + - type: CPKey + autoGenerateShape: Debug + - type: EmitSoundOnLand + sound: + path: /Audio/_CP14/Items/key_drop.ogg + params: + variation: 0.05 + +- type: entity + parent: BaseItem + id: BaseLockpick + name: отмычка + description: Воровской инструмент, при должном умении и сноровке позволяющий взламывать любые замки. + components: + - type: Sprite + sprite: CrystallPunk/Objects/keys.rsi + state: lockpick + - type: CPLockpick + +- type: entity + parent: BaseKey + id: KeyTavern + name: ключ от таверны + components: + - type: Sprite + state: key1 + - type: CPKey + autoGenerateShape: Tavern \ No newline at end of file diff --git a/Resources/Prototypes/_CP14/Entities/locks.yml b/Resources/Prototypes/_CP14/Entities/locks.yml new file mode 100644 index 0000000000..8dc7183bb3 --- /dev/null +++ b/Resources/Prototypes/_CP14/Entities/locks.yml @@ -0,0 +1,22 @@ +- type: entity + parent: BaseItem + abstract: true + id: BaseLock + name: стальной замок + description: Он запирает вещи. И вам потребуется ключ, чтобы открыть их обратно. + components: + - type: CPLock + lockPickDamageChance: 0.2 + autoGenerateShape: Debug + - type: Sprite + sprite: CrystallPunk/Objects/keys.rsi + layers: + - state: lock + +- type: entity + parent: BaseLock + id: LockTavern + name: замок от таверны + components: + - type: CPLock + autoGenerateShape: Tavern \ No newline at end of file diff --git a/Resources/Prototypes/_CP14/LockCategories/LockCategory.yml b/Resources/Prototypes/_CP14/LockCategories/LockCategory.yml new file mode 100644 index 0000000000..e9cb6787a7 --- /dev/null +++ b/Resources/Prototypes/_CP14/LockCategories/LockCategory.yml @@ -0,0 +1,7 @@ +- type: CPLockCategory + id: Debug + complexity: 10 + +- type: CPLockCategory + id: Tavern + complexity: 3 \ No newline at end of file diff --git a/Resources/Prototypes/CrystallPunk/Roles/Jobs/Mercenary/adventurer.yml b/Resources/Prototypes/_CP14/Roles/Jobs/Mercenary/adventurer.yml similarity index 100% rename from Resources/Prototypes/CrystallPunk/Roles/Jobs/Mercenary/adventurer.yml rename to Resources/Prototypes/_CP14/Roles/Jobs/Mercenary/adventurer.yml diff --git a/Resources/Prototypes/CrystallPunk/Roles/Jobs/departments.yml b/Resources/Prototypes/_CP14/Roles/Jobs/departments.yml similarity index 100% rename from Resources/Prototypes/CrystallPunk/Roles/Jobs/departments.yml rename to Resources/Prototypes/_CP14/Roles/Jobs/departments.yml diff --git a/Resources/Prototypes/CrystallPunk/Roles/play_time_tracker.yml b/Resources/Prototypes/_CP14/Roles/play_time_tracker.yml similarity index 100% rename from Resources/Prototypes/CrystallPunk/Roles/play_time_tracker.yml rename to Resources/Prototypes/_CP14/Roles/play_time_tracker.yml diff --git a/Resources/Prototypes/CrystallPunk/Tiles/natural.yml b/Resources/Prototypes/_CP14/Tiles/natural.yml similarity index 100% rename from Resources/Prototypes/CrystallPunk/Tiles/natural.yml rename to Resources/Prototypes/_CP14/Tiles/natural.yml diff --git a/Resources/Prototypes/_CP14/tags.yml b/Resources/Prototypes/_CP14/tags.yml new file mode 100644 index 0000000000..036e2e097e --- /dev/null +++ b/Resources/Prototypes/_CP14/tags.yml @@ -0,0 +1,2 @@ +- type: Tag + id: CPKey \ No newline at end of file diff --git a/Resources/Textures/CrystallPunk/Objects/keys.rsi/base.png b/Resources/Textures/CrystallPunk/Objects/keys.rsi/base.png deleted file mode 100644 index 3832afa90690f6eb8298c019cb834fddab178169..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 272 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}r#xL8Ln2y} z6C_v{Cy4MEB&dWx-gGtlpYrF$PR=Kcx^;XFPP;B$A}Ij`arV_-+mvUVC}cQO6rSzv z2EsF(PcZ5{$*B7Hg!gc_dj5kyrHz0Fj(t+UB7{(sMZkRa#kBfLQQD@=>|BuWpgU|#X4A$9fjKkn;gJ6Tgi zkG^0CGn}}1x|U+W&nvEN`~FFO;b)9s4GEdy_`fPaq^Bv+L6?ESD$-_EMD)W1psyG_ MUHx3vIVCg!0P4?bT>t<8 diff --git a/Resources/Textures/CrystallPunk/Objects/keys.rsi/key1.png b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key1.png new file mode 100644 index 0000000000000000000000000000000000000000..f1cbbc5907dd9d61f633a38c0dbd0791c6dcb85e GIT binary patch literal 259 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}dp%toLn2y} z6C_v{Cy4Yk1sZUZS6~0r&&8{F%10tW z$!+4KNkYvlrkH>+kbQX5)$D)z(R-iSp9zwvefukyEyXa2A#mN=%&hYh zn&ar^Hp$UDc%<|{Ln2z= zUNGc3WFW%!VE+SA8LpXJl9N8ac;w4cC~)xZT0f`EXgI&j|0FsuB`<_0IaujJw}1JJJ6AFb9K2 z=%OF8jC{+zZREeZzH*+iAcQmf%N$SVwHIHs3toG%o^^VM9z#vtT((vN#THJ61tFbV wt~~zP6twgQ*CW-Le(8`J%F?7^S{Dyobx=TB>~7 z$;&sqrpax$_G^!2W%!*uKiMZ>RisnxjBwQ@4<9ix*va)9Djs8D01BR4dgna%o`0{Z iEW;nMC@C$f|IWgr9iXDpfB!wu#SEUVelF{r5}E+g5?*Tn literal 0 HcmV?d00001 diff --git a/Resources/Textures/CrystallPunk/Objects/keys.rsi/key12.png b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key12.png new file mode 100644 index 0000000000000000000000000000000000000000..ecfa6ab9a297c1a05458c253919d405d53f36289 GIT binary patch literal 235 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}OFdm2Ln2z= zo;T!bF%V$A@P1SHhJfI+x<_tt=RFVOPLi^1R9ew~;gHz_!%d+smvY{0`>~$WhwYzy zLq|skQ%GrY>Fvn7W!qLszyAMv+ve-v``k}V>QL}AK9b2M*r@&3>3S|Z!+x9Rp7(8n*WM^<#$?|uD!^$UfTDkNJ_P+RB h=ej)zXv@Ew;%6emh0D9bxq%L5@O1TaS?83{1OUbTUiAO~ literal 0 HcmV?d00001 diff --git a/Resources/Textures/CrystallPunk/Objects/keys.rsi/key13.png b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key13.png new file mode 100644 index 0000000000000000000000000000000000000000..3ccfd054371facb6a4e91b8a1ab69baafc1cfbd2 GIT binary patch literal 276 zcmV+v0qg#WP)Px#&PhZ;R9J=W(J^YnFcik|zeAu|GJ3GBN#MagPqQ>+?imW9LkVQhmQ00GFZK!2 zEr+lNuL2*SOFJo(ib{qkkRg!wn}qbF_elaFgb?E1MIlAok54z*nxVC(svBF?jrE(iU5}gd*Ukw_ynI{R)$2>-#>NaNl~5Kr z0BzU*)s{t0+x3)1PRNUlLzB8&xn{-;7&8E%RDuh&|2m*l@-Ng?0{92M?=~0zwGcuG aakGw!Mn-w69+Z>-0000Px#u}MThR9J=W(y9R!q8N~wPrNkZGh(T|1$0Is(?)5%zLPogIYS!;>Yj5y7( z){+;c&x_J`Wkdbb`MbU(bUB?_EoKqGe7W|{wHT9hK2p^Uc~SbRZX~T`1Hf~m(Ac>a x=UM=aNeDxQnv{5e*NyhO&DZ{bQc5ZHa}V$JJ>9AwFtPvu002ovPDHLkV1nSUY61WN literal 0 HcmV?d00001 diff --git a/Resources/Textures/CrystallPunk/Objects/keys.rsi/key15.png b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key15.png new file mode 100644 index 0000000000000000000000000000000000000000..18a372694fefdd3a435fb9e28ad009ca255f8909 GIT binary patch literal 251 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}TRmMILn2z= zUfjra$UxxO$9mTbM>jg(_Ni2h6-l4(D8Mdw=WdD65xuwC9KVFDcCh_o(6c(K85Ho4 zjs4(nU-un%$`uz(3G({8+vC!fTkmR?-(`AGwcA*V&+gvo?n~dRV=u-uv@JOql5r`-5Dm|JY*f7=<`V^h@by!xEP1?YsGV+ z7U7HuK28x@b38l6SM1N&9M|pfi@Ln2y} z6C_v{Cy4Yk1sZU+qymlxuwgBlX7 b%zO+gQ(a5d`X@dEI-SAO)z4*}Q$iB})Gbpr literal 0 HcmV?d00001 diff --git a/Resources/Textures/CrystallPunk/Objects/keys.rsi/key17.png b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key17.png new file mode 100644 index 0000000000000000000000000000000000000000..124b5c012e473a477c028812a72d91d774ceb0c9 GIT binary patch literal 230 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}3p`yMLn2z= zUNGcpHV|QZV81lH;Nsi6PILAqm|Ke;(K*Q(#qw6Mq=2`gr^Jg>^@50u)t~#HoIXAH ztIr@PD46=<*TL-My=K?S|2_z|y%jNk)%`g|vs_qQBNu9DcW^k(sJO5x&*Q2y)0xLD z+g66&zLF)Uen;M4=QUgI8h%s0$-8YC<`hfYo0sOb7ytfkJLmCkXXYdERlDP^_y>1% cbo{%?ZR{43c)dkB5a?D0Pgg&ebxsLQ0EUuT-T(jq literal 0 HcmV?d00001 diff --git a/Resources/Textures/CrystallPunk/Objects/keys.rsi/key18.png b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key18.png new file mode 100644 index 0000000000000000000000000000000000000000..a60de847dd78eb525162364ac1cd03b846332ba1 GIT binary patch literal 261 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}`#oJ8Ln2z= zUNq!7WFT_vW4+^rqs$_k$}-L`?tb(}lBH1K;9XyJ$2XVe9ms2{V3v(pEGrXR(iObr zQ9@VugWtXB{S?7-H6$@0$DV^j-^3UWe5;3toj=Ic&Q* z>(Rd&t0eYgo>^tTnHd5lY_irR&f)voo@^}j#b)<4D|gNL8ax{g>qc)*wEMbl2TQ|q zure_J_hd{|?q`S-dLhvJd*yO`gwx-OZQQvvcGgQu&X J%Q~loCIAJ}bo^Mo|Z)c;Yr5xI8p>&|8w7N3fH-DL3P#rIuHBKZQoe$D!9~`T@J6A8VtTz%+>ebdZsqF@z;UBd7nSd=T>YHuz$|DGSrjtq|)&$pidY)UHx3v IIVCg!0Onz5ga7~l literal 0 HcmV?d00001 diff --git a/Resources/Textures/CrystallPunk/Objects/keys.rsi/key3.png b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key3.png new file mode 100644 index 0000000000000000000000000000000000000000..96d8786e2422c1fe03ee3e36148913e30ee4b325 GIT binary patch literal 257 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}yFFbTLn2z= zUb5youOW~ zAzdc1bJx!tIKyYWL7_#!>5ujCWtr6$*Y@VIH@tp(uEc0tRr=!8%S)yl`pO(*@1W^A zDXnx;+SZk`|JdHzuq$O>%=Ohr&lv8!CYty{@Vhd@r$s97+~o^RWNPN#-*)#(%v5nz zhN$q2SVn<1x#gdqs?OSXOsqm~$NgNX-^@-Nibu}dGDLAXRmvEjlmvQ%!PC{xWt~$( F69532WvT!G literal 0 HcmV?d00001 diff --git a/Resources/Textures/CrystallPunk/Objects/keys.rsi/key4.png b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key4.png new file mode 100644 index 0000000000000000000000000000000000000000..0aa950808da1890c1bd42447963715465053dfe4 GIT binary patch literal 263 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}2R&UJLn2z= zUNYo5WFT_vW4*(Lqs$_k$}-Mh))P%Xuh7xV@h;DbGfBLfX*cI1-dhW^w=^&A_A8w* ztxuMTZ{PhX6TW}i=itDh*z%)%mG{N8`W0=>b`0mQ&pugkW###(hA%~HZ~Z?0m(4+h zjZ48!EmVX}%TCQVwl+=mK+eWh(>||Ub^X|sjJFS}^%x@KfMjHxiS54UWn33u3o-0l zzowm0A~?y1v*8-w@-IEt_)2$_NoX_P5`VWXJG&li=}vy;1$Il4&b^oq^bCWitDnm{ Hr-UW|e5GoL literal 0 HcmV?d00001 diff --git a/Resources/Textures/CrystallPunk/Objects/keys.rsi/key5.png b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key5.png new file mode 100644 index 0000000000000000000000000000000000000000..6d16265fc34d45a28777c0fe4954d3fbfe485d3f GIT binary patch literal 257 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}yFFbTLn2z= zUNGc3WFT_vW4+^rqZb!W(44T)wqLJnbGpD0N0xH)xhxyI=Q)`3U*wBrwr%M4D>c03 zc~5KK{V6R^_D<)Y66CeAUffeJ_gnj}+nLM-yX|N6xX0g5JsxZ;^Tl;*^d#?Vx4!TC zp2Z+AtEJZBbazmYn1Gr=^qN;sYouDYeiuDk)5BL2p_?$wf`SsV|b+ znwsBlSE*Fdk5^D=5peorExIXlSH!NWwOj|@{#$T6lYOqXuEVz5*7db}=P+iNN^AKA zJwI=seZMN)i7Drk>0(EJ#xL#3={>HmJ1ji!KCED>IQuuMV*$faRtDGNWSwIX3|sml uQg3hH_=Vx$>SvohGwU5V6kC4mR6ly!qtJBK(;q;`GkCiCxvXPx#xJg7oR9J=W(Y*@7Fc84;e?`#6u|q$mJd-Ypv(F%ig9z?!ItgNy<`o2eiFW83 z=mWUu6ep!BVg?7n`z@D)OYV+<5JCv??*gBq)pqAP?G^y1^M%oH@b;e0jO+KhUhe`l ze2SD(gmFR`Cn%-RnQ=NZ?zu5QUX%~{CrzKCQ<@=A@jh+eMBzu~hGl;8eW*CeHDKw~FhnR@-9{YjZy2vvPNTH#KJF zPh(S1Qd-25d%b(3Ur*_!vb{E^C0;+d`{$IB`jV|~k>(n&*`l(KBwspX;J5i`;lGrb z!n@|_-^dMPWmvPl`lFr0%B*is4g3tQc}CTjF?{$j^E=}`c7}$at9$!R!@n`UbYK2> i;g2kCLBWgmyBS|+_+S1T-}eLPUPx#vq?ljR9J=W(yv3&(tmzXP-e32NB%ebP~ia?JEfS67A46 zkOy$lDNc zNPswweLZ+GATLUnrHRUm(p7a6(l$K6>2PE*n<#+keCdp_XdU?=09D=a>G0qHaNoKe zV2s5W3xL*chw00000NkvXXu0mjfM%HMU literal 0 HcmV?d00001 diff --git a/Resources/Textures/CrystallPunk/Objects/keys.rsi/keyring.png b/Resources/Textures/CrystallPunk/Objects/keys.rsi/keyring.png new file mode 100644 index 0000000000000000000000000000000000000000..d9632909897e7857e83cc45dc9a87d801b5220f7 GIT binary patch literal 225 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}vproLLn2z= zUQy&bWFXT1kza4aTb7oBg|l{XiA>sglePOXp9PQl;=7z}N{Sm=-d^N9^k04Um#@a_ z6+XQeo92D{?ml*nQ(bzlU7MI5l-SI8=3Dni@IzIc`P^s%T*?3d literal 0 HcmV?d00001 diff --git a/Resources/Textures/CrystallPunk/Objects/keys.rsi/lock.png b/Resources/Textures/CrystallPunk/Objects/keys.rsi/lock.png new file mode 100644 index 0000000000000000000000000000000000000000..f5da11ad68e90c7dc14b7ca69754d1fa3001f962 GIT binary patch literal 332 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^TFU3qUM>IaQ&S#kCD+Ni>LE# zD*d_&ff_`XG>USI8?K4i(Gl~uz@bb}KtyoqjUqNSE~f)`Z%=lN^6Pte>gj3`%Z5co z4({Qzl}<}aoY3eJzVzu|vUi97Je%|ggKVLb&nAX8sV;f?*Iius_@_VvF1Ldk2|&QW ZkdWl`ZS`D#7GUr&c)I$ztaD0e0ss;gf;j*H literal 0 HcmV?d00001 diff --git a/Resources/Textures/CrystallPunk/Objects/keys.rsi/lockpick.png b/Resources/Textures/CrystallPunk/Objects/keys.rsi/lockpick.png new file mode 100644 index 0000000000000000000000000000000000000000..09bc94a0e1adcb6f14d336d983cb1e7e7f3d5abf GIT binary patch literal 255 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}J3U<-Ln2y} z6C_v{Cy4Yk1sZU<9b{m3ixD~BPndMF+ON-YzKt1pn%Pw<(rqeOF|Yl=R%8ygqjS*$p{gXZ=56!jqA? z%BaK3(|AwaH<8u07P1$D!cRtAzVh$?B?Wc})uc*XMaSfSB*u1QZw;-5D2j067evu6{1-oD!Ma$N literal 0 HcmV?d00001 diff --git a/Resources/Textures/CrystallPunk/Objects/keys.rsi/ring-2.png b/Resources/Textures/CrystallPunk/Objects/keys.rsi/ring-2.png new file mode 100644 index 0000000000000000000000000000000000000000..22bed39b4229071cfed91616c5e82617dde66b18 GIT binary patch literal 223 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Gd*1#Ln2y} z6C_v{Cy4Yk1sZU7P4AOF87 z>&lg&=q`Nb(Dn24f@GLdGS_8h{a?RyWtWoMI%khQrWx-i>Ml_c@hD^1lzM&L{blt^ zE`9}3vsUq#`o2w3ci1FT@b*`(NSSx6YOOQFT_-Q+1|@?9)A~V9XyavIIBscdU+KE; QC(w}$p00i_>zopr0EzZb8UO$Q literal 0 HcmV?d00001 diff --git a/Resources/Textures/CrystallPunk/Objects/keys.rsi/ring-3.png b/Resources/Textures/CrystallPunk/Objects/keys.rsi/ring-3.png new file mode 100644 index 0000000000000000000000000000000000000000..289e821b5a8e7adfd866811f23a317109f27f0d5 GIT binary patch literal 261 zcmV+g0s8)lP)Px#zez+vR9J=Wk}(d#FbqW<#8o=9H$cqXAX#z~q>7P=YS2A!+kAQ>_zOAiqy zBh$@6r4sl}u_gO|+W`;+K@fz0M{x^o_eZ9&HCoY}HJa6P&ozJ|!#HICfMJ~SoFZEo z*_9OG#B+*pIvy0}mfKmyfHhh~IZt4o!uFuQ-ss`wtoeyxmoIlz?5jb_*^%>uru&KBp2tUIU=)+U8cjaPyJDaPU;cPEB*=VV?2IsKk4jv*1P zZ?A3SY%maMc^GWewWA?vqF({8HM>xbjN69I0&_jN1x1dW+jHput|dG5Cp=R5^xY-* zdj2#9bA6$Iwe)UIn+a literal 0 HcmV?d00001 diff --git a/Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/meta.json b/Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/meta.json new file mode 100644 index 0000000000..cfdbf13d6a --- /dev/null +++ b/Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/meta.json @@ -0,0 +1,46 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 48 + }, + "license": "CC-BY-SA-3.0", + "copyright": "Created by TheShuEd (Discord) for CrystallPunk14", + "states": [ + { + "name": "wood0", + "directions": 4 + }, + { + "name": "wood1", + "directions": 4 + }, + { + "name": "wood2", + "directions": 4 + }, + { + "name": "wood3", + "directions": 4 + }, + { + "name": "wood4", + "directions": 4 + }, + { + "name": "wood5", + "directions": 4 + }, + { + "name": "wood6", + "directions": 4 + }, + { + "name": "wood7", + "directions": 4 + }, + { + "name": "full" + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/wood0.png b/Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/wood0.png new file mode 100644 index 0000000000000000000000000000000000000000..7379d543e168aa901aa00f444ba45d3f1f52c7c0 GIT binary patch literal 457 zcmeAS@N?(olHy`uVBq!ia0vp^4nUm1!3HGP9xZtRq!^2X+?^QKos)S9WH)=dIEGZr zc{|6@i#bq&t^Q~dztEnBq=|YH4&UI2Q=Xe4e8K62DbvfK4l~8?ouLP+_8+bMmGT7oN#~lvcRG~Gk+j3jEFypFK+jiS-$~R_QHDhwY z&)3#wZHyU=Qp^{aOxPB%X7D(0Uyx`JTVTkb>yXS4)v)Y0!$+TjH$M40XIwAa-k)Bj z`O&3g&U0T!nFO=l^A0g9^KGcBmEZgA^<(3^cFTVAJK{3v7{eBZUYJcEeKxf2jB}EC z@a&yg)c%`$mU0QcC}n*0exrRSb5E_{+L!=GKL_sje`dbh&x-CM6oc-v3ryUX`AAaf zc{Tg75Bl>IgO2u|{3u*tBj(zb>@vzhVl|KPbAfd6;cJXV}K? bGBwPsdBz3@88XiTPp(6#O#i%Nso z1zgxfeu0g^%5z`LX6w%Np2qy5({F0g-^zL3)(hVM{=b*mZ~k*u6PdI3S%e+9GlU4> zQ^p6^pDyL(cdJyY-d+2@Qp=_%xctWZU5Rr}z5f-K`A^7$L3e>Ck+`y}zT?h(L7Pvn oYQI)DKPz`&%3$;*5}(z7{!(>^mgdSuzz}EfboFyt=akR{0Ft+s?f?J) literal 0 HcmV?d00001 diff --git a/Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/wood2.png b/Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/wood2.png new file mode 100644 index 0000000000000000000000000000000000000000..7379d543e168aa901aa00f444ba45d3f1f52c7c0 GIT binary patch literal 457 zcmeAS@N?(olHy`uVBq!ia0vp^4nUm1!3HGP9xZtRq!^2X+?^QKos)S9WH)=dIEGZr zc{|6@i#bq&t^Q~dztEnBq=|YH4&UI2Q=Xe4e8K62DbvfK4l~8?ouLP+_8+bMmGT7oN#~lvcRG~Gk+j3jEFypFK+jiS-$~R_QHDhwY z&)3#wZHyU=Qp^{aOxPB%X7D(0Uyx`JTVTkb>yXS4)v)Y0!$+TjH$M40XIwAa-k)Bj z`O&3g&U0T!nFO=l^A0g9^KGcBmEZgA^<(3^cFTVAJK{3v7{eBZUYJcEeKxf2jB}EC z@a&yg)c%`$mU0QcC}n*0exrRSb5E_{+L!=GKL_sje`dbh&x-CM6oc-v3ryUX`AAaf zc{Tg75Bl>IgO2u|{3u*tBj(zb>@vzhVl|KPbAfd6;cJXV}K? bGBwPsdBz3@88XiTPp(6#O#i%Nso z1zgxfeu0g^%5z`LX6w%Np2qy5({F0g-^zL3)(hVM{=b*mZ~k*u6PdI3S%e+9GlU4> zQ^p6^pDyL(cdJyY-d+2@Qp=_%xctWZU5Rr}z5f-K`A^7$L3e>Ck+`y}zT?h(L7Pvn oYQI)DKPz`&%3$;*5}(z7{!(>^mgdSuzz}EfboFyt=akR{0Ft+s?f?J) literal 0 HcmV?d00001 diff --git a/Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/wood4.png b/Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/wood4.png new file mode 100644 index 0000000000000000000000000000000000000000..4e2f0b9e1a0a0fb3a11de678783581762ffb7430 GIT binary patch literal 417 zcmeAS@N?(olHy`uVBq!ia0vp^4nUm1!3HGP9xZtRq!^2X+?^QKos)S9WJi0tIEGZr zd3)Q?i#brl?V-(2w*UB3_Itz1JN4m~HQXuA2)5@ z&pKv_V=Ha#ZKug#zfZ+r#~j0=rf}V%)_2q@ihclQe(Oi*@W1?k(3_!fp__FXP{K`DY(z+&q)A ziTl~puNAY8DK7u4dfB3;`p?4;d!mj0AD(pZew z1IAsf2D}ScO>p7a{2P8aJgNG-{)Z)Mo-bWD-US9bgQu&X%Q~loCIEXu BoY4RP literal 0 HcmV?d00001 diff --git a/Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/wood6.png b/Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/wood6.png new file mode 100644 index 0000000000000000000000000000000000000000..4e2f0b9e1a0a0fb3a11de678783581762ffb7430 GIT binary patch literal 417 zcmeAS@N?(olHy`uVBq!ia0vp^4nUm1!3HGP9xZtRq!^2X+?^QKos)S9WJi0tIEGZr zd3)Q?i#brl?V-(2w*UB3_Itz1JN4m~HQXuA2)5@ z&pKv_V=Ha#ZKugZ&cgvb2LhIVZh2$xe$wu(fSrxUlHHCR^UwT0p78GX@7rhQKQGOBW1il{q_5we(`D$r-6WZSfrir ozdHZpKim5I4LIC@MbBsU^Xqx`O<2+A3Jd}UPgg&ebxsLQ0Eh=}p#T5? literal 0 HcmV?d00001 diff --git a/Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/full.png b/Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/full.png new file mode 100644 index 0000000000000000000000000000000000000000..1a8030fc5510a37056536473c6b97d3414a2d378 GIT binary patch literal 1039 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 Bm)HOR literal 0 HcmV?d00001 diff --git a/Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/stone6.png b/Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/stone6.png new file mode 100644 index 0000000000000000000000000000000000000000..8fe504833c58612e2b6e35e25c368ee43252fef5 GIT binary patch literal 1176 zcmV;J1ZVq+P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D1T9HKK~#8N?VG=A z6hRnn6r#`EzVXYjmy^uS&D>oc7>k+T_CD|DXM;5CEU(EKJup^`kB|K|z>xbHLtqd<{IAuYZeKUq7=S0< zXe^hDeWScnIPtAKAe3wjfV(e#{p6P5Y%}+-gXB4Y_{aU_`gnkhAn}`dKu_d=iDO60 z-M>BJA*TC776zDq`>q%r8F6do+4J(WNlfvOMF=R{3&lRPGeA#-fa*PH|9f@CT_IKp zgyaVJ{NVtGL}jZiCSihBNK$oBohe;H)z9I5Kg{38+GGtD25T zCANiyX1^aQAe3k!(5`+@ojp_T(h|)8tunW={NmD5d6Jf>ApjVG5Rm)J^&z$ULy{_> zPOqKuIzdze_#vRi25i@tlBfny5~P$-+NkTQ0_1@li0%P?C9th-4n+3=B|(AkT*O1i zlAt<0wYOY*z6$syP}#o|J^ud^%>cf5LH5_@ubwW0o3+7q44#^(9w4ay%KoYV@`BVv ze;ZU7R0+-@5q7K!_~eoZgRRd%L!)iq8+f`JcvStF9LiwuKfnsY&Fx3ds;6u#0&j+0 z9|DSPD<0UZ?h88vIWc*BgE3N3g8_!tg(1p9#gXYVNi3lGFsd-;JAh*ASyY z$MtJh-Sykj_w_Hm8gi;BlJFd=Ky5j|iWGLbEByOPj;RR#%a!HzIorPZ>CEEaU-03uklzAT=wJpe8AWrTOs0@dyhBW7Jm1KqYwyAfn2xIU@v^ zDk0cH$nXo4e&}q4EIa@sFjw3^vadWXiu(^9mb)fatPPp24*_xjag7n=*18IbugVpn z21p(Ph>|<&KTAnGXI8w*q41~BTOqjzFjTef-3knVXQ%>b>KvK`vkC!g2nnV_&@5R` zu%Yr|=1F%OKuJ)d5Q<1Y*7e=N_m-}I7qH?5KT9wlQM4C$3=2brl0_>l@p`&Siu%Bc qK|uF8vjz(xiyTmHw?tS76vZEac3-VLXk=6X0000Yp>)L-??sC+Af-{$#5-*Va-y82yey>)0h%;Sr0^UHEi{H z&-}0M{P{~9FaZ$;94e6|y6qhPvm%*-EO$ym-#L}1ZruxyD4 Date: Wed, 3 Apr 2024 00:48:08 +0300 Subject: [PATCH 2/7] =?UTF-8?q?=D0=9A=D0=9E=D0=A1=D0=A2=D0=81=D0=A0=20(#22?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * респрайт костра, новый костёр * fix itemheating * этот костер потребовал слишком много работы * перекрас травы --- .../Atmos/Components/FlammableComponent.cs | 13 +++ .../Atmos/EntitySystems/FlammableSystem.cs | 22 +++++ Content.Server/Audio/AmbientSoundSystem.cs | 9 +++ .../Temperature/Systems/EntityHeaterSystem.cs | 17 ++++ .../LockKey/KeyholeGenerationSystem.cs | 0 .../StationBiome/StationBiomeComponent.cs | 0 .../StationBiome/StationBiomeSystem.cs | 0 .../CPFlammableAmbientSoundComponent.cs | 20 +++++ .../CPFlammableEntityHeaterComponent.cs | 11 +++ .../Structures/Decoration/bonfire.yml | 2 + .../Structures/Decoration/bonfire.yml | 75 ++++++++++++++++++ .../Decoration/bonfire.rsi/bonfire.png | Bin 0 -> 936 bytes .../bonfire.rsi/bonfire_extinguished.png | Bin 0 -> 1245 bytes .../Decoration/bonfire.rsi/burning.png | Bin 0 -> 4635 bytes .../Decoration/bonfire.rsi/meta.json | 27 +++++++ .../CrystallPunk/Tiles/Grass/double_edge.png | Bin 745 -> 740 bytes .../CrystallPunk/Tiles/Grass/grass.png | Bin 6334 -> 6163 bytes .../CrystallPunk/Tiles/Grass/single_edge.png | Bin 590 -> 588 bytes .../CrystallPunk/Tiles/Grass/triple_edge.png | Bin 1211 -> 1195 bytes 19 files changed, 196 insertions(+) rename Content.Server/{CrystallPunk => _CP14}/LockKey/KeyholeGenerationSystem.cs (100%) rename Content.Server/{CrystallPunk => _CP14}/StationBiome/StationBiomeComponent.cs (100%) rename Content.Server/{CrystallPunk => _CP14}/StationBiome/StationBiomeSystem.cs (100%) create mode 100644 Content.Server/_CP14/Temperature/CPFlammableAmbientSoundComponent.cs create mode 100644 Content.Server/_CP14/Temperature/CPFlammableEntityHeaterComponent.cs create mode 100644 Resources/Prototypes/_CP14/Entities/Structures/Decoration/bonfire.yml create mode 100644 Resources/Textures/CrystallPunk/Structures/Decoration/bonfire.rsi/bonfire.png create mode 100644 Resources/Textures/CrystallPunk/Structures/Decoration/bonfire.rsi/bonfire_extinguished.png create mode 100644 Resources/Textures/CrystallPunk/Structures/Decoration/bonfire.rsi/burning.png create mode 100644 Resources/Textures/CrystallPunk/Structures/Decoration/bonfire.rsi/meta.json diff --git a/Content.Server/Atmos/Components/FlammableComponent.cs b/Content.Server/Atmos/Components/FlammableComponent.cs index 679b551058..49da56563b 100644 --- a/Content.Server/Atmos/Components/FlammableComponent.cs +++ b/Content.Server/Atmos/Components/FlammableComponent.cs @@ -61,5 +61,18 @@ namespace Content.Server.Atmos.Components /// [DataField, ViewVariables(VVAccess.ReadWrite)] public float FirestackFade = -0.1f; + + /// + /// Set FirestackFade on Ingite to this value + /// + [DataField] + public float? FirestackFadeOnIgnite = null; + + /// + /// CrystallPunk moment + /// determines how extinction "FirestackFade" will fade out. it can be used to make "parabolas" of object ignition and decay. + /// + [DataField] + public float FirestackFadeFade = 0; } } diff --git a/Content.Server/Atmos/EntitySystems/FlammableSystem.cs b/Content.Server/Atmos/EntitySystems/FlammableSystem.cs index 53fcb72076..267daff089 100644 --- a/Content.Server/Atmos/EntitySystems/FlammableSystem.cs +++ b/Content.Server/Atmos/EntitySystems/FlammableSystem.cs @@ -27,6 +27,7 @@ using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Events; using Robust.Shared.Physics.Systems; using Robust.Shared.Random; +using Content.Server.CrystallPunk.Temperature; namespace Content.Server.Atmos.EntitySystems { @@ -296,6 +297,12 @@ namespace Content.Server.Atmos.EntitySystems _ignitionSourceSystem.SetIgnited(uid, false); + + //CrystallPunk bonfire moment + var ev = new OnFireChangedEvent(flammable.OnFire); + RaiseLocalEvent(uid, ref ev); + //CrystallPunk bonfire moment end + UpdateAppearance(uid, flammable); } @@ -317,9 +324,19 @@ namespace Content.Server.Atmos.EntitySystems else _adminLogger.Add(LogType.Flammable, $"{ToPrettyString(uid):target} set on fire by {ToPrettyString(ignitionSource):actor}"); flammable.OnFire = true; + + //CrystallPunk bonfire moment + var ev = new OnFireChangedEvent(flammable.OnFire); + RaiseLocalEvent(uid, ref ev); + //CrystallPunk bonfire moment end } UpdateAppearance(uid, flammable); + + //CrystallPunk bonfire moment + if (flammable.FirestackFadeOnIgnite != null) + flammable.FirestackFade = flammable.FirestackFadeOnIgnite.Value; + //CrystallPunk bonfire moment end } private void OnDamageChanged(EntityUid uid, IgniteOnHeatDamageComponent component, DamageChangedEvent args) @@ -434,6 +451,11 @@ namespace Content.Server.Atmos.EntitySystems _damageableSystem.TryChangeDamage(uid, flammable.Damage * damageScale, interruptsDoAfters: false); AdjustFireStacks(uid, flammable.FirestackFade * (flammable.Resisting ? 10f : 1f), flammable); + + //CrystallPunk bonfire moment + if (flammable.FirestackFadeFade != 0) + flammable.FirestackFade += flammable.FirestackFadeFade * frameTime; + //CrystallPunk bonfire moment end } else { diff --git a/Content.Server/Audio/AmbientSoundSystem.cs b/Content.Server/Audio/AmbientSoundSystem.cs index 53a03be2aa..b8cabbef41 100644 --- a/Content.Server/Audio/AmbientSoundSystem.cs +++ b/Content.Server/Audio/AmbientSoundSystem.cs @@ -1,3 +1,4 @@ +using Content.Server.CrystallPunk.Temperature; using Content.Server.Power.Components; using Content.Server.Power.EntitySystems; using Content.Shared.Audio; @@ -11,6 +12,7 @@ public sealed class AmbientSoundSystem : SharedAmbientSoundSystem base.Initialize(); SubscribeLocalEvent(HandlePowerChange); SubscribeLocalEvent(HandlePowerSupply); + SubscribeLocalEvent(OnFireChanged); //CrystallPunk bonfire moment } private void HandlePowerSupply(EntityUid uid, AmbientOnPoweredComponent component, ref PowerNetBatterySupplyEvent args) @@ -22,4 +24,11 @@ public sealed class AmbientSoundSystem : SharedAmbientSoundSystem { SetAmbience(uid, args.Powered); } + + //CrystallPunk bonfire moment + private void OnFireChanged(Entity ent, ref OnFireChangedEvent args) + { + SetAmbience(ent, args.OnFire); + } + //CrystallPunk bonfire moment end } diff --git a/Content.Server/Temperature/Systems/EntityHeaterSystem.cs b/Content.Server/Temperature/Systems/EntityHeaterSystem.cs index 6da774ba07..78323198fc 100644 --- a/Content.Server/Temperature/Systems/EntityHeaterSystem.cs +++ b/Content.Server/Temperature/Systems/EntityHeaterSystem.cs @@ -1,3 +1,5 @@ +using Content.Server.Atmos.Components; +using Content.Server.CrystallPunk.Temperature; using Content.Server.Power.Components; using Content.Server.Temperature.Components; using Content.Shared.Examine; @@ -45,6 +47,21 @@ public sealed class EntityHeaterSystem : EntitySystem _temperature.ChangeHeat(ent, energy); } } + + //CrystallPunk bonfire + var flammbaleQuery = EntityQueryEnumerator(); + while (flammbaleQuery.MoveNext(out var uid, out _, out var placer, out var flammable)) + { + if (!flammable.OnFire) + return; + + var energy = flammable.FireStacks * deltaTime * 300; + foreach (var ent in placer.PlacedEntities) + { + _temperature.ChangeHeat(ent, energy); + } + } + //CrystallPunk bonfire end } private void OnExamined(EntityUid uid, EntityHeaterComponent comp, ExaminedEvent args) diff --git a/Content.Server/CrystallPunk/LockKey/KeyholeGenerationSystem.cs b/Content.Server/_CP14/LockKey/KeyholeGenerationSystem.cs similarity index 100% rename from Content.Server/CrystallPunk/LockKey/KeyholeGenerationSystem.cs rename to Content.Server/_CP14/LockKey/KeyholeGenerationSystem.cs diff --git a/Content.Server/CrystallPunk/StationBiome/StationBiomeComponent.cs b/Content.Server/_CP14/StationBiome/StationBiomeComponent.cs similarity index 100% rename from Content.Server/CrystallPunk/StationBiome/StationBiomeComponent.cs rename to Content.Server/_CP14/StationBiome/StationBiomeComponent.cs diff --git a/Content.Server/CrystallPunk/StationBiome/StationBiomeSystem.cs b/Content.Server/_CP14/StationBiome/StationBiomeSystem.cs similarity index 100% rename from Content.Server/CrystallPunk/StationBiome/StationBiomeSystem.cs rename to Content.Server/_CP14/StationBiome/StationBiomeSystem.cs diff --git a/Content.Server/_CP14/Temperature/CPFlammableAmbientSoundComponent.cs b/Content.Server/_CP14/Temperature/CPFlammableAmbientSoundComponent.cs new file mode 100644 index 0000000000..aa04a35172 --- /dev/null +++ b/Content.Server/_CP14/Temperature/CPFlammableAmbientSoundComponent.cs @@ -0,0 +1,20 @@ +using Content.Server.Temperature.Systems; + +namespace Content.Server.CrystallPunk.Temperature; + +/// +/// CTurn on and turn off AmbientSound when Flammable OnFire os changed +/// +[RegisterComponent, Access(typeof(EntityHeaterSystem))] +public sealed partial class CPFlammableAmbientSoundComponent : Component +{ +} + +/// +/// Raised whenever an FlammableComponen OnFire is Changed +/// +[ByRefEvent] +public readonly record struct OnFireChangedEvent(bool OnFire) +{ + public readonly bool OnFire = OnFire; +} diff --git a/Content.Server/_CP14/Temperature/CPFlammableEntityHeaterComponent.cs b/Content.Server/_CP14/Temperature/CPFlammableEntityHeaterComponent.cs new file mode 100644 index 0000000000..84ece0aff5 --- /dev/null +++ b/Content.Server/_CP14/Temperature/CPFlammableEntityHeaterComponent.cs @@ -0,0 +1,11 @@ +using Content.Server.Temperature.Systems; + +namespace Content.Server.CrystallPunk.Temperature; + +/// +/// Adds thermal energy from FlammableComponent to entities with placed on it. +/// +[RegisterComponent, Access(typeof(EntityHeaterSystem))] +public sealed partial class CPFlammableEntityHeaterComponent : Component +{ +} diff --git a/Resources/Prototypes/Entities/Structures/Decoration/bonfire.yml b/Resources/Prototypes/Entities/Structures/Decoration/bonfire.yml index f82fe8b51b..d46e992f8a 100644 --- a/Resources/Prototypes/Entities/Structures/Decoration/bonfire.yml +++ b/Resources/Prototypes/Entities/Structures/Decoration/bonfire.yml @@ -1,5 +1,6 @@ - type: entity id: Bonfire + noSpawn: true parent: BaseStructure name: bonfire description: What can be better then late evening under the sky with guitar and friends. @@ -37,6 +38,7 @@ - type: entity id: LegionnaireBonfire + noSpawn: true parent: Bonfire name: legionnaire bonfire description: There, in the land of lava and ash, place to to cook marshmallow and potato. diff --git a/Resources/Prototypes/_CP14/Entities/Structures/Decoration/bonfire.yml b/Resources/Prototypes/_CP14/Entities/Structures/Decoration/bonfire.yml new file mode 100644 index 0000000000..63c85d7436 --- /dev/null +++ b/Resources/Prototypes/_CP14/Entities/Structures/Decoration/bonfire.yml @@ -0,0 +1,75 @@ +- type: entity + id: CPBonfire + parent: BaseStructure + name: костёр + description: Груда бревен, сложенных вместе, и готовых вспыхнуть от малейшей искры. + components: + - type: Sprite + noRot: true + sprite: CrystallPunk/Structures/Decoration/bonfire.rsi + layers: + - state: bonfire + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeAabb + bounds: "-0.08,-0.35,0.15,0.25" + mask: + - TabletopMachineMask + layer: + - Impassable + - MidImpassable + - LowImpassable + hard: true + - type: Damageable + damageContainer: Inorganic + damageModifierSet: Wood + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 80 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - trigger: + !type:DamageTypeTrigger + damageType: Heat + damage: 50 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - type: CPFlammableAmbientSound + - type: AmbientSound + enabled: false + volume: -5 + range: 5 + sound: + path: /Audio/Ambience/Objects/fireplace.ogg + - type: Appearance + - type: Reactive + groups: + Flammable: [ Touch ] + Extinguish: [ Touch ] + - type: Flammable + fireSpread: false + canResistFire: false + alwaysCombustible: true + canExtinguish: true + firestacksOnIgnite: 0.5 + firestackFade: 0.3 + firestackFadeOnIgnite: 0.3 + firestackFadeFade: -0.2 + damage: + types: + Heat: 0.01 + - type: FireVisuals + sprite: CrystallPunk/Structures/Decoration/bonfire.rsi + normalState: burning + - type: ItemPlacer + maxEntities: 4 + whitelist: + components: + - Temperature + - type: CPFlammableEntityHeater \ No newline at end of file diff --git a/Resources/Textures/CrystallPunk/Structures/Decoration/bonfire.rsi/bonfire.png b/Resources/Textures/CrystallPunk/Structures/Decoration/bonfire.rsi/bonfire.png new file mode 100644 index 0000000000000000000000000000000000000000..a34ec61a1c54fed44cf11f80330b7f3df3efa1ac GIT binary patch literal 936 zcmV;Z16TZsP)Px&Vo5|nR9J=WR=;c8KotILiWZ?EgKXqL@S+a&KVUj#>=f*&q(eItVKNl*V=;zK zAx03AhGqysWbhIQ8Eiad^i&KT3IP{VFQ!l%`-Tj{ixziq-u2x{iM=-uj8CU`@B7~S z-rWg!wrBg_E!F9C7CIeOwq^jZcYc;y2I0G9@Y9$F@uaej8qOV`*?;2?>rWTQdT#9eZ$A*YN4>XSj|50O*e* zWh_aD)1_ok2=L7I&d*Xum91IrU=xAg1^{@~4cM710O0ztA;H%_ya51o8aE0NPC}1O zV<`b?4FEgd2?(43z3PS}0syC1`?&q_9f9A*I-tBGvn^8sKh_^lhH>RQ_mQ?~T|lAZ>xUmZfqYU$^&_W+S7Xpj`q0rE(sv=0N(qez^hw`1b1_ zKzs|wBp`6tF;FV!(d!N+c%hh+Rd5{xoyN_)tPg#{tx(LtdtZ?8h={(0(==&YCS1pm zSr&@9SWq%?cPl$z+}+~(u%Wzn9RscA0KM)|Ns9VG=>ZPjA4Rh40A%($pz%+tCL96q@JlBoSu8#p#Q!nTQlK}Os zc`O>!ox(|^f%z8UTaFG69*79)37iNI~klmM;fAhw9+iP&RRAwXUQ znxmMq2lyhYhTaR@k}ANTX)S55n+PL_FhY7hn99YZ6A|P6K|ysgWQAf*Sx+PZwPFD9 zD!1~l0wRp?b9gVE`5B1bl2)3nu>*+m0@ANrt zR0S?E$9wXlwEFJj%(e_Aqa-k$7|)){tphJbfJi*)u)vZ)x%~zEf@Q}K+Dxth0000< KMNUMnLSTYU?5kb? literal 0 HcmV?d00001 diff --git a/Resources/Textures/CrystallPunk/Structures/Decoration/bonfire.rsi/bonfire_extinguished.png b/Resources/Textures/CrystallPunk/Structures/Decoration/bonfire.rsi/bonfire_extinguished.png new file mode 100644 index 0000000000000000000000000000000000000000..3a5d39a209b7b2d1861d228165b853023e56c370 GIT binary patch literal 1245 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 LNkvXXu0mjf^$D4b delta 318 zcmV-E0m1&{1?dH_wE=%0NklO$_k;eg(jCeKcC#uXBCV0vO-EX<1A~dbk(W#zcQk5sF64w1-A7><0eG z*A0B!Q_ZJxy0%;&=_<}Hq5syLC%~esLdt!f>RZZ|y7B(ui*lc*)4XVPU54nI_?P=U zl|1nK1k&{J_+}Q7SZc3_>(Nj#oz}Z5G|NnHEuL8s@AQ)lAo29mwbgbr$f@&l z`g8f!b~89?3E?({F$tHU^>e;SR>ZsKyU*0&Z@BbQ7K_DVu~;k?i{&5l1A#rPf_QWn QLjV8(07*qoM6N<$f?>R(2><{9 diff --git a/Resources/Textures/CrystallPunk/Tiles/Grass/grass.png b/Resources/Textures/CrystallPunk/Tiles/Grass/grass.png index 0a7d319e3c5685a56c446192f662146e5c1c492d..b0bbe82face373a545ff106294a412a7d3647f0f 100644 GIT binary patch delta 5713 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 D@U(a8 delta 5903 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 Qr~m)}07*qoM6N<$f*xN?q5uE@ diff --git a/Resources/Textures/CrystallPunk/Tiles/Grass/triple_edge.png b/Resources/Textures/CrystallPunk/Tiles/Grass/triple_edge.png index 5f9211126b07963d75b52c7d5d5e7715ac007e23..de2355094b422d8bb8c4df8d920d86eac892f5d6 100644 GIT binary patch delta 771 zcmV+e1N{8E39AXPwE=(ONkl1^5|rw2kh z-RZvfzI(q^YK)pI0MHACPIn0an2f8qJ--S8oWYIs0if1vMfQJ$PjD4zOvY6JAh=T* zOzRP_#AIBB3N(mYYK)pIy->SAU0DyT82~mcq;UejQidnN8>42FY3f|g)|bKZD`li{ zf>N#5S^2Tm$-UYvKG(L1YQW7Ld}j}qsOIGENWS&p~*0anBLa26I(6HZUAL%SB3j>wKpe&7JtP;WDk zivkXA&#!;NTCWw!#DNF;1NR{Vq@JN~+H#7WmIu>%^iVcvJq=__t^$p{gQqV)N$~k_ z7CwIcqRlIK^#}L+hwWcqzg^aPt?1+DgZBT%@zL}4k1yXZYrR(V?8B4x-OoL|dmH0^ z|F8`J-u@l{z<-o(G9fKz+e`)~r@MQ^uCZPyG)Bz`0FIBcn3qSe^UsJ1 zNP6t%!4`R3%=Q0T&pCppakA|LwgMd6pmOalr6d>uZN<_!$$rhanE6>Qus5>j&3A+ifwE=(eNkl$im3VG@71TCF>& z31ETor~=E0K)5CinDwSAs4n&ZfRp2k003OSB9hR?Y8k^U14a_sl5xH7iPTf=HrQMe z%Pg0$TE-~2erpW?mJ_Ke=v1IX4cBjp|5*a9@)K~gy};RJBx4Q$40VuhV6yq}G@u{{ zwt+8~fCg=v+7*Amo>a7)C{@66B3Mq8s{$O9$ACc%z7c^1jZPziNodP=26+RdxtdcN zb^vgK0N4_&mT|_392`J*QWIyF_auAENwXmngyiAIiCp%9dfyY20ZC}XAof%Xa#BE& zAqD7enB|i6MkzwN0SYAui_A~iSZ z0}Z%RdR2dcOcv0?e0UnTeoOF;12>EZnuio1=_&OK^}e^}?A2|#JE@7AszL0DV0t7^ zQ~%c8N6+7J@L6vfJb3oBL6>vz6W7JV#*dGm&RxGH-oC%n_}6n>J!pKJemQsjmU#T; zVdL}n5?;OditFNG0|1QMMF4<#|Mzw$B<6H%CIx@Sqlzrkbg(2Q&GrKOo|DiR{olq@AAzry@oo&L4$!j-%E#_=ih~iL>ey-- zr@v-2nD%ErK%GeK Date: Wed, 3 Apr 2024 10:01:57 +0300 Subject: [PATCH 3/7] =?UTF-8?q?=D0=BF=D1=80=D0=BE=D1=88=D1=83,=20=D0=B1?= =?UTF-8?q?=D0=BE=D0=B6=D0=B5,=20=D0=BD=D0=B0=D0=B4=D0=B5=D1=8E=D1=81?= =?UTF-8?q?=D1=8C=20=D1=8F=20=D0=BD=D0=B5=20=D0=BD=D0=B0=D0=BA=D0=BE=D1=81?= =?UTF-8?q?=D1=8F=D1=87=D0=B8=D0=BB=20=D1=81=20=D1=80=D0=B5=D1=86=D0=B5?= =?UTF-8?q?=D0=BF=D1=82=D0=B0=D0=BC=D0=B8=20(#23)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * прошу, боже, надеюсь я не накосячил с рецептами * Update structures.yml * Update structures.yml * blessed git * huh * meh --- .../UI/ConstructionMenuPresenter.cs | 3 + .../Prototypes/ConstructionPrototype.cs | 8 +- .../Recipes/Construction/clothing.yml | 196 +- .../Prototypes/Recipes/Construction/fun.yml | 20 +- .../Recipes/Construction/furniture.yml | 1770 ++++----- .../Recipes/Construction/lighting.yml | 130 +- .../Recipes/Construction/machines.yml | 250 +- .../Recipes/Construction/materials.yml | 242 +- .../Recipes/Construction/modular.yml | 26 +- .../Recipes/Construction/storage.yml | 100 +- .../Recipes/Construction/structures.yml | 3164 ++++++++--------- .../Prototypes/Recipes/Construction/tools.yml | 86 +- .../Recipes/Construction/utilities.yml | 1720 ++++----- .../Recipes/Construction/weapons.yml | 326 +- .../Prototypes/Recipes/Construction/web.yml | 238 +- .../Prototypes/Recipes/Crafting/artifact.yml | 24 +- .../Prototypes/Recipes/Crafting/bots.yml | 128 +- .../Prototypes/Recipes/Crafting/crates.yml | 152 +- .../Recipes/Crafting/improvised.yml | 484 +-- .../Prototypes/Recipes/Crafting/potato.yml | 64 +- .../Recipes/Crafting/smokeables.yml | 110 +- .../Prototypes/Recipes/Crafting/tallbox.yml | 74 +- .../Prototypes/Recipes/Crafting/tiles.yml | 172 +- .../Prototypes/Recipes/Crafting/toys.yml | 50 +- Resources/Prototypes/Recipes/Crafting/web.yml | 222 +- .../Prototypes/Recipes/Lathes/electronics.yml | 4 +- .../Structures/Decoration/bonfire.yml | 3 + .../Entities/Structures/Furniture/chairs.yml | 5 +- .../Entities/Structures/Furniture/tables.yml | 5 +- .../Construction/Graphs/Furniture/bonfire.yml | 16 + .../Construction/Graphs/Furniture/seats.yml | 16 + .../Construction/Graphs/Furniture/tables.yml | 16 + .../_CP14/Recipes/Construction/furniture.yml | 53 + 33 files changed, 4997 insertions(+), 4880 deletions(-) create mode 100644 Resources/Prototypes/_CP14/Recipes/Construction/Graphs/Furniture/bonfire.yml create mode 100644 Resources/Prototypes/_CP14/Recipes/Construction/Graphs/Furniture/seats.yml create mode 100644 Resources/Prototypes/_CP14/Recipes/Construction/Graphs/Furniture/tables.yml create mode 100644 Resources/Prototypes/_CP14/Recipes/Construction/furniture.yml diff --git a/Content.Client/Construction/UI/ConstructionMenuPresenter.cs b/Content.Client/Construction/UI/ConstructionMenuPresenter.cs index 9a09436176..c96501fa65 100644 --- a/Content.Client/Construction/UI/ConstructionMenuPresenter.cs +++ b/Content.Client/Construction/UI/ConstructionMenuPresenter.cs @@ -155,6 +155,9 @@ namespace Content.Client.Construction.UI if (recipe.Hide) continue; + if (!recipe.CrystallPunkAllowed) //CrystallPunk clearing recipes + continue; + if (_playerManager.LocalSession == null || _playerManager.LocalEntity == null || (recipe.EntityWhitelist != null && !recipe.EntityWhitelist.IsValid(_playerManager.LocalEntity.Value))) diff --git a/Content.Shared/Construction/Prototypes/ConstructionPrototype.cs b/Content.Shared/Construction/Prototypes/ConstructionPrototype.cs index e9863f8364..511d84de80 100644 --- a/Content.Shared/Construction/Prototypes/ConstructionPrototype.cs +++ b/Content.Shared/Construction/Prototypes/ConstructionPrototype.cs @@ -1,4 +1,4 @@ -using Content.Shared.Construction.Conditions; +using Content.Shared.Construction.Conditions; using Content.Shared.Whitelist; using Robust.Shared.Prototypes; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; @@ -97,6 +97,12 @@ public sealed partial class ConstructionPrototype : IPrototype public IReadOnlyList Conditions => _conditions; public IReadOnlyList Layers => _layers ?? new List { Icon }; + + /// + /// allows you to display to players only the recipes needed for the project + /// + [DataField] + public bool CrystallPunkAllowed = false; } public enum ConstructionType diff --git a/Resources/Prototypes/Recipes/Construction/clothing.yml b/Resources/Prototypes/Recipes/Construction/clothing.yml index d383339e1a..89f22cdf30 100644 --- a/Resources/Prototypes/Recipes/Construction/clothing.yml +++ b/Resources/Prototypes/Recipes/Construction/clothing.yml @@ -1,98 +1,98 @@ -#- type: construction -# name: clown hardsuit -# id: ClownHardsuit -# graph: ClownHardsuit -# startNode: start -# targetNode: clownHardsuit -# category: construction-category-clothing -# description: A modified hardsuit fit for a clown. -# icon: { sprite: Clothing/OuterClothing/Hardsuits/clown.rsi, state: icon } -# objectType: Item -# -#- type: construction -# name: mime hardsuit -# id: MimeHardsuit -# graph: MimeHardsuit -# startNode: start -# targetNode: mimeHardsuit -# category: construction-category-clothing -# description: A modified hardsuit fit for a mime. -# icon: { sprite: Clothing/OuterClothing/Hardsuits/mime.rsi, state: icon } -# objectType: Item -# -#- type: construction -# name: bone armor -# id: BoneArmor -# graph: BoneArmor -# startNode: start -# targetNode: armor -# category: construction-category-clothing -# description: Armor made of bones. -# icon: { sprite: Clothing/OuterClothing/Armor/bone_armor.rsi, state: icon } -# objectType: Item -# -#- type: construction -# name: bone helmet -# id: BoneHelmet -# graph: BoneHelmet -# startNode: start -# targetNode: helmet -# category: construction-category-clothing -# description: Helmet made of bones. -# icon: { sprite: Clothing/Head/Helmets/bone_helmet.rsi, state: icon } -# objectType: Item -# -#- type: construction -# name: banana clown mask -# id: BananaClownMask -# graph: BananaClownMask -# startNode: start -# targetNode: mask -# category: construction-category-clothing -# description: A clown mask upgraded with banana peels. -# icon: { sprite: Clothing/Mask/clown_banana.rsi, state: icon } -# objectType: Item -# -#- type: construction -# name: banana clown suit -# id: BananaClownJumpsuit -# graph: BananaClownJumpsuit -# startNode: start -# targetNode: jumpsuit -# category: construction-category-clothing -# description: A clown suit upgraded with banana peels. -# icon: { sprite: Clothing/Uniforms/Jumpsuit/clown_banana.rsi, state: icon } -# objectType: Item -# -#- type: construction -# name: banana clown shoes -# id: BananaClownShoes -# graph: BananaClownShoes -# startNode: start -# targetNode: shoes -# category: construction-category-clothing -# description: A pair of clown shoes upgraded with banana peels. -# icon: { sprite: Clothing/Shoes/Specific/clown_banana.rsi, state: icon } -# objectType: Item -# -#- type: construction -# name: medsec hud -# id: ClothingEyesHudMedSec -# graph: HudMedSec -# startNode: start -# targetNode: medsecHud -# category: construction-category-clothing -# description: Two huds joined by arms -# icon: { sprite: Clothing/Eyes/Hud/medsec.rsi, state: icon } -# objectType: Item -# -#- type: construction -# name: ducky slippers -# id: ClothingShoeSlippersDuck -# graph: ClothingShoeSlippersDuck -# startNode: start -# targetNode: shoes -# category: construction-category-clothing -# description: Comfy, yet haunted by the ghosts of ducks you fed bread to as a child. -# icon: { sprite: Clothing/Shoes/Misc/duck-slippers.rsi, state: icon } -# objectType: Item +- type: construction + name: clown hardsuit + id: ClownHardsuit + graph: ClownHardsuit + startNode: start + targetNode: clownHardsuit + category: construction-category-clothing + description: A modified hardsuit fit for a clown. + icon: { sprite: Clothing/OuterClothing/Hardsuits/clown.rsi, state: icon } + objectType: Item + +- type: construction + name: mime hardsuit + id: MimeHardsuit + graph: MimeHardsuit + startNode: start + targetNode: mimeHardsuit + category: construction-category-clothing + description: A modified hardsuit fit for a mime. + icon: { sprite: Clothing/OuterClothing/Hardsuits/mime.rsi, state: icon } + objectType: Item + +- type: construction + name: bone armor + id: BoneArmor + graph: BoneArmor + startNode: start + targetNode: armor + category: construction-category-clothing + description: Armor made of bones. + icon: { sprite: Clothing/OuterClothing/Armor/bone_armor.rsi, state: icon } + objectType: Item + +- type: construction + name: bone helmet + id: BoneHelmet + graph: BoneHelmet + startNode: start + targetNode: helmet + category: construction-category-clothing + description: Helmet made of bones. + icon: { sprite: Clothing/Head/Helmets/bone_helmet.rsi, state: icon } + objectType: Item + +- type: construction + name: banana clown mask + id: BananaClownMask + graph: BananaClownMask + startNode: start + targetNode: mask + category: construction-category-clothing + description: A clown mask upgraded with banana peels. + icon: { sprite: Clothing/Mask/clown_banana.rsi, state: icon } + objectType: Item + +- type: construction + name: banana clown suit + id: BananaClownJumpsuit + graph: BananaClownJumpsuit + startNode: start + targetNode: jumpsuit + category: construction-category-clothing + description: A clown suit upgraded with banana peels. + icon: { sprite: Clothing/Uniforms/Jumpsuit/clown_banana.rsi, state: icon } + objectType: Item + +- type: construction + name: banana clown shoes + id: BananaClownShoes + graph: BananaClownShoes + startNode: start + targetNode: shoes + category: construction-category-clothing + description: A pair of clown shoes upgraded with banana peels. + icon: { sprite: Clothing/Shoes/Specific/clown_banana.rsi, state: icon } + objectType: Item + +- type: construction + name: medsec hud + id: ClothingEyesHudMedSec + graph: HudMedSec + startNode: start + targetNode: medsecHud + category: construction-category-clothing + description: Two huds joined by arms + icon: { sprite: Clothing/Eyes/Hud/medsec.rsi, state: icon } + objectType: Item + +- type: construction + name: ducky slippers + id: ClothingShoeSlippersDuck + graph: ClothingShoeSlippersDuck + startNode: start + targetNode: shoes + category: construction-category-clothing + description: Comfy, yet haunted by the ghosts of ducks you fed bread to as a child. + icon: { sprite: Clothing/Shoes/Misc/duck-slippers.rsi, state: icon } + objectType: Item diff --git a/Resources/Prototypes/Recipes/Construction/fun.yml b/Resources/Prototypes/Recipes/Construction/fun.yml index 066a623d0e..46d43e7372 100644 --- a/Resources/Prototypes/Recipes/Construction/fun.yml +++ b/Resources/Prototypes/Recipes/Construction/fun.yml @@ -1,10 +1,10 @@ -#- type: construction -# name: bananium horn -# id: HornBananium -# graph: BananiumHorn -# startNode: start -# targetNode: bananiumHorn -# category: construction-category-weapons -# description: An air horn made from bananium. -# icon: { sprite: Objects/Fun/bananiumhorn.rsi, state: icon } -# objectType: Item +- type: construction + name: bananium horn + id: HornBananium + graph: BananiumHorn + startNode: start + targetNode: bananiumHorn + category: construction-category-weapons + description: An air horn made from bananium. + icon: { sprite: Objects/Fun/bananiumhorn.rsi, state: icon } + objectType: Item diff --git a/Resources/Prototypes/Recipes/Construction/furniture.yml b/Resources/Prototypes/Recipes/Construction/furniture.yml index bf3038dfc5..2597877187 100644 --- a/Resources/Prototypes/Recipes/Construction/furniture.yml +++ b/Resources/Prototypes/Recipes/Construction/furniture.yml @@ -1,886 +1,886 @@ #chairs -#- type: construction -# name: chair -# id: Chair -# graph: Seat -# startNode: start -# targetNode: chair -# category: construction-category-furniture -# description: You sit in this. Either by will or force. -# icon: -# sprite: Structures/Furniture/chairs.rsi -# state: chair -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: stool -# id: Stool -# graph: Seat -# startNode: start -# targetNode: stool -# category: construction-category-furniture -# description: You sit in this. Either by will or force. -# icon: -# sprite: Structures/Furniture/chairs.rsi -# state: stool -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: bar stool -# id: StoolBar -# graph: Seat -# startNode: start -# targetNode: stoolBar -# category: construction-category-furniture -# description: You sit in this. Either by will or force. -# icon: -# sprite: Structures/Furniture/chairs.rsi -# state: bar -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: brass chair -# id: ChairBrass -# graph: Seat -# startNode: start -# targetNode: chairBrass -# category: construction-category-furniture -# description: You sit in this. Either by will or force. -# icon: -# sprite: Structures/Furniture/chairs.rsi -# state: brass_chair -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: office chair -# id: ChairOfficeLight -# graph: Seat -# startNode: start -# targetNode: chairOffice -# category: construction-category-furniture -# description: You sit in this. Either by will or force. -# icon: -# sprite: Structures/Furniture/chairs.rsi -# state: office-white -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: dark office chair -# id: ChairOfficeDark -# graph: Seat -# startNode: start -# targetNode: chairOfficeDark -# category: construction-category-furniture -# description: You sit in this. Either by will or force. -# icon: -# sprite: Structures/Furniture/chairs.rsi -# state: office-dark -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: comfy chair -# id: ChairComfy -# graph: Seat -# startNode: start -# targetNode: chairComfy -# category: construction-category-furniture -# description: It looks comfy. -# icon: -# sprite: Structures/Furniture/chairs.rsi -# state: comfy -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: pilots chair -# id: chairPilotSeat -# graph: Seat -# startNode: start -# targetNode: chairPilotSeat -# category: construction-category-furniture -# description: Fit for a captain. -# icon: -# sprite: Structures/Furniture/chairs.rsi -# state: shuttle -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: wooden chair -# id: ChairWood -# graph: Seat -# startNode: start -# targetNode: chairWood -# category: construction-category-furniture -# description: You sit in this. Either by will or force. -# icon: -# sprite: Structures/Furniture/chairs.rsi -# state: wooden -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: meat chair -# id: ChairMeat -# graph: Seat -# startNode: start -# targetNode: chairMeat -# category: construction-category-furniture -# description: Uncomfortably sweaty. -# icon: -# sprite: Structures/Furniture/chairs.rsi -# state: meat -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: ritual chair -# id: ChairRitual -# graph: RitualSeat -# startNode: start -# targetNode: chairRitual -# category: construction-category-furniture -# description: A strangely carved chair. -# icon: -# sprite: Structures/Furniture/chairs.rsi -# state: ritual -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: folding chair -# id: ChairFolding -# graph: Seat -# startNode: start -# targetNode: chairFolding -# category: construction-category-furniture -# description: An easy to carry chair. -# icon: -# sprite: Structures/Furniture/folding_chair.rsi -# state: folding -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: steel bench -# id: ChairSteelBench -# graph: Seat -# startNode: start -# targetNode: chairSteelBench -# category: construction-category-furniture -# description: A long chair made for a metro. Really standard design. -# icon: -# sprite: Structures/Furniture/chairs.rsi -# state: steel-bench -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: wooden bench -# id: ChairWoodBench -# graph: Seat -# startNode: start -# targetNode: chairWoodBench -# category: construction-category-furniture -# description: Did you get a splinter? Well, at least it’s eco friendly. -# icon: -# sprite: Structures/Furniture/chairs.rsi -# state: wooden-bench -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: comfortable red bench -# id: RedComfBench -# graph: Seat -# startNode: start -# targetNode: redComfBench -# category: construction-category-furniture -# description: A bench with an extremely comfortable backrest. -# icon: -# sprite: Structures/Furniture/Bench/comf_bench.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: comfortable blue bench -# id: BlueComfBench -# graph: Seat -# startNode: start -# targetNode: blueComfBench -# category: construction-category-furniture -# description: A bench with an extremely comfortable backrest. -# icon: -# sprite: Structures/Furniture/Bench/comf_bench.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -##tables -#- type: construction -# name: steel table -# id: Table -# graph: Table -# startNode: start -# targetNode: Table -# category: construction-category-furniture -# description: A square piece of metal standing on four metal legs. -# icon: -# sprite: Structures/Furniture/Tables/generic.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: reinforced steel table -# id: TableReinforced -# graph: Table -# startNode: start -# targetNode: TableReinforced -# category: construction-category-furniture -# description: A square piece of metal standing on four metal legs. Extra robust. -# icon: -# sprite: Structures/Furniture/Tables/reinforced.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: glass table -# id: TableGlass -# graph: Table -# startNode: start -# targetNode: TableGlass -# category: construction-category-furniture -# description: A square piece of glass, standing on four metal legs. -# icon: -# sprite: Structures/Furniture/Tables/glass.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: reinforced glass table -# id: TableReinforcedGlass -# graph: Table -# startNode: start -# targetNode: TableReinforcedGlass -# category: construction-category-furniture -# description: A square piece of glass, standing on four metal legs. Extra robust. -# icon: -# sprite: Structures/Furniture/Tables/r_glass.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: plasma glass table -# id: TablePlasmaGlass -# graph: Table -# startNode: start -# targetNode: TablePlasmaGlass -# category: construction-category-furniture -# description: A square piece of plasma glass, standing on four metal legs. Pretty! -# icon: -# sprite: Structures/Furniture/Tables/plasma.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: brass table -# id: TableBrass -# graph: Table -# startNode: start -# targetNode: TableBrass -# category: construction-category-furniture -# description: A shiny, corrosion resistant brass table. Steampunk! -# icon: -# sprite: Structures/Furniture/Tables/brass.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: wood table -# id: TableWood -# graph: Table -# startNode: start -# targetNode: TableWood -# category: construction-category-furniture -# description: Do not apply fire to this. Rumour says it burns easily. -# icon: -# sprite: Structures/Furniture/Tables/wood.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: poker table -# id: TableCarpet -# graph: Table -# startNode: start -# targetNode: TableCarpet -# category: construction-category-furniture -# description: A square piece of wood standing on four legs covered by a cloth. (What did you expect?) -# icon: -# sprite: Structures/Furniture/Tables/carpet.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: fancy black table -# id: TableFancyBlack -# graph: Table -# startNode: start -# targetNode: TableFancyBlack -# category: construction-category-furniture -# description: A table covered with a beautiful cloth. -# icon: -# sprite: Structures/Furniture/Tables/Fancy/black.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: fancy blue table -# id: TableFancyBlue -# graph: Table -# startNode: start -# targetNode: TableFancyBlue -# category: construction-category-furniture -# description: A table covered with a beautiful cloth. -# icon: -# sprite: Structures/Furniture/Tables/Fancy/blue.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: fancy cyan table -# id: TableFancyCyan -# graph: Table -# startNode: start -# targetNode: TableFancyCyan -# category: construction-category-furniture -# description: A table covered with a beautiful cloth. -# icon: -# sprite: Structures/Furniture/Tables/Fancy/cyan.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: fancy green table -# id: TableFancyGreen -# graph: Table -# startNode: start -# targetNode: TableFancyGreen -# category: construction-category-furniture -# description: A table covered with a beautiful cloth. -# icon: -# sprite: Structures/Furniture/Tables/Fancy/green.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: fancy orange table -# id: TableFancyOrange -# graph: Table -# startNode: start -# targetNode: TableFancyOrange -# category: construction-category-furniture -# description: A table covered with a beautiful cloth. -# icon: -# sprite: Structures/Furniture/Tables/Fancy/orange.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: fancy purple table -# id: TableFancyPurple -# graph: Table -# startNode: start -# targetNode: TableFancyPurple -# category: construction-category-furniture -# description: A table covered with a beautiful cloth. -# icon: -# sprite: Structures/Furniture/Tables/Fancy/purple.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: fancy pink table -# id: TableFancyPink -# graph: Table -# startNode: start -# targetNode: TableFancyPink -# category: construction-category-furniture -# description: A table covered with a beautiful cloth. -# icon: -# sprite: Structures/Furniture/Tables/Fancy/pink.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: fancy red table -# id: TableFancyRed -# graph: Table -# startNode: start -# targetNode: TableFancyRed -# category: construction-category-furniture -# description: A table covered with a beautiful cloth. -# icon: -# sprite: Structures/Furniture/Tables/Fancy/red.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: fancy white table -# id: TableFancyWhite -# graph: Table -# startNode: start -# targetNode: TableFancyWhite -# category: construction-category-furniture -# description: A table covered with a beautiful cloth. -# icon: -# sprite: Structures/Furniture/Tables/Fancy/white.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: metal counter -# id: TableCounterMetal -# graph: Table -# startNode: start -# targetNode: CounterMetal -# category: construction-category-furniture -# description: Looks like a good place to put a drink down. -# icon: -# sprite: Structures/Furniture/Tables/countermetal.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: wood counter -# id: TableCounterWood -# graph: Table -# startNode: start -# targetNode: CounterWood -# category: construction-category-furniture -# description: Do not apply fire to this. Rumour says it burns easily. -# icon: -# sprite: Structures/Furniture/Tables/counterwood.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -##bathroom -#- type: construction -# name: toilet -# id: ToiletEmpty -# graph: Toilet -# startNode: start -# targetNode: toilet -# category: construction-category-furniture -# description: A human excrement flushing apparatus. -# icon: -# sprite: Structures/Furniture/toilet.rsi -# state: closed_toilet_seat_up -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -##bedroom -#- type: construction -# id: Bed -# name: bed -# description: This is used to lie in, sleep in or strap on. Resting here provides extremely slow healing. -# graph: bed -# startNode: start -# targetNode: bed -# category: construction-category-furniture -# icon: -# sprite: Structures/Furniture/furniture.rsi -# state: bed -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# id: MedicalBed -# name: medical bed -# description: A hospital bed for patients to recover in. Resting here provides fairly slow healing. -# graph: bed -# startNode: start -# targetNode: medicalbed -# category: construction-category-furniture -# icon: -# sprite: Structures/Furniture/furniture.rsi -# state: bed-MED -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# id: DogBed -# name: dog bed -# description: A comfy-looking dog bed. You can even strap your pet in, in case the gravity turns off. -# graph: bed -# startNode: start -# targetNode: dogbed -# category: construction-category-furniture -# icon: -# sprite: Structures/Furniture/furniture.rsi -# state: dogbed -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# id: Dresser -# name: dresser -# description: Wooden dresser, can store things inside itself. -# graph: Dresser -# startNode: start -# targetNode: dresser -# category: construction-category-furniture -# icon: -# sprite: Structures/Furniture/furniture.rsi -# state: dresser -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -##racks -#- type: construction -# id: Rack -# name: rack -# description: A rack for storing things on. -# graph: Rack -# startNode: start -# targetNode: Rack -# category: construction-category-furniture -# icon: -# sprite: Structures/Furniture/furniture.rsi -# state: rack -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -##misc -#- type: construction -# id: MeatSpike -# name: meat spike -# description: A spike found in kitchens butchering animals. -# graph: MeatSpike -# startNode: start -# targetNode: MeatSpike -# category: construction-category-furniture -# icon: -# sprite: Structures/meat_spike.rsi -# state: spike -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# id: Curtains -# name: curtains -# description: Contains less than 1% mercury. -# graph: Curtains -# startNode: start -# targetNode: Curtains -# category: construction-category-furniture -# icon: -# sprite: Structures/Decoration/Curtains/hospital.rsi -# state: closed -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: true -# -#- type: construction -# id: CurtainsBlack -# name: black curtains -# description: Hides what others shouldn't see. -# graph: Curtains -# startNode: start -# targetNode: CurtainsBlack -# category: construction-category-furniture -# icon: -# sprite: Structures/Decoration/Curtains/black.rsi -# state: closed -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: true -# -#- type: construction -# id: CurtainsBlue -# name: blue curtains -# description: Hides what others shouldn't see. -# graph: Curtains -# startNode: start -# targetNode: CurtainsBlue -# category: construction-category-furniture -# icon: -# sprite: Structures/Decoration/Curtains/blue.rsi -# state: closed -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: true -# -#- type: construction -# id: CurtainsCyan -# name: cyan curtains -# description: Hides what others shouldn't see. -# graph: Curtains -# startNode: start -# targetNode: CurtainsCyan -# category: construction-category-furniture -# icon: -# sprite: Structures/Decoration/Curtains/cyan.rsi -# state: closed -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: true -# -#- type: construction -# id: CurtainsGreen -# name: green curtains -# description: Hides what others shouldn't see. -# graph: Curtains -# startNode: start -# targetNode: CurtainsGreen -# category: construction-category-furniture -# icon: -# sprite: Structures/Decoration/Curtains/green.rsi -# state: closed -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: true -# -#- type: construction -# id: CurtainsOrange -# name: orange curtains -# description: Hides what others shouldn't see. -# graph: Curtains -# startNode: start -# targetNode: CurtainsOrange -# category: construction-category-furniture -# icon: -# sprite: Structures/Decoration/Curtains/orange.rsi -# state: closed -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: true -# -#- type: construction -# id: CurtainsPink -# name: pink curtains -# description: Hides what others shouldn't see. -# graph: Curtains -# startNode: start -# targetNode: CurtainsPink -# category: construction-category-furniture -# icon: -# sprite: Structures/Decoration/Curtains/pink.rsi -# state: closed -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: true -# -#- type: construction -# id: CurtainsPurple -# name: purple curtains -# description: Hides what others shouldn't see. -# graph: Curtains -# startNode: start -# targetNode: CurtainsPurple -# category: construction-category-furniture -# icon: -# sprite: Structures/Decoration/Curtains/purple.rsi -# state: closed -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: true -# -#- type: construction -# id: CurtainsRed -# name: red curtains -# description: Hides what others shouldn't see. -# graph: Curtains -# startNode: start -# targetNode: CurtainsRed -# category: construction-category-furniture -# icon: -# sprite: Structures/Decoration/Curtains/red.rsi -# state: closed -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: true -# -#- type: construction -# id: CurtainsWhite -# name: white curtains -# description: Hides what others shouldn't see. -# graph: Curtains -# startNode: start -# targetNode: CurtainsWhite -# category: construction-category-furniture -# icon: -# sprite: Structures/Decoration/Curtains/white.rsi -# state: closed -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: true -# -#- type: construction -# id: Bookshelf -# name: bookshelf -# description: Mostly filled with books. -# graph: Bookshelf -# startNode: start -# targetNode: bookshelf -# category: construction-category-furniture -# icon: -# sprite: Structures/Furniture/bookshelf.rsi -# state: base -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked +- type: construction + name: chair + id: Chair + graph: Seat + startNode: start + targetNode: chair + category: construction-category-furniture + description: You sit in this. Either by will or force. + icon: + sprite: Structures/Furniture/chairs.rsi + state: chair + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: stool + id: Stool + graph: Seat + startNode: start + targetNode: stool + category: construction-category-furniture + description: You sit in this. Either by will or force. + icon: + sprite: Structures/Furniture/chairs.rsi + state: stool + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: bar stool + id: StoolBar + graph: Seat + startNode: start + targetNode: stoolBar + category: construction-category-furniture + description: You sit in this. Either by will or force. + icon: + sprite: Structures/Furniture/chairs.rsi + state: bar + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: brass chair + id: ChairBrass + graph: Seat + startNode: start + targetNode: chairBrass + category: construction-category-furniture + description: You sit in this. Either by will or force. + icon: + sprite: Structures/Furniture/chairs.rsi + state: brass_chair + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: office chair + id: ChairOfficeLight + graph: Seat + startNode: start + targetNode: chairOffice + category: construction-category-furniture + description: You sit in this. Either by will or force. + icon: + sprite: Structures/Furniture/chairs.rsi + state: office-white + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: dark office chair + id: ChairOfficeDark + graph: Seat + startNode: start + targetNode: chairOfficeDark + category: construction-category-furniture + description: You sit in this. Either by will or force. + icon: + sprite: Structures/Furniture/chairs.rsi + state: office-dark + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: comfy chair + id: ChairComfy + graph: Seat + startNode: start + targetNode: chairComfy + category: construction-category-furniture + description: It looks comfy. + icon: + sprite: Structures/Furniture/chairs.rsi + state: comfy + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: pilots chair + id: chairPilotSeat + graph: Seat + startNode: start + targetNode: chairPilotSeat + category: construction-category-furniture + description: Fit for a captain. + icon: + sprite: Structures/Furniture/chairs.rsi + state: shuttle + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: wooden chair + id: ChairWood + graph: Seat + startNode: start + targetNode: chairWood + category: construction-category-furniture + description: You sit in this. Either by will or force. + icon: + sprite: Structures/Furniture/chairs.rsi + state: wooden + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: meat chair + id: ChairMeat + graph: Seat + startNode: start + targetNode: chairMeat + category: construction-category-furniture + description: Uncomfortably sweaty. + icon: + sprite: Structures/Furniture/chairs.rsi + state: meat + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: ritual chair + id: ChairRitual + graph: RitualSeat + startNode: start + targetNode: chairRitual + category: construction-category-furniture + description: A strangely carved chair. + icon: + sprite: Structures/Furniture/chairs.rsi + state: ritual + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: folding chair + id: ChairFolding + graph: Seat + startNode: start + targetNode: chairFolding + category: construction-category-furniture + description: An easy to carry chair. + icon: + sprite: Structures/Furniture/folding_chair.rsi + state: folding + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: steel bench + id: ChairSteelBench + graph: Seat + startNode: start + targetNode: chairSteelBench + category: construction-category-furniture + description: A long chair made for a metro. Really standard design. + icon: + sprite: Structures/Furniture/chairs.rsi + state: steel-bench + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: wooden bench + id: ChairWoodBench + graph: Seat + startNode: start + targetNode: chairWoodBench + category: construction-category-furniture + description: Did you get a splinter? Well, at least it’s eco friendly. + icon: + sprite: Structures/Furniture/chairs.rsi + state: wooden-bench + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: comfortable red bench + id: RedComfBench + graph: Seat + startNode: start + targetNode: redComfBench + category: construction-category-furniture + description: A bench with an extremely comfortable backrest. + icon: + sprite: Structures/Furniture/Bench/comf_bench.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: comfortable blue bench + id: BlueComfBench + graph: Seat + startNode: start + targetNode: blueComfBench + category: construction-category-furniture + description: A bench with an extremely comfortable backrest. + icon: + sprite: Structures/Furniture/Bench/comf_bench.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +#tables +- type: construction + name: steel table + id: Table + graph: Table + startNode: start + targetNode: Table + category: construction-category-furniture + description: A square piece of metal standing on four metal legs. + icon: + sprite: Structures/Furniture/Tables/generic.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: reinforced steel table + id: TableReinforced + graph: Table + startNode: start + targetNode: TableReinforced + category: construction-category-furniture + description: A square piece of metal standing on four metal legs. Extra robust. + icon: + sprite: Structures/Furniture/Tables/reinforced.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: glass table + id: TableGlass + graph: Table + startNode: start + targetNode: TableGlass + category: construction-category-furniture + description: A square piece of glass, standing on four metal legs. + icon: + sprite: Structures/Furniture/Tables/glass.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: reinforced glass table + id: TableReinforcedGlass + graph: Table + startNode: start + targetNode: TableReinforcedGlass + category: construction-category-furniture + description: A square piece of glass, standing on four metal legs. Extra robust. + icon: + sprite: Structures/Furniture/Tables/r_glass.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: plasma glass table + id: TablePlasmaGlass + graph: Table + startNode: start + targetNode: TablePlasmaGlass + category: construction-category-furniture + description: A square piece of plasma glass, standing on four metal legs. Pretty! + icon: + sprite: Structures/Furniture/Tables/plasma.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: brass table + id: TableBrass + graph: Table + startNode: start + targetNode: TableBrass + category: construction-category-furniture + description: A shiny, corrosion resistant brass table. Steampunk! + icon: + sprite: Structures/Furniture/Tables/brass.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: wood table + id: TableWood + graph: Table + startNode: start + targetNode: TableWood + category: construction-category-furniture + description: Do not apply fire to this. Rumour says it burns easily. + icon: + sprite: Structures/Furniture/Tables/wood.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: poker table + id: TableCarpet + graph: Table + startNode: start + targetNode: TableCarpet + category: construction-category-furniture + description: A square piece of wood standing on four legs covered by a cloth. (What did you expect?) + icon: + sprite: Structures/Furniture/Tables/carpet.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: fancy black table + id: TableFancyBlack + graph: Table + startNode: start + targetNode: TableFancyBlack + category: construction-category-furniture + description: A table covered with a beautiful cloth. + icon: + sprite: Structures/Furniture/Tables/Fancy/black.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: fancy blue table + id: TableFancyBlue + graph: Table + startNode: start + targetNode: TableFancyBlue + category: construction-category-furniture + description: A table covered with a beautiful cloth. + icon: + sprite: Structures/Furniture/Tables/Fancy/blue.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: fancy cyan table + id: TableFancyCyan + graph: Table + startNode: start + targetNode: TableFancyCyan + category: construction-category-furniture + description: A table covered with a beautiful cloth. + icon: + sprite: Structures/Furniture/Tables/Fancy/cyan.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: fancy green table + id: TableFancyGreen + graph: Table + startNode: start + targetNode: TableFancyGreen + category: construction-category-furniture + description: A table covered with a beautiful cloth. + icon: + sprite: Structures/Furniture/Tables/Fancy/green.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: fancy orange table + id: TableFancyOrange + graph: Table + startNode: start + targetNode: TableFancyOrange + category: construction-category-furniture + description: A table covered with a beautiful cloth. + icon: + sprite: Structures/Furniture/Tables/Fancy/orange.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: fancy purple table + id: TableFancyPurple + graph: Table + startNode: start + targetNode: TableFancyPurple + category: construction-category-furniture + description: A table covered with a beautiful cloth. + icon: + sprite: Structures/Furniture/Tables/Fancy/purple.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: fancy pink table + id: TableFancyPink + graph: Table + startNode: start + targetNode: TableFancyPink + category: construction-category-furniture + description: A table covered with a beautiful cloth. + icon: + sprite: Structures/Furniture/Tables/Fancy/pink.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: fancy red table + id: TableFancyRed + graph: Table + startNode: start + targetNode: TableFancyRed + category: construction-category-furniture + description: A table covered with a beautiful cloth. + icon: + sprite: Structures/Furniture/Tables/Fancy/red.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: fancy white table + id: TableFancyWhite + graph: Table + startNode: start + targetNode: TableFancyWhite + category: construction-category-furniture + description: A table covered with a beautiful cloth. + icon: + sprite: Structures/Furniture/Tables/Fancy/white.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: metal counter + id: TableCounterMetal + graph: Table + startNode: start + targetNode: CounterMetal + category: construction-category-furniture + description: Looks like a good place to put a drink down. + icon: + sprite: Structures/Furniture/Tables/countermetal.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: wood counter + id: TableCounterWood + graph: Table + startNode: start + targetNode: CounterWood + category: construction-category-furniture + description: Do not apply fire to this. Rumour says it burns easily. + icon: + sprite: Structures/Furniture/Tables/counterwood.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +#bathroom +- type: construction + name: toilet + id: ToiletEmpty + graph: Toilet + startNode: start + targetNode: toilet + category: construction-category-furniture + description: A human excrement flushing apparatus. + icon: + sprite: Structures/Furniture/toilet.rsi + state: closed_toilet_seat_up + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +#bedroom +- type: construction + id: Bed + name: bed + description: This is used to lie in, sleep in or strap on. Resting here provides extremely slow healing. + graph: bed + startNode: start + targetNode: bed + category: construction-category-furniture + icon: + sprite: Structures/Furniture/furniture.rsi + state: bed + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + id: MedicalBed + name: medical bed + description: A hospital bed for patients to recover in. Resting here provides fairly slow healing. + graph: bed + startNode: start + targetNode: medicalbed + category: construction-category-furniture + icon: + sprite: Structures/Furniture/furniture.rsi + state: bed-MED + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + id: DogBed + name: dog bed + description: A comfy-looking dog bed. You can even strap your pet in, in case the gravity turns off. + graph: bed + startNode: start + targetNode: dogbed + category: construction-category-furniture + icon: + sprite: Structures/Furniture/furniture.rsi + state: dogbed + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + id: Dresser + name: dresser + description: Wooden dresser, can store things inside itself. + graph: Dresser + startNode: start + targetNode: dresser + category: construction-category-furniture + icon: + sprite: Structures/Furniture/furniture.rsi + state: dresser + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +#racks +- type: construction + id: Rack + name: rack + description: A rack for storing things on. + graph: Rack + startNode: start + targetNode: Rack + category: construction-category-furniture + icon: + sprite: Structures/Furniture/furniture.rsi + state: rack + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +#misc +- type: construction + id: MeatSpike + name: meat spike + description: A spike found in kitchens butchering animals. + graph: MeatSpike + startNode: start + targetNode: MeatSpike + category: construction-category-furniture + icon: + sprite: Structures/meat_spike.rsi + state: spike + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + id: Curtains + name: curtains + description: Contains less than 1% mercury. + graph: Curtains + startNode: start + targetNode: Curtains + category: construction-category-furniture + icon: + sprite: Structures/Decoration/Curtains/hospital.rsi + state: closed + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: true + +- type: construction + id: CurtainsBlack + name: black curtains + description: Hides what others shouldn't see. + graph: Curtains + startNode: start + targetNode: CurtainsBlack + category: construction-category-furniture + icon: + sprite: Structures/Decoration/Curtains/black.rsi + state: closed + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: true + +- type: construction + id: CurtainsBlue + name: blue curtains + description: Hides what others shouldn't see. + graph: Curtains + startNode: start + targetNode: CurtainsBlue + category: construction-category-furniture + icon: + sprite: Structures/Decoration/Curtains/blue.rsi + state: closed + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: true + +- type: construction + id: CurtainsCyan + name: cyan curtains + description: Hides what others shouldn't see. + graph: Curtains + startNode: start + targetNode: CurtainsCyan + category: construction-category-furniture + icon: + sprite: Structures/Decoration/Curtains/cyan.rsi + state: closed + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: true + +- type: construction + id: CurtainsGreen + name: green curtains + description: Hides what others shouldn't see. + graph: Curtains + startNode: start + targetNode: CurtainsGreen + category: construction-category-furniture + icon: + sprite: Structures/Decoration/Curtains/green.rsi + state: closed + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: true + +- type: construction + id: CurtainsOrange + name: orange curtains + description: Hides what others shouldn't see. + graph: Curtains + startNode: start + targetNode: CurtainsOrange + category: construction-category-furniture + icon: + sprite: Structures/Decoration/Curtains/orange.rsi + state: closed + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: true + +- type: construction + id: CurtainsPink + name: pink curtains + description: Hides what others shouldn't see. + graph: Curtains + startNode: start + targetNode: CurtainsPink + category: construction-category-furniture + icon: + sprite: Structures/Decoration/Curtains/pink.rsi + state: closed + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: true + +- type: construction + id: CurtainsPurple + name: purple curtains + description: Hides what others shouldn't see. + graph: Curtains + startNode: start + targetNode: CurtainsPurple + category: construction-category-furniture + icon: + sprite: Structures/Decoration/Curtains/purple.rsi + state: closed + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: true + +- type: construction + id: CurtainsRed + name: red curtains + description: Hides what others shouldn't see. + graph: Curtains + startNode: start + targetNode: CurtainsRed + category: construction-category-furniture + icon: + sprite: Structures/Decoration/Curtains/red.rsi + state: closed + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: true + +- type: construction + id: CurtainsWhite + name: white curtains + description: Hides what others shouldn't see. + graph: Curtains + startNode: start + targetNode: CurtainsWhite + category: construction-category-furniture + icon: + sprite: Structures/Decoration/Curtains/white.rsi + state: closed + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: true + +- type: construction + id: Bookshelf + name: bookshelf + description: Mostly filled with books. + graph: Bookshelf + startNode: start + targetNode: bookshelf + category: construction-category-furniture + icon: + sprite: Structures/Furniture/bookshelf.rsi + state: base + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked diff --git a/Resources/Prototypes/Recipes/Construction/lighting.yml b/Resources/Prototypes/Recipes/Construction/lighting.yml index 289a29d55f..0533f70f1a 100644 --- a/Resources/Prototypes/Recipes/Construction/lighting.yml +++ b/Resources/Prototypes/Recipes/Construction/lighting.yml @@ -1,65 +1,65 @@ -#- type: construction -# name: cyan light tube -# id: CyanLight -# graph: CyanLight -# startNode: start -# targetNode: icon -# category: construction-category-utilities -# description: A high powered light tube containing a cyan crystal -# icon: { sprite: Objects/Power/light_tube.rsi, state: normal } -# objectType: Item -# -#- type: construction -# name: blue light tube -# id: BlueLight -# graph: BlueLight -# startNode: start -# targetNode: icon -# category: construction-category-utilities -# description: A high powered light tube containing a blue crystal -# icon: { sprite: Objects/Power/light_tube.rsi, state: normal } -# objectType: Item -# -#- type: construction -# name: pink light tube -# id: PinkLight -# graph: PinkLight -# startNode: start -# targetNode: icon -# category: construction-category-utilities -# description: A high powered light tube containing a pink crystal -# icon: { sprite: Objects/Power/light_tube.rsi, state: normal } -# objectType: Item -# -#- type: construction -# name: orange light tube -# id: OrangeLight -# graph: OrangeLight -# startNode: start -# targetNode: icon -# category: construction-category-utilities -# description: A high powered light tube containing an orange crystal -# icon: { sprite: Objects/Power/light_tube.rsi, state: normal } -# objectType: Item -# -#- type: construction -# name: red light tube -# id: RedLight -# graph: RedLight -# startNode: start -# targetNode: icon -# category: construction-category-utilities -# description: A high powered light tube containing a red crystal -# icon: { sprite: Objects/Power/light_tube.rsi, state: normal } -# objectType: Item -# -#- type: construction -# name: green light tube -# id: GreenLight -# graph: GreenLight -# startNode: start -# targetNode: icon -# category: construction-category-utilities -# description: A high powered light tube containing a green crystal -# icon: { sprite: Objects/Power/light_tube.rsi, state: normal } -# objectType: Item +- type: construction + name: cyan light tube + id: CyanLight + graph: CyanLight + startNode: start + targetNode: icon + category: construction-category-utilities + description: A high powered light tube containing a cyan crystal + icon: { sprite: Objects/Power/light_tube.rsi, state: normal } + objectType: Item + +- type: construction + name: blue light tube + id: BlueLight + graph: BlueLight + startNode: start + targetNode: icon + category: construction-category-utilities + description: A high powered light tube containing a blue crystal + icon: { sprite: Objects/Power/light_tube.rsi, state: normal } + objectType: Item + +- type: construction + name: pink light tube + id: PinkLight + graph: PinkLight + startNode: start + targetNode: icon + category: construction-category-utilities + description: A high powered light tube containing a pink crystal + icon: { sprite: Objects/Power/light_tube.rsi, state: normal } + objectType: Item + +- type: construction + name: orange light tube + id: OrangeLight + graph: OrangeLight + startNode: start + targetNode: icon + category: construction-category-utilities + description: A high powered light tube containing an orange crystal + icon: { sprite: Objects/Power/light_tube.rsi, state: normal } + objectType: Item + +- type: construction + name: red light tube + id: RedLight + graph: RedLight + startNode: start + targetNode: icon + category: construction-category-utilities + description: A high powered light tube containing a red crystal + icon: { sprite: Objects/Power/light_tube.rsi, state: normal } + objectType: Item + +- type: construction + name: green light tube + id: GreenLight + graph: GreenLight + startNode: start + targetNode: icon + category: construction-category-utilities + description: A high powered light tube containing a green crystal + icon: { sprite: Objects/Power/light_tube.rsi, state: normal } + objectType: Item diff --git a/Resources/Prototypes/Recipes/Construction/machines.yml b/Resources/Prototypes/Recipes/Construction/machines.yml index c931771be3..4026d5c98a 100644 --- a/Resources/Prototypes/Recipes/Construction/machines.yml +++ b/Resources/Prototypes/Recipes/Construction/machines.yml @@ -25,128 +25,128 @@ icon: sprite: Structures/Machines/parts.rsi state: "box_0" -# -## Switching -#- type: construction -# name: two-way lever -# id: TwoWayLeverRecipe -# graph: LeverGraph -# startNode: start -# targetNode: LeverNode -# category: construction-category-machines -# description: A lever to control machines. It has 3 modes. -# objectType: Structure -# canBuildInImpassable: false -# icon: -# sprite: Structures/conveyor.rsi -# state: switch-off -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: light switch -# id: LightSwitchRecipe -# graph: LightSwitchGraph -# startNode: start -# targetNode: LightSwitchNode -# category: construction-category-machines -# description: A switch for toggling lights that are connected to the same apc. -# icon: -# sprite: Structures/Wallmounts/switch.rsi -# state: on -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: true -# canBuildInImpassable: true -# conditions: -# - !type:WallmountCondition -# -#- type: construction -# name: signal switch -# id: SignalSwitchRecipe -# graph: SignalSwitchGraph -# startNode: start -# targetNode: SignalSwitchNode -# category: construction-category-machines -# description: It's a switch for toggling power to things. -# icon: -# sprite: Structures/Wallmounts/switch.rsi -# state: on -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: true -# canBuildInImpassable: true -# conditions: -# - !type:WallmountCondition -# -#- type: construction -# name: signal button -# id: SignalButtonRecipe -# graph: SignalButtonGraph -# startNode: start -# targetNode: SignalButtonNode -# category: construction-category-machines -# description: It's a button for activating something. -# icon: -# sprite: Structures/Wallmounts/switch.rsi -# state: on -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: true -# canBuildInImpassable: true -# conditions: -# - !type:WallmountCondition -# -#- type: construction -# name: directional light switch -# id: LightSwitchDirectionalRecipe -# graph: LightSwitchDirectionalGraph -# startNode: start -# targetNode: LightSwitchDirectionalNode -# category: construction-category-machines -# description: A switch for toggling lights that are connected to the same apc. -# icon: -# sprite: Structures/Wallmounts/switch.rsi -# state: on -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: true -# canBuildInImpassable: true -# conditions: -# - !type:WallmountCondition -# -#- type: construction -# name: directional signal switch -# id: SignalSwitchDirectionalRecipe -# graph: SignalSwitchDirectionalGraph -# startNode: start -# targetNode: SignalSwitchDirectionalNode -# category: construction-category-machines -# description: It's a switch for toggling power to things. -# icon: -# sprite: Structures/Wallmounts/switch.rsi -# state: on -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: true -# canBuildInImpassable: true -# conditions: -# - !type:WallmountCondition -# -#- type: construction -# name: directional signal button -# id: SignalButtonDirectionalRecipe -# graph: SignalButtonDirectionalGraph -# startNode: start -# targetNode: SignalButtonDirectionalNode -# category: construction-category-machines -# description: It's a button for activating something. -# icon: -# sprite: Structures/Wallmounts/switch.rsi -# state: on -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: true -# canBuildInImpassable: true -# conditions: -# - !type:WallmountCondition + +# Switching +- type: construction + name: two-way lever + id: TwoWayLeverRecipe + graph: LeverGraph + startNode: start + targetNode: LeverNode + category: construction-category-machines + description: A lever to control machines. It has 3 modes. + objectType: Structure + canBuildInImpassable: false + icon: + sprite: Structures/conveyor.rsi + state: switch-off + conditions: + - !type:TileNotBlocked + +- type: construction + name: light switch + id: LightSwitchRecipe + graph: LightSwitchGraph + startNode: start + targetNode: LightSwitchNode + category: construction-category-machines + description: A switch for toggling lights that are connected to the same apc. + icon: + sprite: Structures/Wallmounts/switch.rsi + state: on + objectType: Structure + placementMode: SnapgridCenter + canRotate: true + canBuildInImpassable: true + conditions: + - !type:WallmountCondition + +- type: construction + name: signal switch + id: SignalSwitchRecipe + graph: SignalSwitchGraph + startNode: start + targetNode: SignalSwitchNode + category: construction-category-machines + description: It's a switch for toggling power to things. + icon: + sprite: Structures/Wallmounts/switch.rsi + state: on + objectType: Structure + placementMode: SnapgridCenter + canRotate: true + canBuildInImpassable: true + conditions: + - !type:WallmountCondition + +- type: construction + name: signal button + id: SignalButtonRecipe + graph: SignalButtonGraph + startNode: start + targetNode: SignalButtonNode + category: construction-category-machines + description: It's a button for activating something. + icon: + sprite: Structures/Wallmounts/switch.rsi + state: on + objectType: Structure + placementMode: SnapgridCenter + canRotate: true + canBuildInImpassable: true + conditions: + - !type:WallmountCondition + +- type: construction + name: directional light switch + id: LightSwitchDirectionalRecipe + graph: LightSwitchDirectionalGraph + startNode: start + targetNode: LightSwitchDirectionalNode + category: construction-category-machines + description: A switch for toggling lights that are connected to the same apc. + icon: + sprite: Structures/Wallmounts/switch.rsi + state: on + objectType: Structure + placementMode: SnapgridCenter + canRotate: true + canBuildInImpassable: true + conditions: + - !type:WallmountCondition + +- type: construction + name: directional signal switch + id: SignalSwitchDirectionalRecipe + graph: SignalSwitchDirectionalGraph + startNode: start + targetNode: SignalSwitchDirectionalNode + category: construction-category-machines + description: It's a switch for toggling power to things. + icon: + sprite: Structures/Wallmounts/switch.rsi + state: on + objectType: Structure + placementMode: SnapgridCenter + canRotate: true + canBuildInImpassable: true + conditions: + - !type:WallmountCondition + +- type: construction + name: directional signal button + id: SignalButtonDirectionalRecipe + graph: SignalButtonDirectionalGraph + startNode: start + targetNode: SignalButtonDirectionalNode + category: construction-category-machines + description: It's a button for activating something. + icon: + sprite: Structures/Wallmounts/switch.rsi + state: on + objectType: Structure + placementMode: SnapgridCenter + canRotate: true + canBuildInImpassable: true + conditions: + - !type:WallmountCondition diff --git a/Resources/Prototypes/Recipes/Construction/materials.yml b/Resources/Prototypes/Recipes/Construction/materials.yml index c44843e88e..d644538a45 100644 --- a/Resources/Prototypes/Recipes/Construction/materials.yml +++ b/Resources/Prototypes/Recipes/Construction/materials.yml @@ -8,124 +8,124 @@ description: A sturdy metal rod that can be used for various purposes. icon: { sprite: Objects/Materials/parts.rsi, state: rods } objectType: Item -# -#- type: construction -# name: reinforced glass -# description: A reinforced sheet of glass. -# id: SheetRGlass -# graph: Glass -# startNode: start -# targetNode: SheetRGlass -# category: construction-category-materials -# icon: { sprite: Objects/Materials/Sheets/glass.rsi, state: rglass } -# objectType: Item -# -#- type: construction -# name: clockwork glass -# description: A brass-reinforced sheet of glass. -# id: SheetClockworkGlass -# graph: Glass -# startNode: start -# targetNode: SheetClockworkGlass -# category: construction-category-materials -# icon: { sprite: Objects/Materials/Sheets/glass.rsi, state: cglass } -# objectType: Item -# -#- type: construction -# name: plasma glass -# description: A sheet of translucent plasma. -# id: SheetPGlass -# graph: Glass -# startNode: start -# targetNode: SheetPGlass -# category: construction-category-materials -# icon: { sprite: Objects/Materials/Sheets/glass.rsi, state: pglass } -# objectType: Item -# -#- type: construction -# name: reinforced plasma glass -# description: A reinforced sheet of translucent plasma. -# id: SheetRPGlass -# graph: Glass -# startNode: start -# targetNode: SheetRPGlass -# category: construction-category-materials -# icon: { sprite: Objects/Materials/Sheets/glass.rsi, state: rpglass } -# objectType: Item -# -#- type: construction -# name: reinforced plasma glass -# description: A reinforced sheet of translucent plasma. -# id: SheetRPGlass0 -# graph: Glass -# startNode: start -# targetNode: SheetRPGlass0 -# category: construction-category-materials -# icon: { sprite: Objects/Materials/Sheets/glass.rsi, state: rpglass } -# objectType: Item -# -#- type: construction -# name: reinforced plasma glass -# description: A reinforced sheet of translucent plasma. -# id: SheetRPGlass1 -# graph: Glass -# startNode: start -# targetNode: SheetRPGlass1 -# category: construction-category-materials -# icon: { sprite: Objects/Materials/Sheets/glass.rsi, state: rpglass } -# objectType: Item -# -#- type: construction -# name: durathread -# id: MaterialDurathread -# graph: Durathread -# startNode: start -# targetNode: MaterialDurathread -# category: construction-category-materials -# description: A high-quality thread used to make durable clothes. -# icon: { sprite: Objects/Materials/materials.rsi, state: durathread } -# objectType: Item -# -#- type: construction -# name: uranium glass -# description: A sheet of uranium glass. -# id: SheetUGlass -# graph: Glass -# startNode: start -# targetNode: SheetUGlass -# category: construction-category-materials -# icon: { sprite: Objects/Materials/Sheets/glass.rsi, state: uglass } -# objectType: Item -# -#- type: construction -# name: reinforced uranium glass -# description: A reinforced sheet of uranium glass. -# id: SheetRUGlass -# graph: Glass -# startNode: start -# targetNode: SheetRUGlass -# category: construction-category-materials -# icon: { sprite: Objects/Materials/Sheets/glass.rsi, state: ruglass } -# objectType: Item -# -#- type: construction -# name: reinforced uranium glass -# description: A reinforced sheet of uranium glass. -# id: SheetRUGlass0 -# graph: Glass -# startNode: start -# targetNode: SheetRUGlass0 -# category: construction-category-materials -# icon: { sprite: Objects/Materials/Sheets/glass.rsi, state: ruglass } -# objectType: Item -# -#- type: construction -# name: reinforced uranium glass -# description: A reinforced sheet of uranium glass. -# id: SheetRUGlass1 -# graph: Glass -# startNode: start -# targetNode: SheetRUGlass1 -# category: construction-category-materials -# icon: { sprite: Objects/Materials/Sheets/glass.rsi, state: ruglass } -# objectType: Item \ No newline at end of file + +- type: construction + name: reinforced glass + description: A reinforced sheet of glass. + id: SheetRGlass + graph: Glass + startNode: start + targetNode: SheetRGlass + category: construction-category-materials + icon: { sprite: Objects/Materials/Sheets/glass.rsi, state: rglass } + objectType: Item + +- type: construction + name: clockwork glass + description: A brass-reinforced sheet of glass. + id: SheetClockworkGlass + graph: Glass + startNode: start + targetNode: SheetClockworkGlass + category: construction-category-materials + icon: { sprite: Objects/Materials/Sheets/glass.rsi, state: cglass } + objectType: Item + +- type: construction + name: plasma glass + description: A sheet of translucent plasma. + id: SheetPGlass + graph: Glass + startNode: start + targetNode: SheetPGlass + category: construction-category-materials + icon: { sprite: Objects/Materials/Sheets/glass.rsi, state: pglass } + objectType: Item + +- type: construction + name: reinforced plasma glass + description: A reinforced sheet of translucent plasma. + id: SheetRPGlass + graph: Glass + startNode: start + targetNode: SheetRPGlass + category: construction-category-materials + icon: { sprite: Objects/Materials/Sheets/glass.rsi, state: rpglass } + objectType: Item + +- type: construction + name: reinforced plasma glass + description: A reinforced sheet of translucent plasma. + id: SheetRPGlass0 + graph: Glass + startNode: start + targetNode: SheetRPGlass0 + category: construction-category-materials + icon: { sprite: Objects/Materials/Sheets/glass.rsi, state: rpglass } + objectType: Item + +- type: construction + name: reinforced plasma glass + description: A reinforced sheet of translucent plasma. + id: SheetRPGlass1 + graph: Glass + startNode: start + targetNode: SheetRPGlass1 + category: construction-category-materials + icon: { sprite: Objects/Materials/Sheets/glass.rsi, state: rpglass } + objectType: Item + +- type: construction + name: durathread + id: MaterialDurathread + graph: Durathread + startNode: start + targetNode: MaterialDurathread + category: construction-category-materials + description: A high-quality thread used to make durable clothes. + icon: { sprite: Objects/Materials/materials.rsi, state: durathread } + objectType: Item + +- type: construction + name: uranium glass + description: A sheet of uranium glass. + id: SheetUGlass + graph: Glass + startNode: start + targetNode: SheetUGlass + category: construction-category-materials + icon: { sprite: Objects/Materials/Sheets/glass.rsi, state: uglass } + objectType: Item + +- type: construction + name: reinforced uranium glass + description: A reinforced sheet of uranium glass. + id: SheetRUGlass + graph: Glass + startNode: start + targetNode: SheetRUGlass + category: construction-category-materials + icon: { sprite: Objects/Materials/Sheets/glass.rsi, state: ruglass } + objectType: Item + +- type: construction + name: reinforced uranium glass + description: A reinforced sheet of uranium glass. + id: SheetRUGlass0 + graph: Glass + startNode: start + targetNode: SheetRUGlass0 + category: construction-category-materials + icon: { sprite: Objects/Materials/Sheets/glass.rsi, state: ruglass } + objectType: Item + +- type: construction + name: reinforced uranium glass + description: A reinforced sheet of uranium glass. + id: SheetRUGlass1 + graph: Glass + startNode: start + targetNode: SheetRUGlass1 + category: construction-category-materials + icon: { sprite: Objects/Materials/Sheets/glass.rsi, state: ruglass } + objectType: Item \ No newline at end of file diff --git a/Resources/Prototypes/Recipes/Construction/modular.yml b/Resources/Prototypes/Recipes/Construction/modular.yml index 79beee6910..affacb098b 100644 --- a/Resources/Prototypes/Recipes/Construction/modular.yml +++ b/Resources/Prototypes/Recipes/Construction/modular.yml @@ -10,16 +10,16 @@ sprite: Objects/Weapons/Grenades/modular.rsi state: complete objectType: Item -# -#- type: construction -# name: modular mine -# id: ModularMineRecipe -# graph: ModularMineGraph -# startNode: start -# targetNode: mine -# category: construction-category-weapons -# description: Construct a landmine using a payload. -# icon: -# sprite: Objects/Misc/landmine.rsi -# state: landmine -# objectType: Item + +- type: construction + name: modular mine + id: ModularMineRecipe + graph: ModularMineGraph + startNode: start + targetNode: mine + category: construction-category-weapons + description: Construct a landmine using a payload. + icon: + sprite: Objects/Misc/landmine.rsi + state: landmine + objectType: Item diff --git a/Resources/Prototypes/Recipes/Construction/storage.yml b/Resources/Prototypes/Recipes/Construction/storage.yml index 7b4cbf52dc..41abf881b6 100644 --- a/Resources/Prototypes/Recipes/Construction/storage.yml +++ b/Resources/Prototypes/Recipes/Construction/storage.yml @@ -1,51 +1,51 @@ #bureaucracy -#- type: construction -# id: FilingCabinet -# name: filing cabinet -# description: A cabinet for all your filing needs. -# graph: FilingCabinet -# startNode: start -# targetNode: filingCabinet -# category: construction-category-storage -# icon: -# sprite: Structures/Storage/cabinets.rsi -# state: filingcabinet -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# id: TallCabinet -# name: tall cabinet -# description: A cabinet for all your filing needs. -# graph: FilingCabinet -# startNode: start -# targetNode: tallCabinet -# category: construction-category-storage -# icon: -# sprite: Structures/Storage/cabinets.rsi -# state: tallcabinet -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# id: ChestDrawer -# name: chest drawer -# description: A small drawer for all your filing needs, Now with wheels! -# graph: FilingCabinet -# startNode: start -# targetNode: chestDrawer -# category: construction-category-storage -# icon: -# sprite: Structures/Storage/cabinets.rsi -# state: chestdrawer -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked +- type: construction + id: FilingCabinet + name: filing cabinet + description: A cabinet for all your filing needs. + graph: FilingCabinet + startNode: start + targetNode: filingCabinet + category: construction-category-storage + icon: + sprite: Structures/Storage/cabinets.rsi + state: filingcabinet + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + id: TallCabinet + name: tall cabinet + description: A cabinet for all your filing needs. + graph: FilingCabinet + startNode: start + targetNode: tallCabinet + category: construction-category-storage + icon: + sprite: Structures/Storage/cabinets.rsi + state: tallcabinet + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + id: ChestDrawer + name: chest drawer + description: A small drawer for all your filing needs, Now with wheels! + graph: FilingCabinet + startNode: start + targetNode: chestDrawer + category: construction-category-storage + icon: + sprite: Structures/Storage/cabinets.rsi + state: chestdrawer + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked diff --git a/Resources/Prototypes/Recipes/Construction/structures.yml b/Resources/Prototypes/Recipes/Construction/structures.yml index 90e57fb204..963a289bab 100644 --- a/Resources/Prototypes/Recipes/Construction/structures.yml +++ b/Resources/Prototypes/Recipes/Construction/structures.yml @@ -1,56 +1,56 @@ -#- type: construction -# name: girder -# id: Girder -# graph: Girder -# startNode: start -# targetNode: girder -# category: construction-category-structures -# description: A large structural assembly made out of metal. -# icon: -# sprite: /Textures/Structures/Walls/solid.rsi -# state: wall_girder -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: false -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: reinforced girder -# id: ReinforcedGirder -# graph: Girder -# startNode: start -# targetNode: reinforcedGirder -# category: construction-category-structures -# description: A large structural assembly made out of metal and plasteel. -# icon: -# sprite: /Textures/Structures/Walls/solid.rsi -# state: reinforced_wall_girder -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: false -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: wall gear -# id: ClockworkGirder -# graph: ClockworkGirder -# startNode: start -# targetNode: clockGirder -# category: construction-category-structures -# description: A large gear with mounting brackets for additional plating. -# icon: -# sprite: /Textures/Structures/Walls/clock.rsi -# state: wall_gear -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: false -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked +- type: construction + name: girder + id: Girder + graph: Girder + startNode: start + targetNode: girder + category: construction-category-structures + description: A large structural assembly made out of metal. + icon: + sprite: /Textures/Structures/Walls/solid.rsi + state: wall_girder + objectType: Structure + placementMode: SnapgridCenter + canRotate: false + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: reinforced girder + id: ReinforcedGirder + graph: Girder + startNode: start + targetNode: reinforcedGirder + category: construction-category-structures + description: A large structural assembly made out of metal and plasteel. + icon: + sprite: /Textures/Structures/Walls/solid.rsi + state: reinforced_wall_girder + objectType: Structure + placementMode: SnapgridCenter + canRotate: false + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: wall gear + id: ClockworkGirder + graph: ClockworkGirder + startNode: start + targetNode: clockGirder + category: construction-category-structures + description: A large gear with mounting brackets for additional plating. + icon: + sprite: /Textures/Structures/Walls/clock.rsi + state: wall_gear + objectType: Structure + placementMode: SnapgridCenter + canRotate: false + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked - type: construction name: wall @@ -70,239 +70,239 @@ conditions: - !type:TileNotBlocked -#- type: construction -# name: reinforced wall -# id: ReinforcedWall -# graph: Girder -# startNode: start -# targetNode: reinforcedWall -# category: construction-category-structures -# description: Keeps the air in and the greytide out. -# icon: -# sprite: Structures/Walls/solid.rsi -# state: rgeneric -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: false -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: clock wall -# id: WallClock -# graph: ClockworkGirder -# startNode: start -# targetNode: clockworkWall -# category: construction-category-structures -# description: Keeps the air in and the greytide out. -# icon: -# sprite: Structures/Walls/clock.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: false -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -## here -#- type: construction -# name: wood wall -# id: WoodWall -# graph: Girder -# startNode: start -# targetNode: woodWall -# category: construction-category-structures -# description: Keeps the air in and the greytide out. -# icon: -# sprite: Structures/Walls/wood.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: false -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: uranium wall -# id: UraniumWall -# graph: Girder -# startNode: start -# targetNode: uraniumWall -# category: construction-category-structures -# description: Keeps the air in and the greytide out. -# icon: -# sprite: Structures/Walls/uranium.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: false -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: silver wall -# id: SilverWall -# graph: Girder -# startNode: start -# targetNode: silverWall -# category: construction-category-structures -# description: Keeps the air in and the greytide out. -# icon: -# sprite: Structures/Walls/silver.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: false -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: plastic wall -# id: PlasticWall -# graph: Girder -# startNode: start -# targetNode: plasticWall -# category: construction-category-structures -# description: Keeps the air in and the greytide out. -# icon: -# sprite: Structures/Walls/plastic.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: false -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: plasma wall -# id: PlasmaWall -# graph: Girder -# startNode: start -# targetNode: plasmaWall -# category: construction-category-structures -# description: Keeps the air in and the greytide out. -# icon: -# sprite: Structures/Walls/plasma.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: false -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: gold wall -# id: GoldWall -# graph: Girder -# startNode: start -# targetNode: goldWall -# category: construction-category-structures -# description: Keeps the air in and the greytide out. -# icon: -# sprite: Structures/Walls/gold.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: false -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: shuttle wall -# id: ShuttleWall -# graph: Girder -# startNode: start -# targetNode: shuttleWall -# category: construction-category-structures -# description: Keeps the air in and the greytide out. -# icon: -# sprite: Structures/Walls/shuttle.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: false -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: interior shuttle wall -# id: InteriorShuttleWall -# graph: Girder -# startNode: start -# targetNode: shuttleInteriorWall -# category: construction-category-structures -# description: Keeps the air in and the greytide out. -# icon: -# sprite: Structures/Walls/shuttleinterior.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: false -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: diagonal shuttle wall -# id: DiagonalShuttleWall -# graph: Girder -# startNode: start -# targetNode: diagonalshuttleWall -# category: construction-category-structures -# description: Keeps the air in and the greytide out. -# icon: -# sprite: Structures/Walls/shuttle_diagonal.rsi -# state: state0 -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: true -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: bananium wall -# id: ClownWall -# graph: Girder -# startNode: start -# targetNode: bananiumWall -# category: construction-category-structures -# description: Keeps the air in and the greytide out. -# icon: -# sprite: Structures/Walls/clown.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: false -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: meat wall -# id: MeatWall -# graph: Girder -# startNode: start -# targetNode: meatWall -# category: construction-category-structures -# description: Sticky. -# icon: -# sprite: Structures/Walls/meat.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: false -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked +- type: construction + name: reinforced wall + id: ReinforcedWall + graph: Girder + startNode: start + targetNode: reinforcedWall + category: construction-category-structures + description: Keeps the air in and the greytide out. + icon: + sprite: Structures/Walls/solid.rsi + state: rgeneric + objectType: Structure + placementMode: SnapgridCenter + canRotate: false + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: clock wall + id: WallClock + graph: ClockworkGirder + startNode: start + targetNode: clockworkWall + category: construction-category-structures + description: Keeps the air in and the greytide out. + icon: + sprite: Structures/Walls/clock.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canRotate: false + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked +# here +- type: construction + name: wood wall + id: WoodWall + graph: Girder + startNode: start + targetNode: woodWall + category: construction-category-structures + description: Keeps the air in and the greytide out. + icon: + sprite: Structures/Walls/wood.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canRotate: false + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: uranium wall + id: UraniumWall + graph: Girder + startNode: start + targetNode: uraniumWall + category: construction-category-structures + description: Keeps the air in and the greytide out. + icon: + sprite: Structures/Walls/uranium.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canRotate: false + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: silver wall + id: SilverWall + graph: Girder + startNode: start + targetNode: silverWall + category: construction-category-structures + description: Keeps the air in and the greytide out. + icon: + sprite: Structures/Walls/silver.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canRotate: false + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: plastic wall + id: PlasticWall + graph: Girder + startNode: start + targetNode: plasticWall + category: construction-category-structures + description: Keeps the air in and the greytide out. + icon: + sprite: Structures/Walls/plastic.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canRotate: false + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: plasma wall + id: PlasmaWall + graph: Girder + startNode: start + targetNode: plasmaWall + category: construction-category-structures + description: Keeps the air in and the greytide out. + icon: + sprite: Structures/Walls/plasma.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canRotate: false + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: gold wall + id: GoldWall + graph: Girder + startNode: start + targetNode: goldWall + category: construction-category-structures + description: Keeps the air in and the greytide out. + icon: + sprite: Structures/Walls/gold.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canRotate: false + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: shuttle wall + id: ShuttleWall + graph: Girder + startNode: start + targetNode: shuttleWall + category: construction-category-structures + description: Keeps the air in and the greytide out. + icon: + sprite: Structures/Walls/shuttle.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canRotate: false + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: interior shuttle wall + id: InteriorShuttleWall + graph: Girder + startNode: start + targetNode: shuttleInteriorWall + category: construction-category-structures + description: Keeps the air in and the greytide out. + icon: + sprite: Structures/Walls/shuttleinterior.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canRotate: false + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: diagonal shuttle wall + id: DiagonalShuttleWall + graph: Girder + startNode: start + targetNode: diagonalshuttleWall + category: construction-category-structures + description: Keeps the air in and the greytide out. + icon: + sprite: Structures/Walls/shuttle_diagonal.rsi + state: state0 + objectType: Structure + placementMode: SnapgridCenter + canRotate: true + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: bananium wall + id: ClownWall + graph: Girder + startNode: start + targetNode: bananiumWall + category: construction-category-structures + description: Keeps the air in and the greytide out. + icon: + sprite: Structures/Walls/clown.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canRotate: false + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: meat wall + id: MeatWall + graph: Girder + startNode: start + targetNode: meatWall + category: construction-category-structures + description: Sticky. + icon: + sprite: Structures/Walls/meat.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canRotate: false + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked - type: construction name: grille @@ -322,57 +322,57 @@ placementMode: SnapgridCenter canRotate: false -#- type: construction -# name: clockwork grille -# id: ClockGrille -# graph: ClockGrille -# startNode: start -# targetNode: clockGrille -# category: construction-category-structures -# description: A flimsy framework of iron rods assembled in traditional ratvarian fashion. -# conditions: -# - !type:TileNotBlocked -# failIfSpace: false -# icon: -# sprite: Structures/Walls/clockwork_grille.rsi -# state: ratvargrille -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: false -# -#- type: construction -# name: diagonal grille -# id: GrilleDiagonal -# graph: GrilleDiagonal -# startNode: start -# targetNode: grilleDiagonal -# category: construction-category-structures -# description: A flimsy framework of iron rods. -# conditions: -# - !type:TileNotBlocked -# failIfSpace: false -# icon: -# sprite: Structures/Walls/grille.rsi -# state: grille_diagonal -# objectType: Structure -# placementMode: SnapgridCenter -# -#- type: construction -# name: diagonal clockwork grille -# id: ClockworkGrilleDiagonal -# graph: GrilleDiagonal -# startNode: start -# targetNode: clockworkGrilleDiagonal -# category: construction-category-structures -# description: A flimsy framework of iron rods assembled in traditional ratvarian fashion. -# conditions: -# - !type:TileNotBlocked -# failIfSpace: false -# icon: -# sprite: Structures/Walls/clockwork_grille.rsi -# state: ratvargrille_diagonal -# objectType: Structure -# placementMode: SnapgridCenter +- type: construction + name: clockwork grille + id: ClockGrille + graph: ClockGrille + startNode: start + targetNode: clockGrille + category: construction-category-structures + description: A flimsy framework of iron rods assembled in traditional ratvarian fashion. + conditions: + - !type:TileNotBlocked + failIfSpace: false + icon: + sprite: Structures/Walls/clockwork_grille.rsi + state: ratvargrille + objectType: Structure + placementMode: SnapgridCenter + canRotate: false + +- type: construction + name: diagonal grille + id: GrilleDiagonal + graph: GrilleDiagonal + startNode: start + targetNode: grilleDiagonal + category: construction-category-structures + description: A flimsy framework of iron rods. + conditions: + - !type:TileNotBlocked + failIfSpace: false + icon: + sprite: Structures/Walls/grille.rsi + state: grille_diagonal + objectType: Structure + placementMode: SnapgridCenter + +- type: construction + name: diagonal clockwork grille + id: ClockworkGrilleDiagonal + graph: GrilleDiagonal + startNode: start + targetNode: clockworkGrilleDiagonal + category: construction-category-structures + description: A flimsy framework of iron rods assembled in traditional ratvarian fashion. + conditions: + - !type:TileNotBlocked + failIfSpace: false + icon: + sprite: Structures/Walls/clockwork_grille.rsi + state: ratvargrille_diagonal + objectType: Structure + placementMode: SnapgridCenter - type: construction name: window @@ -393,23 +393,23 @@ placementMode: SnapgridCenter canRotate: false -#- type: construction -# name: diagonal window -# id: WindowDiagonal -# graph: WindowDiagonal -# startNode: start -# targetNode: windowDiagonal -# category: construction-category-structures -# description: Clear. -# canBuildInImpassable: true -# conditions: -# - !type:EmptyOrWindowValidInTile -# - !type:NoWindowsInTile -# icon: -# sprite: Structures/Windows/window_diagonal.rsi -# state: state1 -# objectType: Structure -# placementMode: SnapgridCenter +- type: construction + name: diagonal window + id: WindowDiagonal + graph: WindowDiagonal + startNode: start + targetNode: windowDiagonal + category: construction-category-structures + description: Clear. + canBuildInImpassable: true + conditions: + - !type:EmptyOrWindowValidInTile + - !type:NoWindowsInTile + icon: + sprite: Structures/Windows/window_diagonal.rsi + state: state1 + objectType: Structure + placementMode: SnapgridCenter - type: construction name: reinforced window @@ -430,1231 +430,1231 @@ placementMode: SnapgridCenter canRotate: false -#- type: construction -# name: diagonal reinforced window -# id: ReinforcedWindowDiagonal -# graph: WindowDiagonal -# startNode: start -# targetNode: reinforcedWindowDiagonal -# category: construction-category-structures -# description: Clear but tough. -# canBuildInImpassable: true -# conditions: -# - !type:EmptyOrWindowValidInTile -# - !type:NoWindowsInTile -# icon: -# sprite: Structures/Windows/reinforced_window_diagonal.rsi -# state: state1 -# objectType: Structure -# placementMode: SnapgridCenter -# -#- type: construction -# name: tinted window -# id: TintedWindow -# graph: Window -# startNode: start -# targetNode: tintedWindow -# category: construction-category-structures -# description: Not clear but tough. -# canBuildInImpassable: true -# conditions: -# - !type:EmptyOrWindowValidInTile -# - !type:NoWindowsInTile -# icon: -# sprite: Structures/Windows/tinted_window.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: false -# -#- type: construction -# name: clockwork window -# id: ClockworkWindow -# graph: Window -# startNode: start -# targetNode: clockworkWindow -# category: construction-category-structures -# description: Clear and tough, with a golden tint. -# canBuildInImpassable: true -# conditions: -# - !type:EmptyOrWindowValidInTile -# - !type:NoWindowsInTile -# icon: -# sprite: Structures/Windows/clockwork_window.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: false -# -#- type: construction -# name: diagonal clockwork window -# id: ClockworkWindowDiagonal -# graph: WindowDiagonal -# startNode: start -# targetNode: clockworkWindowDiagonal -# category: construction-category-structures -# description: Clear and tough, with a golden tint. -# canBuildInImpassable: true -# conditions: -# - !type:EmptyOrWindowValidInTile -# - !type:NoWindowsInTile -# icon: -# sprite: Structures/Windows/clockwork_diagonal.rsi -# state: state0 -# objectType: Structure -# placementMode: SnapgridCenter -# -#- type: construction -# name: plasma window -# id: PlasmaWindow -# graph: Window -# startNode: start -# targetNode: plasmaWindow -# category: construction-category-structures -# canBuildInImpassable: true -# description: Clear and even tougher, with a purple tint. -# conditions: -# - !type:EmptyOrWindowValidInTile -# - !type:NoWindowsInTile -# icon: -# sprite: Structures/Windows/plasma_window.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: false -# -#- type: construction -# name: reinforced plasma window -# id: ReinforcedPlasmaWindow -# graph: Window -# startNode: start -# targetNode: reinforcedPlasmaWindow -# category: construction-category-structures -# canBuildInImpassable: true -# description: Fire resistant and even tougher, with a purple tint. -# conditions: -# - !type:EmptyOrWindowValidInTile -# - !type:NoWindowsInTile -# icon: -# sprite: Structures/Windows/reinforced_plasma_window.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: false -# -#- type: construction -# name: shuttle window -# id: ShuttleWindow -# graph: Window -# startNode: start -# targetNode: shuttleWindow -# category: construction-category-structures -# canBuildInImpassable: true -# description: Extra sturdy to resist the pressure of FTL or sustain damage from munitions. -# conditions: -# - !type:EmptyOrWindowValidInTile -# - !type:NoWindowsInTile -# icon: -# sprite: Structures/Windows/shuttle_window.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: false -# -#- type: construction -# name: diagonal plasma window -# id: PlasmaWindowDiagonal -# graph: WindowDiagonal -# startNode: start -# targetNode: plasmaWindowDiagonal -# category: construction-category-structures -# canBuildInImpassable: true -# description: Clear and even tougher, with a purple tint. -# conditions: -# - !type:EmptyOrWindowValidInTile -# - !type:NoWindowsInTile -# icon: -# sprite: Structures/Windows/plasma_diagonal.rsi -# state: state1 -# objectType: Structure -# placementMode: SnapgridCenter -# -#- type: construction -# name: diagonal reinforced plasma window -# id: ReinforcedPlasmaWindowDiagonal -# graph: WindowDiagonal -# startNode: start -# targetNode: reinforcedPlasmaWindowDiagonal -# category: construction-category-structures -# canBuildInImpassable: true -# description: Fire resistant and even tougher, with a purple tint. -# conditions: -# - !type:EmptyOrWindowValidInTile -# - !type:NoWindowsInTile -# icon: -# sprite: Structures/Windows/reinforced_plasma_diagonal.rsi -# state: state1 -# objectType: Structure -# placementMode: SnapgridCenter -# -#- type: construction -# name: directional window -# id: WindowDirectional -# graph: WindowDirectional -# startNode: start -# targetNode: windowDirectional -# category: construction-category-structures -# description: Clear. -# canBuildInImpassable: true -# conditions: -# - !type:EmptyOrWindowValidInTile -# - !type:NoWindowsInTile -# icon: -# sprite: Structures/Windows/directional.rsi -# state: window -# objectType: Structure -# placementMode: SnapgridCenter -# -#- type: construction -# name: directional reinforced window -# id: WindowReinforcedDirectional -# graph: WindowDirectional -# startNode: start -# targetNode: windowReinforcedDirectional -# category: construction-category-structures -# description: Clear but tough. -# canBuildInImpassable: true -# conditions: -# - !type:EmptyOrWindowValidInTile -# - !type:NoWindowsInTile -# icon: -# sprite: Structures/Windows/directional.rsi -# state: reinforced_window -# objectType: Structure -# placementMode: SnapgridCenter -# -#- type: construction -# name: directional clockwork window -# id: WindowClockworkDirectional -# graph: WindowDirectional -# startNode: start -# targetNode: windowClockworkDirectional -# category: construction-category-structures -# description: Clear and tough, with a golden tint. -# canBuildInImpassable: true -# conditions: -# - !type:EmptyOrWindowValidInTile -# - !type:NoWindowsInTile -# icon: -# sprite: Structures/Windows/directional.rsi -# state: clock_window -# objectType: Structure -# placementMode: SnapgridCenter -# -#- type: construction -# name: directional plasma window -# id: PlasmaWindowDirectional -# graph: WindowDirectional -# startNode: start -# targetNode: plasmaWindowDirectional -# category: construction-category-structures -# canBuildInImpassable: true -# description: Clear and even tougher, with a purple tint. -# conditions: -# - !type:EmptyOrWindowValidInTile -# - !type:NoWindowsInTile -# icon: -# sprite: Structures/Windows/directional.rsi -# state: plasma_window -# objectType: Structure -# placementMode: SnapgridCenter -# -#- type: construction -# name: directional reinforced plasma window -# id: PlasmaReinforcedWindowDirectional -# graph: WindowDirectional -# startNode: start -# targetNode: plasmaReinforcedWindowDirectional -# category: construction-category-structures -# canBuildInImpassable: true -# description: Fire resistant and even tougher, with a purple tint. -# conditions: -# - !type:EmptyOrWindowValidInTile -# - !type:NoWindowsInTile -# icon: -# sprite: Structures/Windows/directional.rsi -# state: plasma_reinforced_window -# objectType: Structure -# placementMode: SnapgridCenter -# -#- type: construction -# name: uranium window -# id: UraniumWindow -# graph: Window -# startNode: start -# targetNode: uraniumWindow -# category: construction-category-structures -# canBuildInImpassable: true -# description: Clear and much tougher than regular glass, with added RadAbsorb to protect you from deadly radiation. -# conditions: -# - !type:EmptyOrWindowValidInTile -# - !type:NoWindowsInTile -# icon: -# sprite: Structures/Windows/uranium_window.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: false -# -#- type: construction -# name: reinforced uranium window -# id: ReinforcedUraniumWindow -# graph: Window -# startNode: start -# targetNode: reinforcedUraniumWindow -# category: construction-category-structures -# canBuildInImpassable: true -# description: Clear and much tougher than regular glass, with added RadAbsorb to protect you from deadly radiation. -# conditions: -# - !type:EmptyOrWindowValidInTile -# - !type:NoWindowsInTile -# icon: -# sprite: Structures/Windows/reinforced_uranium_window.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: false -# -#- type: construction -# name: diagonal uranium window -# id: UraniumWindowDiagonal -# graph: WindowDiagonal -# startNode: start -# targetNode: uraniumWindowDiagonal -# category: construction-category-structures -# canBuildInImpassable: true -# description: Clear and much tougher than regular glass, with added RadAbsorb to protect you from deadly radiation. -# conditions: -# - !type:EmptyOrWindowValidInTile -# - !type:NoWindowsInTile -# icon: -# sprite: Structures/Windows/uranium_window_diagonal.rsi -# state: state1 -# objectType: Structure -# placementMode: SnapgridCenter -# -#- type: construction -# name: diagonal reinforced uranium window -# id: ReinforcedUraniumWindowDiagonal -# graph: WindowDiagonal -# startNode: start -# targetNode: reinforcedUraniumWindowDiagonal -# category: construction-category-structures -# canBuildInImpassable: true -# description: Clear and much tougher than regular glass, with added RadAbsorb to protect you from deadly radiation. -# conditions: -# - !type:EmptyOrWindowValidInTile -# - !type:NoWindowsInTile -# icon: -# sprite: Structures/Windows/reinforced_uranium_diagonal.rsi -# state: state1 -# objectType: Structure -# placementMode: SnapgridCenter -# -#- type: construction -# name: firelock -# id: Firelock -# graph: Firelock -# startNode: start -# targetNode: Firelock -# category: construction-category-structures -# description: This is a firelock - it locks an area when a fire alarm in the area is triggered. Don't get squished! -# icon: -# sprite: Structures/Doors/Airlocks/Standard/firelock.rsi -# state: closed -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: glass firelock -# id: FirelockGlass -# graph: Firelock -# startNode: start -# targetNode: FirelockGlass -# category: construction-category-structures -# description: This is a firelock - it locks an area when a fire alarm in the area is triggered. Don't get squished! -# icon: -# sprite: Structures/Doors/Airlocks/Glass/firelock.rsi -# state: closed -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: shutter -# id: Shutters -# graph: Shutters -# startNode: start -# targetNode: Shutters -# category: construction-category-structures -# description: This is a shutter - connect it to a button to open and close it. -# icon: -# sprite: Structures/Doors/Shutters/shutters.rsi -# state: closed -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: true -# -#- type: construction -# name: glass shutter -# id: ShuttersWindow -# graph: Shutters -# startNode: start -# targetNode: ShuttersWindow -# category: construction-category-structures -# description: This is a shutter - connect it to a button to open and close it. -# icon: -# sprite: Structures/Doors/Shutters/shutters_window.rsi -# state: closed -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: true -# -#- type: construction -# name: radiation shutter -# id: ShuttersRadiation -# graph: Shutters -# startNode: start -# targetNode: ShuttersRadiation -# category: construction-category-structures -# description: This is a shutter - connect it to a button to open and close it. -# icon: -# sprite: Structures/Doors/Shutters/shutters_radiation.rsi -# state: closed -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: true -# -#- type: construction -# name: blast door -# id: BlastDoor -# graph: BlastDoor -# startNode: start -# targetNode: blastdoor -# category: construction-category-structures -# description: This one says 'BLAST DONGER'. -# icon: -# sprite: Structures/Doors/Shutters/blastdoor.rsi -# state: closed -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: true -# -#- type: construction -# name: catwalk -# id: Catwalk -# graph: Catwalk -# startNode: start -# targetNode: Catwalk -# category: construction-category-structures -# description: Just like a lattice. Except it looks better. -# conditions: -# - !type:TileNotBlocked -# failIfSpace: false -# - !type:TileType -# targets: -# - Lattice -# - Plating -# icon: -# sprite: Structures/catwalk.rsi -# state: catwalk_preview -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# -#- type: construction -# name: bananium floor -# id: FloorBananium -# graph: FloorBananium -# startNode: start -# targetNode: BananiumFloor -# category: construction-category-structures -# description: A slippery floor of bright yellow bananium. -# conditions: -# - !type:TileNotBlocked -# failIfSpace: false -# - !type:TileType -# targets: -# - Plating -# icon: -# sprite: Tiles/Misc/bananium.rsi -# state: bananium -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# -#- type: construction -# name: wooden barricade -# id: Barricade -# graph: Barricade -# startNode: start -# targetNode: barricadefull -# category: construction-category-structures -# description: An improvised barricade made out of wooden planks. -# icon: -# sprite: Structures/barricades.rsi -# state: barricade_full -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: wooden barricade -# id: BarricadeDirectional -# graph: BarricadeDirectional -# startNode: start -# targetNode: barricadefull -# category: construction-category-structures -# description: An improvised barricade made out of wooden planks. -# icon: -# sprite: Structures/barricades.rsi -# state: barricade_directional -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: railing -# id: Railing -# graph: Railing -# startNode: start -# targetNode: railing -# category: construction-category-structures -# description: Basic railing meant to protect idiots like you from falling. -# icon: -# sprite: Structures/Walls/railing.rsi -# state: side -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: railing corner -# id: RailingCorner -# graph: Railing -# startNode: start -# targetNode: railingCorner -# category: construction-category-structures -# description: Basic railing meant to protect idiots like you from falling. -# icon: -# sprite: Structures/Walls/railing.rsi -# state: corner -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: railing corner small -# id: RailingCornerSmall -# graph: Railing -# startNode: start -# targetNode: railingCornerSmall -# category: construction-category-structures -# description: Basic railing meant to protect idiots like you from falling. -# icon: -# sprite: Structures/Walls/railing.rsi -# state: corner_small -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: railing round -# id: RailingRound -# graph: Railing -# startNode: start -# targetNode: railingRound -# category: construction-category-structures -# description: Basic railing meant to protect idiots like you from falling. -# icon: -# sprite: Structures/Walls/railing.rsi -# state: round -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -## Chain link fencing -#- type: construction -# name: chain link fence -# id: FenceMetal -# graph: FenceMetal -# startNode: start -# targetNode: straight -# category: construction-category-structures -# description: Part of a chain link fence meant to cordon off areas. -# icon: -# sprite: Structures/Walls/fence.rsi -# state: straight -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: chain link fence corner -# id: FenceMetalCorner -# graph: FenceMetal -# startNode: start -# targetNode: corner -# category: construction-category-structures -# description: Part of a chain link fence meant to cordon off areas. -# icon: -# sprite: Structures/Walls/fence.rsi -# state: corner -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: chain link fence end-piece -# id: FenceMetalEnd -# graph: FenceMetal -# startNode: start -# targetNode: end -# category: construction-category-structures -# description: Part of a chain link fence meant to cordon off areas. -# icon: -# sprite: Structures/Walls/fence.rsi -# state: end -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: chain link fence gate -# id: FenceMetalGate -# graph: FenceMetal -# startNode: start -# targetNode: gate -# category: construction-category-structures -# description: An easy way to get through a chain link fence. -# icon: -# sprite: Structures/Walls/fence.rsi -# state: door_closed -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -##Wooden fence high -#- type: construction -# name: wooden high fence -# id: FenceWood -# graph: FenceWood -# startNode: start -# targetNode: straight -# category: construction-category-structures -# description: Part of a wooden fence meant to cordon off areas. -# icon: -# sprite: Structures/Walls/wooden_fence.rsi -# state: straight -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: wooden high fence end -# id: FenceWoodEnd -# graph: FenceWood -# startNode: start -# targetNode: end -# category: construction-category-structures -# description: Part of a wooden fence meant to cordon off areas. -# icon: -# sprite: Structures/Walls/wooden_fence.rsi -# state: end -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: wooden high fence corner -# id: FenceWoodCorner -# graph: FenceWood -# startNode: start -# targetNode: corner -# category: construction-category-structures -# description: Part of a wooden fence meant to cordon off areas. -# icon: -# sprite: Structures/Walls/wooden_fence.rsi -# state: corner -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: wooden high fence t-junction -# id: FenceWoodTJunction -# graph: FenceWood -# startNode: start -# targetNode: tjunction -# category: construction-category-structures -# description: Part of a wooden fence meant to cordon off areas. -# icon: -# sprite: Structures/Walls/wooden_fence.rsi -# state: tjunction -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: wooden high fence gate -# id: FenceWoodGate -# graph: FenceWood -# startNode: start -# targetNode: gate -# category: construction-category-structures -# description: Part of a wooden fence meant to cordon off areas. -# icon: -# sprite: Structures/Walls/wooden_fence.rsi -# state: door_closed -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -##Wooden fence small -#- type: construction -# name: wooden small fence -# id: FenceWoodSmall -# graph: FenceWood -# startNode: start -# targetNode: straight_small -# category: construction-category-structures -# description: Part of a wooden fence meant to cordon off areas. -# icon: -# sprite: Structures/Walls/wooden_fence.rsi -# state: straight_small -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: wooden small fence end -# id: FenceWoodEndSmall -# graph: FenceWood -# startNode: start -# targetNode: end_small -# category: construction-category-structures -# description: Part of a wooden fence meant to cordon off areas. -# icon: -# sprite: Structures/Walls/wooden_fence.rsi -# state: end_small -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: wooden small fence corner -# id: FenceWoodCornerSmall -# graph: FenceWood -# startNode: start -# targetNode: corner_small -# category: construction-category-structures -# description: Part of a wooden fence meant to cordon off areas. -# icon: -# sprite: Structures/Walls/wooden_fence.rsi -# state: corner_small -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: wooden small fence t-junction -# id: FenceWoodTJunctionSmall -# graph: FenceWood -# startNode: start -# targetNode: tjunction_small -# category: construction-category-structures -# description: Part of a wooden fence meant to cordon off areas. -# icon: -# sprite: Structures/Walls/wooden_fence.rsi -# state: tjunction_small -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: wooden small fence gate -# id: FenceWoodGateSmall -# graph: FenceWood -# startNode: start -# targetNode: gate_small -# category: construction-category-structures -# description: Part of a wooden fence meant to cordon off areas. -# icon: -# sprite: Structures/Walls/wooden_fence.rsi -# state: door_closed_small -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -##Airlocks -#- type: construction -# name: airlock -# id: Airlock -# graph: Airlock -# startNode: start -# targetNode: airlock -# category: construction-category-structures -# description: It opens, it closes, and maybe crushes you. -# icon: -# sprite: Structures/Doors/Airlocks/Standard/basic.rsi -# state: assembly -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: glass airlock -# id: AirlockGlass -# graph: Airlock -# startNode: start -# targetNode: glassAirlock -# category: construction-category-structures -# description: It opens, it closes, and maybe crushes you. -# icon: -# sprite: Structures/Doors/Airlocks/Glass/glass.rsi -# state: assembly -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: pinion airlock -# id: PinionAirlock -# graph: PinionAirlock -# startNode: start -# targetNode: airlock -# category: construction-category-structures -# description: It opens, it closes, and maybe crushes you. -# icon: -# sprite: Structures/Doors/Airlocks/Standard/clockwork_pinion.rsi -# state: assembly -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: glass pinion airlock -# id: PinionAirlockGlass -# graph: PinionAirlock -# startNode: start -# targetNode: glassAirlock -# category: construction-category-structures -# description: It opens, it closes, and maybe crushes you. -# icon: -# sprite: Structures/Doors/Airlocks/Glass/clockwork_pinion.rsi -# state: assembly -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: shuttle airlock -# id: AirlockShuttle -# graph: AirlockShuttle -# startNode: start -# targetNode: airlock -# category: construction-category-structures -# description: It opens, it closes, and maybe crushes you. Necessary for connecting two space craft together. -# icon: -# sprite: Structures/Doors/Airlocks/Glass/shuttle.rsi -# state: closed -# # state: assembly -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: glass shuttle airlock -# id: AirlockGlassShuttle -# graph: AirlockShuttle -# startNode: start -# targetNode: airlockGlass -# category: construction-category-structures -# description: It opens, it closes, and maybe crushes you. Necessary for connecting two space craft together. This one has a window. -# icon: -# sprite: Structures/Doors/Airlocks/Glass/shuttle.rsi -# state: closed -# # state: assembly -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: windoor -# id: Windoor -# graph: Windoor -# startNode: start -# targetNode: windoor -# category: construction-category-structures -# description: It opens, it closes, and you can see through it! And it can be made of Plasma, Uranium, or normal Glass! -# icon: -# sprite: Structures/Doors/Windoors/windoor.rsi -# state: closed -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: secure windoor -# id: SecureWindoor -# graph: Windoor -# startNode: start -# targetNode: windoorSecure -# category: construction-category-structures -# description: It's tough, it's a door, and you can see through it! And it can be made of Plasma, Uranium, or normal Glass! -# icon: -# sprite: Structures/Doors/Windoors/windoor.rsi -# state: closed -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: clockwork windoor -# id: ClockworkWindoor -# graph: Windoor -# startNode: start -# targetNode: windoorClockwork -# category: construction-category-structures -# description: It opens, it closes, and you can see through it! This one looks tough. -# icon: -# sprite: Structures/Doors/Windoors/clockwork_windoor.rsi -# state: closed -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -##lighting -#- type: construction -# name: wall light -# id: LightTubeFixture -# graph: LightFixture -# startNode: start -# targetNode: tubeLight -# category: construction-category-structures -# description: A wall light fixture. Use light tubes. -# icon: -# sprite: Structures/Wallmounts/Lighting/light_tube.rsi -# state: base -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: true -# canBuildInImpassable: false -# conditions: -# # Need an *additional* condition here that forces there to be a wall in the opposite direction to the one used for placement. -# # Also see below. Didn't add it b/c construction ECS work going on. Cheers, - 20kdc -# - !type:TileNotBlocked -# -#- type: construction -# name: small wall light -# id: LightSmallFixture -# graph: LightFixture -# startNode: start -# targetNode: bulbLight -# category: construction-category-structures -# description: A wall light fixture. Use light bulbs. -# icon: -# sprite: Structures/Wallmounts/Lighting/light_small.rsi -# state: base -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: true -# canBuildInImpassable: false -# conditions: -# # Same here. - 20kdc -# - !type:TileNotBlocked -# -#- type: construction -# name: ground light post -# id: LightGroundFixture -# graph: LightFixture -# startNode: start -# targetNode: groundLight -# category: construction-category-structures -# description: A ground light fixture. Use light bulbs. -# icon: -# sprite: Structures/Lighting/LightPosts/small_light_post.rsi -# state: base -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: false -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -##conveyor -#- type: construction -# name: conveyor belt -# id: ConveyorBelt -# graph: ConveyorGraph -# startNode: start -# targetNode: entity -# category: construction-category-structures -# description: A conveyor belt, commonly used to transport large numbers of items elsewhere quite quickly. -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/conveyor.rsi -# state: conveyor_stopped_cw -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: metal door -# id: MetalDoor -# graph: DoorGraph -# startNode: start -# targetNode: metalDoor -# category: construction-category-structures -# description: A primitive door with manual operation like the cavemen used. -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Doors/MineralDoors/metal_door.rsi -# state: closed -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: wooden door -# id: WoodDoor -# graph: DoorGraph -# startNode: start -# targetNode: woodDoor -# category: construction-category-structures -# description: A primitive door with manual operation like the cavemen used. -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Doors/MineralDoors/wood_door.rsi -# state: closed -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: plasma door -# id: PlasmaDoor -# graph: DoorGraph -# startNode: start -# targetNode: plasmaDoor -# category: construction-category-structures -# description: A primitive door with manual operation like the cavemen used. -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Doors/MineralDoors/plasma_door.rsi -# state: closed -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: gold door -# id: GoldDoor -# graph: DoorGraph -# startNode: start -# targetNode: goldDoor -# category: construction-category-structures -# description: A primitive door with manual operation like the cavemen used. -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Doors/MineralDoors/gold_door.rsi -# state: closed -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: silver door -# id: SilverDoor -# graph: DoorGraph -# startNode: start -# targetNode: silverDoor -# category: construction-category-structures -# description: A primitive door with manual operation like the cavemen used. -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Doors/MineralDoors/silver_door.rsi -# state: closed -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: paper door -# id: PaperDoor -# graph: DoorGraph -# startNode: start -# targetNode: paperDoor -# category: construction-category-structures -# description: A primitive door with manual operation like the cavemen used. -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Doors/MineralDoors/paper_door.rsi -# state: closed -# -#- type: construction -# name: plastic flaps -# id: PlasticFlapsClear -# graph: PlasticFlapsGraph -# startNode: start -# targetNode: plasticFlaps -# category: construction-category-structures -# placementMode: SnapgridCenter -# description: A plastic flap to let items through and keep people out. -# objectType: Structure -# canBuildInImpassable: false -# icon: -# sprite: Structures/plastic_flaps.rsi -# state: plasticflaps -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: bananium clown statue -# id: BananiumClownStatue -# graph: BananiumStatueClown -# startNode: start -# targetNode: bananiumStatue -# category: construction-category-structures -# placementMode: SnapgridCenter -# description: A clown statue made from bananium. -# objectType: Structure -# canBuildInImpassable: false -# icon: -# sprite: Structures/Decoration/statues.rsi -# state: bananium_clown -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: bananium door -# id: BananiumDoor -# graph: DoorGraph -# startNode: start -# targetNode: bananiumDoor -# category: construction-category-structures -# description: A primitive door made from bananium, it honks. -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Doors/MineralDoors/bananium_door.rsi -# state: closed -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: bananium altar -# id: BananiumAltar -# graph: BananiumAltarGraph -# startNode: start -# targetNode: bananiumAltar -# category: construction-category-structures -# description: An altar to worship the honkmother with. -# icon: -# sprite: Structures/Furniture/Altars/Cults/bananium.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: false -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: solid secret door -# id: SolidSecretDoor -# graph: SecretDoor -# startNode: start -# targetNode: solidSecretDoor -# category: construction-category-structures -# description: A secret door for the wall. -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Doors/secret_door.rsi -# state: closed -# conditions: -# - !type:TileNotBlocked +- type: construction + name: diagonal reinforced window + id: ReinforcedWindowDiagonal + graph: WindowDiagonal + startNode: start + targetNode: reinforcedWindowDiagonal + category: construction-category-structures + description: Clear but tough. + canBuildInImpassable: true + conditions: + - !type:EmptyOrWindowValidInTile + - !type:NoWindowsInTile + icon: + sprite: Structures/Windows/reinforced_window_diagonal.rsi + state: state1 + objectType: Structure + placementMode: SnapgridCenter + +- type: construction + name: tinted window + id: TintedWindow + graph: Window + startNode: start + targetNode: tintedWindow + category: construction-category-structures + description: Not clear but tough. + canBuildInImpassable: true + conditions: + - !type:EmptyOrWindowValidInTile + - !type:NoWindowsInTile + icon: + sprite: Structures/Windows/tinted_window.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canRotate: false + +- type: construction + name: clockwork window + id: ClockworkWindow + graph: Window + startNode: start + targetNode: clockworkWindow + category: construction-category-structures + description: Clear and tough, with a golden tint. + canBuildInImpassable: true + conditions: + - !type:EmptyOrWindowValidInTile + - !type:NoWindowsInTile + icon: + sprite: Structures/Windows/clockwork_window.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canRotate: false + +- type: construction + name: diagonal clockwork window + id: ClockworkWindowDiagonal + graph: WindowDiagonal + startNode: start + targetNode: clockworkWindowDiagonal + category: construction-category-structures + description: Clear and tough, with a golden tint. + canBuildInImpassable: true + conditions: + - !type:EmptyOrWindowValidInTile + - !type:NoWindowsInTile + icon: + sprite: Structures/Windows/clockwork_diagonal.rsi + state: state0 + objectType: Structure + placementMode: SnapgridCenter + +- type: construction + name: plasma window + id: PlasmaWindow + graph: Window + startNode: start + targetNode: plasmaWindow + category: construction-category-structures + canBuildInImpassable: true + description: Clear and even tougher, with a purple tint. + conditions: + - !type:EmptyOrWindowValidInTile + - !type:NoWindowsInTile + icon: + sprite: Structures/Windows/plasma_window.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canRotate: false + +- type: construction + name: reinforced plasma window + id: ReinforcedPlasmaWindow + graph: Window + startNode: start + targetNode: reinforcedPlasmaWindow + category: construction-category-structures + canBuildInImpassable: true + description: Fire resistant and even tougher, with a purple tint. + conditions: + - !type:EmptyOrWindowValidInTile + - !type:NoWindowsInTile + icon: + sprite: Structures/Windows/reinforced_plasma_window.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canRotate: false + +- type: construction + name: shuttle window + id: ShuttleWindow + graph: Window + startNode: start + targetNode: shuttleWindow + category: construction-category-structures + canBuildInImpassable: true + description: Extra sturdy to resist the pressure of FTL or sustain damage from munitions. + conditions: + - !type:EmptyOrWindowValidInTile + - !type:NoWindowsInTile + icon: + sprite: Structures/Windows/shuttle_window.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canRotate: false + +- type: construction + name: diagonal plasma window + id: PlasmaWindowDiagonal + graph: WindowDiagonal + startNode: start + targetNode: plasmaWindowDiagonal + category: construction-category-structures + canBuildInImpassable: true + description: Clear and even tougher, with a purple tint. + conditions: + - !type:EmptyOrWindowValidInTile + - !type:NoWindowsInTile + icon: + sprite: Structures/Windows/plasma_diagonal.rsi + state: state1 + objectType: Structure + placementMode: SnapgridCenter + +- type: construction + name: diagonal reinforced plasma window + id: ReinforcedPlasmaWindowDiagonal + graph: WindowDiagonal + startNode: start + targetNode: reinforcedPlasmaWindowDiagonal + category: construction-category-structures + canBuildInImpassable: true + description: Fire resistant and even tougher, with a purple tint. + conditions: + - !type:EmptyOrWindowValidInTile + - !type:NoWindowsInTile + icon: + sprite: Structures/Windows/reinforced_plasma_diagonal.rsi + state: state1 + objectType: Structure + placementMode: SnapgridCenter + +- type: construction + name: directional window + id: WindowDirectional + graph: WindowDirectional + startNode: start + targetNode: windowDirectional + category: construction-category-structures + description: Clear. + canBuildInImpassable: true + conditions: + - !type:EmptyOrWindowValidInTile + - !type:NoWindowsInTile + icon: + sprite: Structures/Windows/directional.rsi + state: window + objectType: Structure + placementMode: SnapgridCenter + +- type: construction + name: directional reinforced window + id: WindowReinforcedDirectional + graph: WindowDirectional + startNode: start + targetNode: windowReinforcedDirectional + category: construction-category-structures + description: Clear but tough. + canBuildInImpassable: true + conditions: + - !type:EmptyOrWindowValidInTile + - !type:NoWindowsInTile + icon: + sprite: Structures/Windows/directional.rsi + state: reinforced_window + objectType: Structure + placementMode: SnapgridCenter + +- type: construction + name: directional clockwork window + id: WindowClockworkDirectional + graph: WindowDirectional + startNode: start + targetNode: windowClockworkDirectional + category: construction-category-structures + description: Clear and tough, with a golden tint. + canBuildInImpassable: true + conditions: + - !type:EmptyOrWindowValidInTile + - !type:NoWindowsInTile + icon: + sprite: Structures/Windows/directional.rsi + state: clock_window + objectType: Structure + placementMode: SnapgridCenter + +- type: construction + name: directional plasma window + id: PlasmaWindowDirectional + graph: WindowDirectional + startNode: start + targetNode: plasmaWindowDirectional + category: construction-category-structures + canBuildInImpassable: true + description: Clear and even tougher, with a purple tint. + conditions: + - !type:EmptyOrWindowValidInTile + - !type:NoWindowsInTile + icon: + sprite: Structures/Windows/directional.rsi + state: plasma_window + objectType: Structure + placementMode: SnapgridCenter + +- type: construction + name: directional reinforced plasma window + id: PlasmaReinforcedWindowDirectional + graph: WindowDirectional + startNode: start + targetNode: plasmaReinforcedWindowDirectional + category: construction-category-structures + canBuildInImpassable: true + description: Fire resistant and even tougher, with a purple tint. + conditions: + - !type:EmptyOrWindowValidInTile + - !type:NoWindowsInTile + icon: + sprite: Structures/Windows/directional.rsi + state: plasma_reinforced_window + objectType: Structure + placementMode: SnapgridCenter + +- type: construction + name: uranium window + id: UraniumWindow + graph: Window + startNode: start + targetNode: uraniumWindow + category: construction-category-structures + canBuildInImpassable: true + description: Clear and much tougher than regular glass, with added RadAbsorb to protect you from deadly radiation. + conditions: + - !type:EmptyOrWindowValidInTile + - !type:NoWindowsInTile + icon: + sprite: Structures/Windows/uranium_window.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canRotate: false + +- type: construction + name: reinforced uranium window + id: ReinforcedUraniumWindow + graph: Window + startNode: start + targetNode: reinforcedUraniumWindow + category: construction-category-structures + canBuildInImpassable: true + description: Clear and much tougher than regular glass, with added RadAbsorb to protect you from deadly radiation. + conditions: + - !type:EmptyOrWindowValidInTile + - !type:NoWindowsInTile + icon: + sprite: Structures/Windows/reinforced_uranium_window.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canRotate: false + +- type: construction + name: diagonal uranium window + id: UraniumWindowDiagonal + graph: WindowDiagonal + startNode: start + targetNode: uraniumWindowDiagonal + category: construction-category-structures + canBuildInImpassable: true + description: Clear and much tougher than regular glass, with added RadAbsorb to protect you from deadly radiation. + conditions: + - !type:EmptyOrWindowValidInTile + - !type:NoWindowsInTile + icon: + sprite: Structures/Windows/uranium_window_diagonal.rsi + state: state1 + objectType: Structure + placementMode: SnapgridCenter + +- type: construction + name: diagonal reinforced uranium window + id: ReinforcedUraniumWindowDiagonal + graph: WindowDiagonal + startNode: start + targetNode: reinforcedUraniumWindowDiagonal + category: construction-category-structures + canBuildInImpassable: true + description: Clear and much tougher than regular glass, with added RadAbsorb to protect you from deadly radiation. + conditions: + - !type:EmptyOrWindowValidInTile + - !type:NoWindowsInTile + icon: + sprite: Structures/Windows/reinforced_uranium_diagonal.rsi + state: state1 + objectType: Structure + placementMode: SnapgridCenter + +- type: construction + name: firelock + id: Firelock + graph: Firelock + startNode: start + targetNode: Firelock + category: construction-category-structures + description: This is a firelock - it locks an area when a fire alarm in the area is triggered. Don't get squished! + icon: + sprite: Structures/Doors/Airlocks/Standard/firelock.rsi + state: closed + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: glass firelock + id: FirelockGlass + graph: Firelock + startNode: start + targetNode: FirelockGlass + category: construction-category-structures + description: This is a firelock - it locks an area when a fire alarm in the area is triggered. Don't get squished! + icon: + sprite: Structures/Doors/Airlocks/Glass/firelock.rsi + state: closed + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: shutter + id: Shutters + graph: Shutters + startNode: start + targetNode: Shutters + category: construction-category-structures + description: This is a shutter - connect it to a button to open and close it. + icon: + sprite: Structures/Doors/Shutters/shutters.rsi + state: closed + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: true + +- type: construction + name: glass shutter + id: ShuttersWindow + graph: Shutters + startNode: start + targetNode: ShuttersWindow + category: construction-category-structures + description: This is a shutter - connect it to a button to open and close it. + icon: + sprite: Structures/Doors/Shutters/shutters_window.rsi + state: closed + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: true + +- type: construction + name: radiation shutter + id: ShuttersRadiation + graph: Shutters + startNode: start + targetNode: ShuttersRadiation + category: construction-category-structures + description: This is a shutter - connect it to a button to open and close it. + icon: + sprite: Structures/Doors/Shutters/shutters_radiation.rsi + state: closed + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: true + +- type: construction + name: blast door + id: BlastDoor + graph: BlastDoor + startNode: start + targetNode: blastdoor + category: construction-category-structures + description: This one says 'BLAST DONGER'. + icon: + sprite: Structures/Doors/Shutters/blastdoor.rsi + state: closed + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: true + +- type: construction + name: catwalk + id: Catwalk + graph: Catwalk + startNode: start + targetNode: Catwalk + category: construction-category-structures + description: Just like a lattice. Except it looks better. + conditions: + - !type:TileNotBlocked + failIfSpace: false + - !type:TileType + targets: + - Lattice + - Plating + icon: + sprite: Structures/catwalk.rsi + state: catwalk_preview + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + +- type: construction + name: bananium floor + id: FloorBananium + graph: FloorBananium + startNode: start + targetNode: BananiumFloor + category: construction-category-structures + description: A slippery floor of bright yellow bananium. + conditions: + - !type:TileNotBlocked + failIfSpace: false + - !type:TileType + targets: + - Plating + icon: + sprite: Tiles/Misc/bananium.rsi + state: bananium + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + +- type: construction + name: wooden barricade + id: Barricade + graph: Barricade + startNode: start + targetNode: barricadefull + category: construction-category-structures + description: An improvised barricade made out of wooden planks. + icon: + sprite: Structures/barricades.rsi + state: barricade_full + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: wooden barricade + id: BarricadeDirectional + graph: BarricadeDirectional + startNode: start + targetNode: barricadefull + category: construction-category-structures + description: An improvised barricade made out of wooden planks. + icon: + sprite: Structures/barricades.rsi + state: barricade_directional + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: railing + id: Railing + graph: Railing + startNode: start + targetNode: railing + category: construction-category-structures + description: Basic railing meant to protect idiots like you from falling. + icon: + sprite: Structures/Walls/railing.rsi + state: side + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: railing corner + id: RailingCorner + graph: Railing + startNode: start + targetNode: railingCorner + category: construction-category-structures + description: Basic railing meant to protect idiots like you from falling. + icon: + sprite: Structures/Walls/railing.rsi + state: corner + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: railing corner small + id: RailingCornerSmall + graph: Railing + startNode: start + targetNode: railingCornerSmall + category: construction-category-structures + description: Basic railing meant to protect idiots like you from falling. + icon: + sprite: Structures/Walls/railing.rsi + state: corner_small + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: railing round + id: RailingRound + graph: Railing + startNode: start + targetNode: railingRound + category: construction-category-structures + description: Basic railing meant to protect idiots like you from falling. + icon: + sprite: Structures/Walls/railing.rsi + state: round + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +# Chain link fencing +- type: construction + name: chain link fence + id: FenceMetal + graph: FenceMetal + startNode: start + targetNode: straight + category: construction-category-structures + description: Part of a chain link fence meant to cordon off areas. + icon: + sprite: Structures/Walls/fence.rsi + state: straight + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: chain link fence corner + id: FenceMetalCorner + graph: FenceMetal + startNode: start + targetNode: corner + category: construction-category-structures + description: Part of a chain link fence meant to cordon off areas. + icon: + sprite: Structures/Walls/fence.rsi + state: corner + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: chain link fence end-piece + id: FenceMetalEnd + graph: FenceMetal + startNode: start + targetNode: end + category: construction-category-structures + description: Part of a chain link fence meant to cordon off areas. + icon: + sprite: Structures/Walls/fence.rsi + state: end + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: chain link fence gate + id: FenceMetalGate + graph: FenceMetal + startNode: start + targetNode: gate + category: construction-category-structures + description: An easy way to get through a chain link fence. + icon: + sprite: Structures/Walls/fence.rsi + state: door_closed + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +#Wooden fence high +- type: construction + name: wooden high fence + id: FenceWood + graph: FenceWood + startNode: start + targetNode: straight + category: construction-category-structures + description: Part of a wooden fence meant to cordon off areas. + icon: + sprite: Structures/Walls/wooden_fence.rsi + state: straight + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: wooden high fence end + id: FenceWoodEnd + graph: FenceWood + startNode: start + targetNode: end + category: construction-category-structures + description: Part of a wooden fence meant to cordon off areas. + icon: + sprite: Structures/Walls/wooden_fence.rsi + state: end + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: wooden high fence corner + id: FenceWoodCorner + graph: FenceWood + startNode: start + targetNode: corner + category: construction-category-structures + description: Part of a wooden fence meant to cordon off areas. + icon: + sprite: Structures/Walls/wooden_fence.rsi + state: corner + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: wooden high fence t-junction + id: FenceWoodTJunction + graph: FenceWood + startNode: start + targetNode: tjunction + category: construction-category-structures + description: Part of a wooden fence meant to cordon off areas. + icon: + sprite: Structures/Walls/wooden_fence.rsi + state: tjunction + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: wooden high fence gate + id: FenceWoodGate + graph: FenceWood + startNode: start + targetNode: gate + category: construction-category-structures + description: Part of a wooden fence meant to cordon off areas. + icon: + sprite: Structures/Walls/wooden_fence.rsi + state: door_closed + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +#Wooden fence small +- type: construction + name: wooden small fence + id: FenceWoodSmall + graph: FenceWood + startNode: start + targetNode: straight_small + category: construction-category-structures + description: Part of a wooden fence meant to cordon off areas. + icon: + sprite: Structures/Walls/wooden_fence.rsi + state: straight_small + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: wooden small fence end + id: FenceWoodEndSmall + graph: FenceWood + startNode: start + targetNode: end_small + category: construction-category-structures + description: Part of a wooden fence meant to cordon off areas. + icon: + sprite: Structures/Walls/wooden_fence.rsi + state: end_small + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: wooden small fence corner + id: FenceWoodCornerSmall + graph: FenceWood + startNode: start + targetNode: corner_small + category: construction-category-structures + description: Part of a wooden fence meant to cordon off areas. + icon: + sprite: Structures/Walls/wooden_fence.rsi + state: corner_small + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: wooden small fence t-junction + id: FenceWoodTJunctionSmall + graph: FenceWood + startNode: start + targetNode: tjunction_small + category: construction-category-structures + description: Part of a wooden fence meant to cordon off areas. + icon: + sprite: Structures/Walls/wooden_fence.rsi + state: tjunction_small + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: wooden small fence gate + id: FenceWoodGateSmall + graph: FenceWood + startNode: start + targetNode: gate_small + category: construction-category-structures + description: Part of a wooden fence meant to cordon off areas. + icon: + sprite: Structures/Walls/wooden_fence.rsi + state: door_closed_small + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +#Airlocks +- type: construction + name: airlock + id: Airlock + graph: Airlock + startNode: start + targetNode: airlock + category: construction-category-structures + description: It opens, it closes, and maybe crushes you. + icon: + sprite: Structures/Doors/Airlocks/Standard/basic.rsi + state: assembly + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: glass airlock + id: AirlockGlass + graph: Airlock + startNode: start + targetNode: glassAirlock + category: construction-category-structures + description: It opens, it closes, and maybe crushes you. + icon: + sprite: Structures/Doors/Airlocks/Glass/glass.rsi + state: assembly + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: pinion airlock + id: PinionAirlock + graph: PinionAirlock + startNode: start + targetNode: airlock + category: construction-category-structures + description: It opens, it closes, and maybe crushes you. + icon: + sprite: Structures/Doors/Airlocks/Standard/clockwork_pinion.rsi + state: assembly + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: glass pinion airlock + id: PinionAirlockGlass + graph: PinionAirlock + startNode: start + targetNode: glassAirlock + category: construction-category-structures + description: It opens, it closes, and maybe crushes you. + icon: + sprite: Structures/Doors/Airlocks/Glass/clockwork_pinion.rsi + state: assembly + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: shuttle airlock + id: AirlockShuttle + graph: AirlockShuttle + startNode: start + targetNode: airlock + category: construction-category-structures + description: It opens, it closes, and maybe crushes you. Necessary for connecting two space craft together. + icon: + sprite: Structures/Doors/Airlocks/Glass/shuttle.rsi + state: closed + # state: assembly + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: glass shuttle airlock + id: AirlockGlassShuttle + graph: AirlockShuttle + startNode: start + targetNode: airlockGlass + category: construction-category-structures + description: It opens, it closes, and maybe crushes you. Necessary for connecting two space craft together. This one has a window. + icon: + sprite: Structures/Doors/Airlocks/Glass/shuttle.rsi + state: closed + # state: assembly + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: windoor + id: Windoor + graph: Windoor + startNode: start + targetNode: windoor + category: construction-category-structures + description: It opens, it closes, and you can see through it! And it can be made of Plasma, Uranium, or normal Glass! + icon: + sprite: Structures/Doors/Windoors/windoor.rsi + state: closed + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: secure windoor + id: SecureWindoor + graph: Windoor + startNode: start + targetNode: windoorSecure + category: construction-category-structures + description: It's tough, it's a door, and you can see through it! And it can be made of Plasma, Uranium, or normal Glass! + icon: + sprite: Structures/Doors/Windoors/windoor.rsi + state: closed + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: clockwork windoor + id: ClockworkWindoor + graph: Windoor + startNode: start + targetNode: windoorClockwork + category: construction-category-structures + description: It opens, it closes, and you can see through it! This one looks tough. + icon: + sprite: Structures/Doors/Windoors/clockwork_windoor.rsi + state: closed + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +#lighting +- type: construction + name: wall light + id: LightTubeFixture + graph: LightFixture + startNode: start + targetNode: tubeLight + category: construction-category-structures + description: A wall light fixture. Use light tubes. + icon: + sprite: Structures/Wallmounts/Lighting/light_tube.rsi + state: base + objectType: Structure + placementMode: SnapgridCenter + canRotate: true + canBuildInImpassable: false + conditions: + # Need an *additional* condition here that forces there to be a wall in the opposite direction to the one used for placement. + # Also see below. Didn't add it b/c construction ECS work going on. Cheers, - 20kdc + - !type:TileNotBlocked + +- type: construction + name: small wall light + id: LightSmallFixture + graph: LightFixture + startNode: start + targetNode: bulbLight + category: construction-category-structures + description: A wall light fixture. Use light bulbs. + icon: + sprite: Structures/Wallmounts/Lighting/light_small.rsi + state: base + objectType: Structure + placementMode: SnapgridCenter + canRotate: true + canBuildInImpassable: false + conditions: + # Same here. - 20kdc + - !type:TileNotBlocked + +- type: construction + name: ground light post + id: LightGroundFixture + graph: LightFixture + startNode: start + targetNode: groundLight + category: construction-category-structures + description: A ground light fixture. Use light bulbs. + icon: + sprite: Structures/Lighting/LightPosts/small_light_post.rsi + state: base + objectType: Structure + placementMode: SnapgridCenter + canRotate: false + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +#conveyor +- type: construction + name: conveyor belt + id: ConveyorBelt + graph: ConveyorGraph + startNode: start + targetNode: entity + category: construction-category-structures + description: A conveyor belt, commonly used to transport large numbers of items elsewhere quite quickly. + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/conveyor.rsi + state: conveyor_stopped_cw + conditions: + - !type:TileNotBlocked + +- type: construction + name: metal door + id: MetalDoor + graph: DoorGraph + startNode: start + targetNode: metalDoor + category: construction-category-structures + description: A primitive door with manual operation like the cavemen used. + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Doors/MineralDoors/metal_door.rsi + state: closed + conditions: + - !type:TileNotBlocked + +- type: construction + name: wooden door + id: WoodDoor + graph: DoorGraph + startNode: start + targetNode: woodDoor + category: construction-category-structures + description: A primitive door with manual operation like the cavemen used. + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Doors/MineralDoors/wood_door.rsi + state: closed + conditions: + - !type:TileNotBlocked + +- type: construction + name: plasma door + id: PlasmaDoor + graph: DoorGraph + startNode: start + targetNode: plasmaDoor + category: construction-category-structures + description: A primitive door with manual operation like the cavemen used. + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Doors/MineralDoors/plasma_door.rsi + state: closed + conditions: + - !type:TileNotBlocked + +- type: construction + name: gold door + id: GoldDoor + graph: DoorGraph + startNode: start + targetNode: goldDoor + category: construction-category-structures + description: A primitive door with manual operation like the cavemen used. + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Doors/MineralDoors/gold_door.rsi + state: closed + conditions: + - !type:TileNotBlocked + +- type: construction + name: silver door + id: SilverDoor + graph: DoorGraph + startNode: start + targetNode: silverDoor + category: construction-category-structures + description: A primitive door with manual operation like the cavemen used. + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Doors/MineralDoors/silver_door.rsi + state: closed + conditions: + - !type:TileNotBlocked + +- type: construction + name: paper door + id: PaperDoor + graph: DoorGraph + startNode: start + targetNode: paperDoor + category: construction-category-structures + description: A primitive door with manual operation like the cavemen used. + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Doors/MineralDoors/paper_door.rsi + state: closed + +- type: construction + name: plastic flaps + id: PlasticFlapsClear + graph: PlasticFlapsGraph + startNode: start + targetNode: plasticFlaps + category: construction-category-structures + placementMode: SnapgridCenter + description: A plastic flap to let items through and keep people out. + objectType: Structure + canBuildInImpassable: false + icon: + sprite: Structures/plastic_flaps.rsi + state: plasticflaps + conditions: + - !type:TileNotBlocked + +- type: construction + name: bananium clown statue + id: BananiumClownStatue + graph: BananiumStatueClown + startNode: start + targetNode: bananiumStatue + category: construction-category-structures + placementMode: SnapgridCenter + description: A clown statue made from bananium. + objectType: Structure + canBuildInImpassable: false + icon: + sprite: Structures/Decoration/statues.rsi + state: bananium_clown + conditions: + - !type:TileNotBlocked + +- type: construction + name: bananium door + id: BananiumDoor + graph: DoorGraph + startNode: start + targetNode: bananiumDoor + category: construction-category-structures + description: A primitive door made from bananium, it honks. + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Doors/MineralDoors/bananium_door.rsi + state: closed + conditions: + - !type:TileNotBlocked + +- type: construction + name: bananium altar + id: BananiumAltar + graph: BananiumAltarGraph + startNode: start + targetNode: bananiumAltar + category: construction-category-structures + description: An altar to worship the honkmother with. + icon: + sprite: Structures/Furniture/Altars/Cults/bananium.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canRotate: false + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + name: solid secret door + id: SolidSecretDoor + graph: SecretDoor + startNode: start + targetNode: solidSecretDoor + category: construction-category-structures + description: A secret door for the wall. + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Doors/secret_door.rsi + state: closed + conditions: + - !type:TileNotBlocked diff --git a/Resources/Prototypes/Recipes/Construction/tools.yml b/Resources/Prototypes/Recipes/Construction/tools.yml index a8487d7030..a6d9e33f4c 100644 --- a/Resources/Prototypes/Recipes/Construction/tools.yml +++ b/Resources/Prototypes/Recipes/Construction/tools.yml @@ -1,43 +1,43 @@ -#- type: construction -# name: torch -# id: LightTorch -# graph: LightTorch -# startNode: start -# targetNode: torch -# category: construction-category-tools -# description: A torch fashioned from some wood. -# icon: { sprite: Objects/Misc/torch.rsi, state: icon } -# objectType: Item -# -#- type: construction -# name: logic gate -# id: LogicGate -# graph: LogicGate -# startNode: start -# targetNode: logic_gate -# category: construction-category-tools -# description: A binary logic gate for signals. -# icon: { sprite: Objects/Devices/gates.rsi, state: or_icon } -# objectType: Item -# -#- type: construction -# name: edge detector -# id: EdgeDetector -# graph: LogicGate -# startNode: start -# targetNode: edge_detector -# category: construction-category-tools -# description: An edge detector for signals. -# icon: { sprite: Objects/Devices/gates.rsi, state: edge_detector } -# objectType: Item -# -#- type: construction -# name: power sensor -# id: PowerSensor -# graph: LogicGate -# startNode: start -# targetNode: power_sensor -# category: construction-category-tools -# description: A power network checking device for signals. -# icon: { sprite: Objects/Devices/gates.rsi, state: power_sensor } -# objectType: Item +- type: construction + name: torch + id: LightTorch + graph: LightTorch + startNode: start + targetNode: torch + category: construction-category-tools + description: A torch fashioned from some wood. + icon: { sprite: Objects/Misc/torch.rsi, state: icon } + objectType: Item + +- type: construction + name: logic gate + id: LogicGate + graph: LogicGate + startNode: start + targetNode: logic_gate + category: construction-category-tools + description: A binary logic gate for signals. + icon: { sprite: Objects/Devices/gates.rsi, state: or_icon } + objectType: Item + +- type: construction + name: edge detector + id: EdgeDetector + graph: LogicGate + startNode: start + targetNode: edge_detector + category: construction-category-tools + description: An edge detector for signals. + icon: { sprite: Objects/Devices/gates.rsi, state: edge_detector } + objectType: Item + +- type: construction + name: power sensor + id: PowerSensor + graph: LogicGate + startNode: start + targetNode: power_sensor + category: construction-category-tools + description: A power network checking device for signals. + icon: { sprite: Objects/Devices/gates.rsi, state: power_sensor } + objectType: Item diff --git a/Resources/Prototypes/Recipes/Construction/utilities.yml b/Resources/Prototypes/Recipes/Construction/utilities.yml index fe84db10de..1647e98bce 100644 --- a/Resources/Prototypes/Recipes/Construction/utilities.yml +++ b/Resources/Prototypes/Recipes/Construction/utilities.yml @@ -1,861 +1,861 @@ # SURVEILLANCE -#- type: construction -# name: camera -# id: camera -# graph: SurveillanceCamera -# startNode: start -# targetNode: camera -# category: construction-category-utilities -# description: "Surveillance camera. It's watching. Soon." -# icon: -# sprite: Structures/Wallmounts/camera.rsi -# state: camera -# objectType: Structure -# placementMode: SnapgridCenter -# -#- type: construction -# name: telescreen -# id: WallmountTelescreen -# graph: WallmountTelescreen -# startNode: start -# targetNode: Telescreen -# category: construction-category-utilities -# description: "A surveillance camera monitor for the wall." -# icon: -# sprite: Structures/Machines/computers.rsi -# state: telescreen_frame -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: true -# -#- type: construction -# name: station map -# id: StationMap -# graph: StationMap -# startNode: start -# targetNode: station_map -# category: construction-category-structures -# description: A station map. -# icon: -# sprite: Structures/Machines/station_map.rsi -# state: station_map0 -# placementMode: SnapgridCenter -# objectType: Structure -# canRotate: true -# canBuildInImpassable: true -# conditions: -# - !type:WallmountCondition {} -# -## POWER -#- type: construction -# name: APC -# id: APC -# graph: APC -# startNode: start -# targetNode: apc -# category: construction-category-utilities -# description: "Area Power Controller (APC). Controls power. In an area." -# icon: -# sprite: Structures/Power/apc.rsi -# state: base -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: true -# -#- type: construction -# name: solar assembly -# id: SolarPanel -# graph: SolarPanel -# startNode: start -# targetNode: solarpanel -# category: construction-category-utilities -# description: "Can be turned into a solar panel or solar tracker." -# icon: -# sprite: Structures/Power/Generation/solar_panel.rsi -# state: solar_assembly -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# conditions: -# - !type:TileNotBlocked -# failIfSpace: false -# -#- type: construction -# name: cable terminal -# id: CableTerminal -# graph: CableTerminal -# startNode: start -# targetNode: cable_terminal -# category: construction-category-utilities -# description: "Input of devices such as the SMES. The red cables needs to face the device." -# icon: -# sprite: Structures/Power/cable_terminal.rsi -# state: term -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# -#- type: construction -# name: wallmount substation -# id: WallmountSubstation -# graph: WallmountSubstation -# startNode: start -# targetNode: substation -# category: construction-category-utilities -# description: "A wallmount substation for compact spaces. Make sure to place cable underneath before building the wall." -# icon: -# sprite: Structures/Power/substation.rsi -# state: substation_wall -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: true -# -#- type: construction -# name: wallmount generator -# id: WallmountGenerator -# graph: WallmountGenerator -# startNode: start -# targetNode: generator -# category: construction-category-utilities -# description: "A wallmount generator for compact spaces. Make sure to place cable underneath before building the wall." -# icon: -# sprite: Structures/Power/Generation/wallmount_generator.rsi -# state: panel -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: true -# -#- type: construction -# name: wallmount APU -# id: WallmountGeneratorAPU -# graph: WallmountGenerator -# startNode: start -# targetNode: APU -# category: construction-category-utilities -# description: "A wallmount APU for compact shuttles. Make sure to place cable underneath before building the wall." -# icon: -# sprite: Structures/Power/Generation/wallmount_generator.rsi -# state: panel -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: true -# -## DISPOSALS -#- type: construction -# name: disposal unit -# description: A pneumatic waste disposal unit. -# id: DisposalUnit -# graph: DisposalMachine -# startNode: start -# targetNode: disposal_unit -# category: construction-category-utilities -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Piping/disposal.rsi -# state: "disposal" -# -#- type: construction -# name: mailing unit -# description: A pneumatic mail delivery unit. -# id: MailingUnit -# graph: DisposalMachine -# startNode: start -# targetNode: mailing_unit -# category: construction-category-utilities -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Piping/disposal.rsi -# state: "mailing" -# -#- type: construction -# name: disposal pipe -# id: DisposalPipe -# description: A huge pipe segment used for constructing disposal systems. -# graph: DisposalPipe -# startNode: start -# targetNode: pipe -# category: construction-category-utilities -# placementMode: SnapgridCenter -# canBuildInImpassable: true -# icon: -# sprite: Structures/Piping/disposal.rsi -# state: conpipe-s -# -#- type: construction -# name: disposal tagger -# description: A pipe that tags entities for routing. -# id: DisposalTagger -# graph: DisposalPipe -# startNode: start -# targetNode: tagger -# category: construction-category-utilities -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Piping/disposal.rsi -# state: conpipe-tagger -# -#- type: construction -# name: disposal trunk -# description: A pipe trunk used as an entry point for disposal systems. -# id: DisposalTrunk -# graph: DisposalPipe -# startNode: start -# targetNode: trunk -# category: construction-category-utilities -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Piping/disposal.rsi -# state: conpipe-t -# -#- type: construction -# name: disposal router -# description: A three-way router. Entities with matching tags get routed to the side. -# id: DisposalRouter -# graph: DisposalPipe -# startNode: start -# targetNode: router -# category: construction-category-utilities -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Piping/disposal.rsi -# state: conpipe-j1s -# mirror: DisposalRouterFlipped -# -#- type: construction -# hide: true -# name: disposal router -# description: A three-way router. Entities with matching tags get routed to the side. -# id: DisposalRouterFlipped -# graph: DisposalPipe -# startNode: start -# targetNode: routerflipped -# category: construction-category-utilities -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Piping/disposal.rsi -# state: conpipe-j2s -# mirror: DisposalRouter -# -#- type: construction -# name: disposal signal router -# description: A signal-controlled three-way router. -# id: DisposalSignalRouter -# graph: DisposalPipe -# startNode: start -# targetNode: signal_router -# category: construction-category-utilities -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Piping/disposal.rsi -# state: signal-router-free -# mirror: DisposalSignalRouterFlipped -# -#- type: construction -# hide: true -# name: disposal signal router -# description: A signal-controlled three-way router. -# id: DisposalSignalRouterFlipped -# graph: DisposalPipe -# startNode: start -# targetNode: signal_router_flipped -# category: construction-category-utilities -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Piping/disposal.rsi -# state: signal-router-flipped-free -# mirror: DisposalSignalRouter -# -#- type: construction -# name: disposal junction -# description: A three-way junction. The arrow indicates where items exit. -# id: DisposalJunction -# graph: DisposalPipe -# startNode: start -# targetNode: junction -# category: construction-category-utilities -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Piping/disposal.rsi -# state: conpipe-j1 -# mirror: DisposalJunctionFlipped -# -#- type: construction -# hide: true -# name: disposal junction -# description: A three-way junction. The arrow indicates where items exit. -# id: DisposalJunctionFlipped -# graph: DisposalPipe -# startNode: start -# targetNode: junctionflipped -# category: construction-category-utilities -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Piping/disposal.rsi -# state: conpipe-j2 -# mirror: DisposalJunction -# -#- type: construction -# name: disposal Y junction -# description: A three-way junction with another exit point. -# id: DisposalYJunction -# graph: DisposalPipe -# startNode: start -# targetNode: yJunction -# category: construction-category-utilities -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Piping/disposal.rsi -# state: conpipe-y -# -#- type: construction -# name: disposal bend -# description: A tube bent at a 90 degree angle. -# id: DisposalBend -# graph: DisposalPipe -# startNode: start -# targetNode: bend -# category: construction-category-utilities -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Piping/disposal.rsi -# state: conpipe-c -# -## ATMOS -#- type: construction -# name: air alarm -# id: AirAlarmFixture -# graph: AirAlarm -# startNode: start -# targetNode: air_alarm -# category: construction-category-structures -# description: An air alarm. Alarms... air? -# icon: -# sprite: Structures/Wallmounts/air_monitors.rsi -# state: alarm0 -# placementMode: SnapgridCenter -# objectType: Structure -# canRotate: true -# canBuildInImpassable: true -# conditions: -# - !type:WallmountCondition {} -# -#- type: construction -# name: fire alarm -# id: FireAlarm -# graph: FireAlarm -# startNode: start -# targetNode: fire_alarm -# category: construction-category-structures -# description: A fire alarm. Spicy! -# icon: -# sprite: Structures/Wallmounts/air_monitors.rsi -# state: fire0 -# placementMode: SnapgridCenter -# objectType: Structure -# canRotate: true -# canBuildInImpassable: true -# conditions: -# - !type:WallmountCondition {} -# -#- type: construction -# name: air sensor -# id: AirSensor -# graph: AirSensor -# startNode: start -# targetNode: sensor -# category: construction-category-structures -# description: An air sensor. Senses air. -# icon: -# sprite: Structures/Specific/Atmospherics/sensor.rsi -# state: gsensor1 -# placementMode: SnapgridCenter -# objectType: Structure -# canRotate: true -# -## ATMOS PIPES -#- type: construction -# name: gas pipe half -# id: GasPipeHalf -# description: Half of a gas pipe. No skateboards. -# graph: GasPipe -# startNode: start -# targetNode: half -# category: construction-category-utilities -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Piping/Atmospherics/pipe.rsi -# state: pipeHalf -# -#- type: construction -# name: gas pipe straight -# id: GasPipeStraight -# description: A straight pipe segment. -# graph: GasPipe -# startNode: start -# targetNode: straight -# category: construction-category-utilities -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Piping/Atmospherics/pipe.rsi -# state: pipeStraight -# -#- type: construction -# name: gas pipe bend -# id: GasPipeBend -# description: A pipe segment bent at a 90 degree angle. -# graph: GasPipe -# startNode: start -# targetNode: bend -# category: construction-category-utilities -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Piping/Atmospherics/pipe.rsi -# state: pipeBend -# -#- type: construction -# name: gas pipe T junction -# id: GasPipeTJunction -# description: A pipe segment with a T junction. -# graph: GasPipe -# startNode: start -# targetNode: tjunction -# category: construction-category-utilities -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Piping/Atmospherics/pipe.rsi -# state: pipeTJunction -# -#- type: construction -# name: gas pipe fourway -# id: GasPipeFourway -# description: A pipe segment with a fourway junction. -# graph: GasPipe -# startNode: start -# targetNode: fourway -# category: construction-category-utilities -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Piping/Atmospherics/pipe.rsi -# state: pipeFourway -# -## ATMOS UNARY -#- type: construction -# name: air vent -# description: Pumps gas into the room. -# id: GasVentPump -# graph: GasUnary -# startNode: start -# targetNode: ventpump -# category: construction-category-utilities -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Piping/Atmospherics/vent.rsi -# state: vent_off -# layers: -# - sprite: Structures/Piping/Atmospherics/pipe.rsi -# state: pipeHalf -# - sprite: Structures/Piping/Atmospherics/vent.rsi -# state: vent_off -# conditions: -# - !type:NoUnstackableInTile -# -#- type: construction -# name: passive vent -# description: Unpowered vent that equalises gases on both sides. -# id: GasPassiveVent -# graph: GasUnary -# startNode: start -# targetNode: passivevent -# category: construction-category-utilities -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Piping/Atmospherics/vent.rsi -# state: vent_off -# layers: -# - sprite: Structures/Piping/Atmospherics/pipe.rsi -# state: pipeHalf -# - sprite: Structures/Piping/Atmospherics/vent.rsi -# state: vent_off -# conditions: -# - !type:NoUnstackableInTile -# -#- type: construction -# name: air scrubber -# description: Sucks gas into connected pipes. -# id: GasVentScrubber -# graph: GasUnary -# startNode: start -# targetNode: ventscrubber -# category: construction-category-utilities -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Piping/Atmospherics/scrubber.rsi -# state: scrub_off -# layers: -# - sprite: Structures/Piping/Atmospherics/pipe.rsi -# state: pipeHalf -# - sprite: Structures/Piping/Atmospherics/scrubber.rsi -# state: scrub_off -# conditions: -# - !type:NoUnstackableInTile -# -#- type: construction -# name: air injector -# description: Injects air into the atmosphere. -# id: GasOutletInjector -# graph: GasUnary -# startNode: start -# targetNode: outletinjector -# category: construction-category-utilities -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Piping/Atmospherics/outletinjector.rsi -# state: injector -# layers: -# - sprite: Structures/Piping/Atmospherics/pipe.rsi -# state: pipeHalf -# - sprite: Structures/Piping/Atmospherics/outletinjector.rsi -# state: injector -# conditions: -# - !type:NoUnstackableInTile -# -## ATMOS BINARY -#- type: construction -# name: gas pump -# id: GasPressurePump -# description: A pump that moves gas by pressure. -# graph: GasBinary -# startNode: start -# targetNode: pressurepump -# category: construction-category-utilities -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Piping/Atmospherics/pump.rsi -# state: pumpPressure -# layers: -# - sprite: Structures/Piping/Atmospherics/pipe.rsi -# state: pipeStraight -# - sprite: Structures/Piping/Atmospherics/pump.rsi -# state: pumpPressure -# conditions: -# - !type:NoUnstackableInTile -# -#- type: construction -# name: volumetric gas pump -# description: A pump that moves gas by volume. -# id: GasVolumePump -# graph: GasBinary -# startNode: start -# targetNode: volumepump -# category: construction-category-utilities -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Piping/Atmospherics/pump.rsi -# state: pumpVolume -# layers: -# - sprite: Structures/Piping/Atmospherics/pipe.rsi -# state: pipeStraight -# - sprite: Structures/Piping/Atmospherics/pump.rsi -# state: pumpVolume -# conditions: -# - !type:NoUnstackableInTile -# -#- type: construction -# id: GasPassiveGate -# name: passive gate -# description: A one-way air valve that does not require power. -# graph: GasBinary -# startNode: start -# targetNode: passivegate -# category: construction-category-utilities -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Piping/Atmospherics/pump.rsi -# state: pumpPassiveGate -# layers: -# - sprite: Structures/Piping/Atmospherics/pipe.rsi -# state: pipeStraight -# - sprite: Structures/Piping/Atmospherics/pump.rsi -# state: pumpPassiveGate -# conditions: -# - !type:NoUnstackableInTile -# -#- type: construction -# id: GasValve -# name: manual valve -# description: A pipe with a valve that can be used to disable the flow of gas through it. -# graph: GasBinary -# startNode: start -# targetNode: valve -# category: construction-category-utilities -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Piping/Atmospherics/pump.rsi -# state: pumpManualValve -# layers: -# - sprite: Structures/Piping/Atmospherics/pipe.rsi -# state: pipeStraight -# - sprite: Structures/Piping/Atmospherics/pump.rsi -# state: pumpManualValve -# conditions: -# - !type:NoUnstackableInTile -# -#- type: construction -# id: SignalControlledValve -# name: signal valve -# description: Valve controlled by signal inputs. -# graph: GasBinary -# startNode: start -# targetNode: signalvalve -# category: construction-category-utilities -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Piping/Atmospherics/pump.rsi -# state: pumpSignalValve -# layers: -# - sprite: Structures/Piping/Atmospherics/pipe.rsi -# state: pipeStraight -# - sprite: Structures/Piping/Atmospherics/pump.rsi -# state: pumpSignalValve -# conditions: -# - !type:NoUnstackableInTile -# -#- type: construction -# id: GasPort -# name: connector port -# description: For connecting portable devices related to atmospherics control. -# graph: GasBinary -# startNode: start -# targetNode: port -# category: construction-category-utilities -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Piping/Atmospherics/gascanisterport.rsi -# state: gasCanisterPort -# layers: -# - sprite: Structures/Piping/Atmospherics/pipe.rsi -# state: pipeHalf -# - sprite: Structures/Piping/Atmospherics/gascanisterport.rsi -# state: gasCanisterPort -# conditions: -# - !type:NoUnstackableInTile -# -#- type: construction -# id: GasDualPortVentPump -# name: dual-port air vent -# description: Has a valve and a pump attached to it. There are two ports, one is an input for releasing air, the other is an output when siphoning. -# graph: GasBinary -# startNode: start -# targetNode: dualportventpump -# category: construction-category-utilities -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Piping/Atmospherics/vent.rsi -# state: vent_off -# layers: -# - sprite: Structures/Piping/Atmospherics/pipe.rsi -# state: pipeStraight -# - sprite: Structures/Piping/Atmospherics/vent.rsi -# state: vent_off -# -#- type: construction -# id: HeatExchanger -# name: radiator -# description: Transfers heat between the pipe and its surroundings. -# graph: GasBinary -# startNode: start -# targetNode: radiator -# category: construction-category-utilities -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Piping/Atmospherics/heatexchanger.rsi -# state: heStraight -# -## ATMOS TRINARY -#- type: construction -# id: GasFilter -# name: gas filter -# description: Very useful for filtering gases. -# graph: GasTrinary -# startNode: start -# targetNode: filter -# category: construction-category-utilities -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Piping/Atmospherics/gasfilter.rsi -# state: gasFilter -# mirror: GasFilterFlipped -# conditions: -# - !type:NoUnstackableInTile -# -#- type: construction -# id: GasFilterFlipped -# hide: true -# name: gas filter -# description: Very useful for filtering gases. -# graph: GasTrinary -# startNode: start -# targetNode: filterflipped -# category: construction-category-utilities -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Piping/Atmospherics/gasfilter.rsi -# state: gasFilterF -# mirror: GasFilter -# conditions: -# - !type:NoUnstackableInTile -# -#- type: construction -# id: GasMixer -# name: gas mixer -# description: Very useful for mixing gases. -# graph: GasTrinary -# startNode: start -# targetNode: mixer -# category: construction-category-utilities -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Piping/Atmospherics/gasmixer.rsi -# state: gasMixer -# mirror: GasMixerFlipped -# conditions: -# - !type:NoUnstackableInTile -# -#- type: construction -# id: GasMixerFlipped -# hide: true -# name: gas mixer -# description: Very useful for mixing gases. -# graph: GasTrinary -# startNode: start -# targetNode: mixerflipped -# category: construction-category-utilities -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Piping/Atmospherics/gasmixer.rsi -# state: gasMixerF -# mirror: GasMixer -# conditions: -# - !type:NoUnstackableInTile -# -#- type: construction -# id: PressureControlledValve -# name: pneumatic valve -# description: Valve controlled by pressure. -# graph: GasTrinary -# startNode: start -# targetNode: pneumaticvalve -# category: construction-category-utilities -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# icon: -# sprite: Structures/Piping/Atmospherics/pneumaticvalve.rsi -# state: off -# conditions: -# - !type:NoUnstackableInTile -# -## INTERCOM -#- type: construction -# name: intercom -# id: IntercomAssesmbly -# graph: Intercom -# startNode: start -# targetNode: intercom -# category: construction-category-structures -# description: An intercom. For when the station just needs to know something. -# icon: -# sprite: Structures/Wallmounts/intercom.rsi -# state: base -# placementMode: SnapgridCenter -# objectType: Structure -# canRotate: true -# canBuildInImpassable: true -# conditions: -# - !type:WallmountCondition {} -# -## TIMERS -#- type: construction -# name: signal timer -# id: SignalTimer -# graph: Timer -# startNode: start -# targetNode: signal -# category: construction-category-utilities -# description: "A wallmounted timer for sending timed signals to things." -# icon: -# sprite: Structures/Wallmounts/switch.rsi -# state: on -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: true -# conditions: -# - !type:WallmountCondition -# -#- type: construction -# name: screen timer -# id: ScreenTimer -# graph: Timer -# startNode: start -# targetNode: screen -# category: construction-category-utilities -# description: "A wallmounted timer for sending timed signals to things. This one has a screen for displaying text." -# icon: -# sprite: Structures/Wallmounts/signalscreen.rsi -# state: signalscreen -# objectType: Structure -# canRotate: false -# placementMode: SnapgridCenter -# canBuildInImpassable: true -# conditions: -# - !type:WallmountCondition -# -#- type: construction -# name: brig timer -# id: BrigTimer -# graph: Timer -# startNode: start -# targetNode: brig -# category: construction-category-utilities -# description: "A wallmounted timer for sending timed signals to things. This one has a screen for displaying text and requires security access to use." -# icon: -# sprite: Structures/Wallmounts/signalscreen.rsi -# state: signalscreen -# objectType: Structure -# canRotate: false -# placementMode: SnapgridCenter -# canBuildInImpassable: true -# conditions: -# - !type:WallmountCondition +- type: construction + name: camera + id: camera + graph: SurveillanceCamera + startNode: start + targetNode: camera + category: construction-category-utilities + description: "Surveillance camera. It's watching. Soon." + icon: + sprite: Structures/Wallmounts/camera.rsi + state: camera + objectType: Structure + placementMode: SnapgridCenter + +- type: construction + name: telescreen + id: WallmountTelescreen + graph: WallmountTelescreen + startNode: start + targetNode: Telescreen + category: construction-category-utilities + description: "A surveillance camera monitor for the wall." + icon: + sprite: Structures/Machines/computers.rsi + state: telescreen_frame + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: true + +- type: construction + name: station map + id: StationMap + graph: StationMap + startNode: start + targetNode: station_map + category: construction-category-structures + description: A station map. + icon: + sprite: Structures/Machines/station_map.rsi + state: station_map0 + placementMode: SnapgridCenter + objectType: Structure + canRotate: true + canBuildInImpassable: true + conditions: + - !type:WallmountCondition {} + +# POWER +- type: construction + name: APC + id: APC + graph: APC + startNode: start + targetNode: apc + category: construction-category-utilities + description: "Area Power Controller (APC). Controls power. In an area." + icon: + sprite: Structures/Power/apc.rsi + state: base + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: true + +- type: construction + name: solar assembly + id: SolarPanel + graph: SolarPanel + startNode: start + targetNode: solarpanel + category: construction-category-utilities + description: "Can be turned into a solar panel or solar tracker." + icon: + sprite: Structures/Power/Generation/solar_panel.rsi + state: solar_assembly + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + failIfSpace: false + +- type: construction + name: cable terminal + id: CableTerminal + graph: CableTerminal + startNode: start + targetNode: cable_terminal + category: construction-category-utilities + description: "Input of devices such as the SMES. The red cables needs to face the device." + icon: + sprite: Structures/Power/cable_terminal.rsi + state: term + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + +- type: construction + name: wallmount substation + id: WallmountSubstation + graph: WallmountSubstation + startNode: start + targetNode: substation + category: construction-category-utilities + description: "A wallmount substation for compact spaces. Make sure to place cable underneath before building the wall." + icon: + sprite: Structures/Power/substation.rsi + state: substation_wall + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: true + +- type: construction + name: wallmount generator + id: WallmountGenerator + graph: WallmountGenerator + startNode: start + targetNode: generator + category: construction-category-utilities + description: "A wallmount generator for compact spaces. Make sure to place cable underneath before building the wall." + icon: + sprite: Structures/Power/Generation/wallmount_generator.rsi + state: panel + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: true + +- type: construction + name: wallmount APU + id: WallmountGeneratorAPU + graph: WallmountGenerator + startNode: start + targetNode: APU + category: construction-category-utilities + description: "A wallmount APU for compact shuttles. Make sure to place cable underneath before building the wall." + icon: + sprite: Structures/Power/Generation/wallmount_generator.rsi + state: panel + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: true + +# DISPOSALS +- type: construction + name: disposal unit + description: A pneumatic waste disposal unit. + id: DisposalUnit + graph: DisposalMachine + startNode: start + targetNode: disposal_unit + category: construction-category-utilities + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Piping/disposal.rsi + state: "disposal" + +- type: construction + name: mailing unit + description: A pneumatic mail delivery unit. + id: MailingUnit + graph: DisposalMachine + startNode: start + targetNode: mailing_unit + category: construction-category-utilities + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Piping/disposal.rsi + state: "mailing" + +- type: construction + name: disposal pipe + id: DisposalPipe + description: A huge pipe segment used for constructing disposal systems. + graph: DisposalPipe + startNode: start + targetNode: pipe + category: construction-category-utilities + placementMode: SnapgridCenter + canBuildInImpassable: true + icon: + sprite: Structures/Piping/disposal.rsi + state: conpipe-s + +- type: construction + name: disposal tagger + description: A pipe that tags entities for routing. + id: DisposalTagger + graph: DisposalPipe + startNode: start + targetNode: tagger + category: construction-category-utilities + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Piping/disposal.rsi + state: conpipe-tagger + +- type: construction + name: disposal trunk + description: A pipe trunk used as an entry point for disposal systems. + id: DisposalTrunk + graph: DisposalPipe + startNode: start + targetNode: trunk + category: construction-category-utilities + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Piping/disposal.rsi + state: conpipe-t + +- type: construction + name: disposal router + description: A three-way router. Entities with matching tags get routed to the side. + id: DisposalRouter + graph: DisposalPipe + startNode: start + targetNode: router + category: construction-category-utilities + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Piping/disposal.rsi + state: conpipe-j1s + mirror: DisposalRouterFlipped + +- type: construction + hide: true + name: disposal router + description: A three-way router. Entities with matching tags get routed to the side. + id: DisposalRouterFlipped + graph: DisposalPipe + startNode: start + targetNode: routerflipped + category: construction-category-utilities + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Piping/disposal.rsi + state: conpipe-j2s + mirror: DisposalRouter + +- type: construction + name: disposal signal router + description: A signal-controlled three-way router. + id: DisposalSignalRouter + graph: DisposalPipe + startNode: start + targetNode: signal_router + category: construction-category-utilities + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Piping/disposal.rsi + state: signal-router-free + mirror: DisposalSignalRouterFlipped + +- type: construction + hide: true + name: disposal signal router + description: A signal-controlled three-way router. + id: DisposalSignalRouterFlipped + graph: DisposalPipe + startNode: start + targetNode: signal_router_flipped + category: construction-category-utilities + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Piping/disposal.rsi + state: signal-router-flipped-free + mirror: DisposalSignalRouter + +- type: construction + name: disposal junction + description: A three-way junction. The arrow indicates where items exit. + id: DisposalJunction + graph: DisposalPipe + startNode: start + targetNode: junction + category: construction-category-utilities + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Piping/disposal.rsi + state: conpipe-j1 + mirror: DisposalJunctionFlipped + +- type: construction + hide: true + name: disposal junction + description: A three-way junction. The arrow indicates where items exit. + id: DisposalJunctionFlipped + graph: DisposalPipe + startNode: start + targetNode: junctionflipped + category: construction-category-utilities + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Piping/disposal.rsi + state: conpipe-j2 + mirror: DisposalJunction + +- type: construction + name: disposal Y junction + description: A three-way junction with another exit point. + id: DisposalYJunction + graph: DisposalPipe + startNode: start + targetNode: yJunction + category: construction-category-utilities + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Piping/disposal.rsi + state: conpipe-y + +- type: construction + name: disposal bend + description: A tube bent at a 90 degree angle. + id: DisposalBend + graph: DisposalPipe + startNode: start + targetNode: bend + category: construction-category-utilities + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Piping/disposal.rsi + state: conpipe-c + +# ATMOS +- type: construction + name: air alarm + id: AirAlarmFixture + graph: AirAlarm + startNode: start + targetNode: air_alarm + category: construction-category-structures + description: An air alarm. Alarms... air? + icon: + sprite: Structures/Wallmounts/air_monitors.rsi + state: alarm0 + placementMode: SnapgridCenter + objectType: Structure + canRotate: true + canBuildInImpassable: true + conditions: + - !type:WallmountCondition {} + +- type: construction + name: fire alarm + id: FireAlarm + graph: FireAlarm + startNode: start + targetNode: fire_alarm + category: construction-category-structures + description: A fire alarm. Spicy! + icon: + sprite: Structures/Wallmounts/air_monitors.rsi + state: fire0 + placementMode: SnapgridCenter + objectType: Structure + canRotate: true + canBuildInImpassable: true + conditions: + - !type:WallmountCondition {} + +- type: construction + name: air sensor + id: AirSensor + graph: AirSensor + startNode: start + targetNode: sensor + category: construction-category-structures + description: An air sensor. Senses air. + icon: + sprite: Structures/Specific/Atmospherics/sensor.rsi + state: gsensor1 + placementMode: SnapgridCenter + objectType: Structure + canRotate: true + +# ATMOS PIPES +- type: construction + name: gas pipe half + id: GasPipeHalf + description: Half of a gas pipe. No skateboards. + graph: GasPipe + startNode: start + targetNode: half + category: construction-category-utilities + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Piping/Atmospherics/pipe.rsi + state: pipeHalf + +- type: construction + name: gas pipe straight + id: GasPipeStraight + description: A straight pipe segment. + graph: GasPipe + startNode: start + targetNode: straight + category: construction-category-utilities + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Piping/Atmospherics/pipe.rsi + state: pipeStraight + +- type: construction + name: gas pipe bend + id: GasPipeBend + description: A pipe segment bent at a 90 degree angle. + graph: GasPipe + startNode: start + targetNode: bend + category: construction-category-utilities + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Piping/Atmospherics/pipe.rsi + state: pipeBend + +- type: construction + name: gas pipe T junction + id: GasPipeTJunction + description: A pipe segment with a T junction. + graph: GasPipe + startNode: start + targetNode: tjunction + category: construction-category-utilities + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Piping/Atmospherics/pipe.rsi + state: pipeTJunction + +- type: construction + name: gas pipe fourway + id: GasPipeFourway + description: A pipe segment with a fourway junction. + graph: GasPipe + startNode: start + targetNode: fourway + category: construction-category-utilities + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Piping/Atmospherics/pipe.rsi + state: pipeFourway + +# ATMOS UNARY +- type: construction + name: air vent + description: Pumps gas into the room. + id: GasVentPump + graph: GasUnary + startNode: start + targetNode: ventpump + category: construction-category-utilities + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Piping/Atmospherics/vent.rsi + state: vent_off + layers: + - sprite: Structures/Piping/Atmospherics/pipe.rsi + state: pipeHalf + - sprite: Structures/Piping/Atmospherics/vent.rsi + state: vent_off + conditions: + - !type:NoUnstackableInTile + +- type: construction + name: passive vent + description: Unpowered vent that equalises gases on both sides. + id: GasPassiveVent + graph: GasUnary + startNode: start + targetNode: passivevent + category: construction-category-utilities + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Piping/Atmospherics/vent.rsi + state: vent_off + layers: + - sprite: Structures/Piping/Atmospherics/pipe.rsi + state: pipeHalf + - sprite: Structures/Piping/Atmospherics/vent.rsi + state: vent_off + conditions: + - !type:NoUnstackableInTile + +- type: construction + name: air scrubber + description: Sucks gas into connected pipes. + id: GasVentScrubber + graph: GasUnary + startNode: start + targetNode: ventscrubber + category: construction-category-utilities + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Piping/Atmospherics/scrubber.rsi + state: scrub_off + layers: + - sprite: Structures/Piping/Atmospherics/pipe.rsi + state: pipeHalf + - sprite: Structures/Piping/Atmospherics/scrubber.rsi + state: scrub_off + conditions: + - !type:NoUnstackableInTile + +- type: construction + name: air injector + description: Injects air into the atmosphere. + id: GasOutletInjector + graph: GasUnary + startNode: start + targetNode: outletinjector + category: construction-category-utilities + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Piping/Atmospherics/outletinjector.rsi + state: injector + layers: + - sprite: Structures/Piping/Atmospherics/pipe.rsi + state: pipeHalf + - sprite: Structures/Piping/Atmospherics/outletinjector.rsi + state: injector + conditions: + - !type:NoUnstackableInTile + +# ATMOS BINARY +- type: construction + name: gas pump + id: GasPressurePump + description: A pump that moves gas by pressure. + graph: GasBinary + startNode: start + targetNode: pressurepump + category: construction-category-utilities + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Piping/Atmospherics/pump.rsi + state: pumpPressure + layers: + - sprite: Structures/Piping/Atmospherics/pipe.rsi + state: pipeStraight + - sprite: Structures/Piping/Atmospherics/pump.rsi + state: pumpPressure + conditions: + - !type:NoUnstackableInTile + +- type: construction + name: volumetric gas pump + description: A pump that moves gas by volume. + id: GasVolumePump + graph: GasBinary + startNode: start + targetNode: volumepump + category: construction-category-utilities + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Piping/Atmospherics/pump.rsi + state: pumpVolume + layers: + - sprite: Structures/Piping/Atmospherics/pipe.rsi + state: pipeStraight + - sprite: Structures/Piping/Atmospherics/pump.rsi + state: pumpVolume + conditions: + - !type:NoUnstackableInTile + +- type: construction + id: GasPassiveGate + name: passive gate + description: A one-way air valve that does not require power. + graph: GasBinary + startNode: start + targetNode: passivegate + category: construction-category-utilities + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Piping/Atmospherics/pump.rsi + state: pumpPassiveGate + layers: + - sprite: Structures/Piping/Atmospherics/pipe.rsi + state: pipeStraight + - sprite: Structures/Piping/Atmospherics/pump.rsi + state: pumpPassiveGate + conditions: + - !type:NoUnstackableInTile + +- type: construction + id: GasValve + name: manual valve + description: A pipe with a valve that can be used to disable the flow of gas through it. + graph: GasBinary + startNode: start + targetNode: valve + category: construction-category-utilities + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Piping/Atmospherics/pump.rsi + state: pumpManualValve + layers: + - sprite: Structures/Piping/Atmospherics/pipe.rsi + state: pipeStraight + - sprite: Structures/Piping/Atmospherics/pump.rsi + state: pumpManualValve + conditions: + - !type:NoUnstackableInTile + +- type: construction + id: SignalControlledValve + name: signal valve + description: Valve controlled by signal inputs. + graph: GasBinary + startNode: start + targetNode: signalvalve + category: construction-category-utilities + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Piping/Atmospherics/pump.rsi + state: pumpSignalValve + layers: + - sprite: Structures/Piping/Atmospherics/pipe.rsi + state: pipeStraight + - sprite: Structures/Piping/Atmospherics/pump.rsi + state: pumpSignalValve + conditions: + - !type:NoUnstackableInTile + +- type: construction + id: GasPort + name: connector port + description: For connecting portable devices related to atmospherics control. + graph: GasBinary + startNode: start + targetNode: port + category: construction-category-utilities + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Piping/Atmospherics/gascanisterport.rsi + state: gasCanisterPort + layers: + - sprite: Structures/Piping/Atmospherics/pipe.rsi + state: pipeHalf + - sprite: Structures/Piping/Atmospherics/gascanisterport.rsi + state: gasCanisterPort + conditions: + - !type:NoUnstackableInTile + +- type: construction + id: GasDualPortVentPump + name: dual-port air vent + description: Has a valve and a pump attached to it. There are two ports, one is an input for releasing air, the other is an output when siphoning. + graph: GasBinary + startNode: start + targetNode: dualportventpump + category: construction-category-utilities + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Piping/Atmospherics/vent.rsi + state: vent_off + layers: + - sprite: Structures/Piping/Atmospherics/pipe.rsi + state: pipeStraight + - sprite: Structures/Piping/Atmospherics/vent.rsi + state: vent_off + +- type: construction + id: HeatExchanger + name: radiator + description: Transfers heat between the pipe and its surroundings. + graph: GasBinary + startNode: start + targetNode: radiator + category: construction-category-utilities + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Piping/Atmospherics/heatexchanger.rsi + state: heStraight + +# ATMOS TRINARY +- type: construction + id: GasFilter + name: gas filter + description: Very useful for filtering gases. + graph: GasTrinary + startNode: start + targetNode: filter + category: construction-category-utilities + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Piping/Atmospherics/gasfilter.rsi + state: gasFilter + mirror: GasFilterFlipped + conditions: + - !type:NoUnstackableInTile + +- type: construction + id: GasFilterFlipped + hide: true + name: gas filter + description: Very useful for filtering gases. + graph: GasTrinary + startNode: start + targetNode: filterflipped + category: construction-category-utilities + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Piping/Atmospherics/gasfilter.rsi + state: gasFilterF + mirror: GasFilter + conditions: + - !type:NoUnstackableInTile + +- type: construction + id: GasMixer + name: gas mixer + description: Very useful for mixing gases. + graph: GasTrinary + startNode: start + targetNode: mixer + category: construction-category-utilities + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Piping/Atmospherics/gasmixer.rsi + state: gasMixer + mirror: GasMixerFlipped + conditions: + - !type:NoUnstackableInTile + +- type: construction + id: GasMixerFlipped + hide: true + name: gas mixer + description: Very useful for mixing gases. + graph: GasTrinary + startNode: start + targetNode: mixerflipped + category: construction-category-utilities + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Piping/Atmospherics/gasmixer.rsi + state: gasMixerF + mirror: GasMixer + conditions: + - !type:NoUnstackableInTile + +- type: construction + id: PressureControlledValve + name: pneumatic valve + description: Valve controlled by pressure. + graph: GasTrinary + startNode: start + targetNode: pneumaticvalve + category: construction-category-utilities + placementMode: SnapgridCenter + canBuildInImpassable: false + icon: + sprite: Structures/Piping/Atmospherics/pneumaticvalve.rsi + state: off + conditions: + - !type:NoUnstackableInTile + +# INTERCOM +- type: construction + name: intercom + id: IntercomAssesmbly + graph: Intercom + startNode: start + targetNode: intercom + category: construction-category-structures + description: An intercom. For when the station just needs to know something. + icon: + sprite: Structures/Wallmounts/intercom.rsi + state: base + placementMode: SnapgridCenter + objectType: Structure + canRotate: true + canBuildInImpassable: true + conditions: + - !type:WallmountCondition {} + +# TIMERS +- type: construction + name: signal timer + id: SignalTimer + graph: Timer + startNode: start + targetNode: signal + category: construction-category-utilities + description: "A wallmounted timer for sending timed signals to things." + icon: + sprite: Structures/Wallmounts/switch.rsi + state: on + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: true + conditions: + - !type:WallmountCondition + +- type: construction + name: screen timer + id: ScreenTimer + graph: Timer + startNode: start + targetNode: screen + category: construction-category-utilities + description: "A wallmounted timer for sending timed signals to things. This one has a screen for displaying text." + icon: + sprite: Structures/Wallmounts/signalscreen.rsi + state: signalscreen + objectType: Structure + canRotate: false + placementMode: SnapgridCenter + canBuildInImpassable: true + conditions: + - !type:WallmountCondition + +- type: construction + name: brig timer + id: BrigTimer + graph: Timer + startNode: start + targetNode: brig + category: construction-category-utilities + description: "A wallmounted timer for sending timed signals to things. This one has a screen for displaying text and requires security access to use." + icon: + sprite: Structures/Wallmounts/signalscreen.rsi + state: signalscreen + objectType: Structure + canRotate: false + placementMode: SnapgridCenter + canBuildInImpassable: true + conditions: + - !type:WallmountCondition diff --git a/Resources/Prototypes/Recipes/Construction/weapons.yml b/Resources/Prototypes/Recipes/Construction/weapons.yml index 78ecacb46d..040d4c8963 100644 --- a/Resources/Prototypes/Recipes/Construction/weapons.yml +++ b/Resources/Prototypes/Recipes/Construction/weapons.yml @@ -1,68 +1,68 @@ -#- type: construction -# name: grey bladed flatcap -# id: BladedFlatcapGrey -# graph: BladedFlatcapGrey -# startNode: start -# targetNode: icon -# category: construction-category-weapons -# description: An inconspicuous hat with glass shards sewn into the brim. -# icon: { sprite: Clothing/Head/Hats/greyflatcap.rsi, state: icon } -# objectType: Item -# -#- type: construction -# name: brown bladed flatcap -# id: BladedFlatcapBrown -# graph: BladedFlatcapBrown -# startNode: start -# targetNode: icon -# category: construction-category-weapons -# description: An inconspicuous hat with glass shards sewn into the brim. -# icon: { sprite: Clothing/Head/Hats/brownflatcap.rsi, state: icon } -# objectType: Item -# -#- type: construction -# name: glass shiv -# id: Shiv -# graph: Shiv -# startNode: start -# targetNode: icon -# category: construction-category-weapons -# description: A glass shard with a piece of cloth wrapped around it. -# icon: { sprite: Objects/Weapons/Melee/shiv.rsi, state: icon } -# objectType: Item -# -#- type: construction -# name: reinforced shiv -# id: ReinforcedShiv -# graph: ReinforcedShiv -# startNode: start -# targetNode: icon -# category: construction-category-weapons -# description: A reinforced glass shard with a piece of cloth wrapped around it. -# icon: { sprite: Objects/Weapons/Melee/reinforced_shiv.rsi, state: icon } -# objectType: Item -# -#- type: construction -# name: plasma shiv -# id: PlasmaShiv -# graph: PlasmaShiv -# startNode: start -# targetNode: icon -# category: construction-category-weapons -# description: A plasma shard with a piece of cloth wrapped around it. -# icon: { sprite: Objects/Weapons/Melee/plasma_shiv.rsi, state: icon } -# objectType: Item -# -#- type: construction -# name: uranium shiv -# id: UraniumShiv -# graph: UraniumShiv -# startNode: start -# targetNode: icon -# category: construction-category-weapons -# description: A uranium shard with a piece of cloth wrapped around it. -# icon: { sprite: Objects/Weapons/Melee/uranium_shiv.rsi, state: icon } -# objectType: Item +- type: construction + name: grey bladed flatcap + id: BladedFlatcapGrey + graph: BladedFlatcapGrey + startNode: start + targetNode: icon + category: construction-category-weapons + description: An inconspicuous hat with glass shards sewn into the brim. + icon: { sprite: Clothing/Head/Hats/greyflatcap.rsi, state: icon } + objectType: Item + +- type: construction + name: brown bladed flatcap + id: BladedFlatcapBrown + graph: BladedFlatcapBrown + startNode: start + targetNode: icon + category: construction-category-weapons + description: An inconspicuous hat with glass shards sewn into the brim. + icon: { sprite: Clothing/Head/Hats/brownflatcap.rsi, state: icon } + objectType: Item + +- type: construction + name: glass shiv + id: Shiv + graph: Shiv + startNode: start + targetNode: icon + category: construction-category-weapons + description: A glass shard with a piece of cloth wrapped around it. + icon: { sprite: Objects/Weapons/Melee/shiv.rsi, state: icon } + objectType: Item + +- type: construction + name: reinforced shiv + id: ReinforcedShiv + graph: ReinforcedShiv + startNode: start + targetNode: icon + category: construction-category-weapons + description: A reinforced glass shard with a piece of cloth wrapped around it. + icon: { sprite: Objects/Weapons/Melee/reinforced_shiv.rsi, state: icon } + objectType: Item + +- type: construction + name: plasma shiv + id: PlasmaShiv + graph: PlasmaShiv + startNode: start + targetNode: icon + category: construction-category-weapons + description: A plasma shard with a piece of cloth wrapped around it. + icon: { sprite: Objects/Weapons/Melee/plasma_shiv.rsi, state: icon } + objectType: Item + +- type: construction + name: uranium shiv + id: UraniumShiv + graph: UraniumShiv + startNode: start + targetNode: icon + category: construction-category-weapons + description: A uranium shard with a piece of cloth wrapped around it. + icon: { sprite: Objects/Weapons/Melee/uranium_shiv.rsi, state: icon } + objectType: Item - type: construction name: crude spear @@ -75,101 +75,101 @@ icon: { sprite: Objects/Weapons/Melee/spear.rsi, state: spear } objectType: Item -#- type: construction -# name: crude reinforced spear -# id: SpearReinforced -# graph: SpearReinforced -# startNode: start -# targetNode: spear -# category: construction-category-weapons -# description: A crude reinforced spear for when you need to put holes in somebody. -# icon: { sprite: Objects/Weapons/Melee/reinforced_spear.rsi, state: spear } -# objectType: Item -# -#- type: construction -# name: crude plasma spear -# id: SpearPlasma -# graph: SpearPlasma -# startNode: start -# targetNode: spear -# category: construction-category-weapons -# description: A crude plasma spear for when you need to put holes in somebody. -# icon: { sprite: Objects/Weapons/Melee/plasma_spear.rsi, state: spear } -# objectType: Item -# -#- type: construction -# name: crude uranium spear -# id: SpearUranium -# graph: SpearUranium -# startNode: start -# targetNode: spear -# category: construction-category-weapons -# description: A crude uranium spear for when you need to put holes in somebody. -# icon: { sprite: Objects/Weapons/Melee/uranium_spear.rsi, state: spear } -# objectType: Item -# -#- type: construction -# name: makeshift bola -# id: Bola -# graph: Bola -# startNode: start -# targetNode: bola -# category: construction-category-weapons -# description: A simple weapon for tripping someone at a distance. -# icon: { sprite: Objects/Weapons/Throwable/bola.rsi, state: icon } -# objectType: Item -# -#- type: construction -# name: wooden buckler -# id: WoodenBuckler -# graph: WoodenBuckler -# startNode: start -# targetNode: woodenBuckler -# category: construction-category-weapons -# description: A nicely carved wooden shield! -# icon: { sprite: Objects/Weapons/Melee/shields.rsi, state: buckler-icon } -# objectType: Item -# -#- type: construction -# name: makeshift shield -# id: MakeshiftShield -# graph: MakeshiftShield -# startNode: start -# targetNode: makeshiftShield -# category: construction-category-weapons -# description: Crude and falling apart. Why would you make this? -# icon: { sprite: Objects/Weapons/Melee/shields.rsi, state: makeshift-icon } -# objectType: Item -# -#- type: construction -# name: glass shard arrow -# id: ImprovisedArrow -# graph: ImprovisedArrow -# startNode: start -# targetNode: ImprovisedArrow -# category: construction-category-weapons -# description: An arrow tipped with pieces of a glass shard, for use with a bow. -# icon: { sprite: Objects/Weapons/Guns/Bow/bow.rsi, state: wielded-arrow } -# objectType: Item -# -#- type: construction -# name: improvised bow -# id: ImprovisedBow -# graph: ImprovisedBow -# startNode: start -# targetNode: ImprovisedBow -# category: construction-category-weapons -# description: A shoddily constructed bow made out of wood and cloth. It's not much, but it's gotten the job done for millennia. -# icon: { sprite: Objects/Weapons/Guns/Bow/bow.rsi, state: unwielded } -# objectType: Item -# -#- type: construction -# name: bone spear -# id: SpearBone -# graph: SpearBone -# startNode: start -# targetNode: spear -# category: construction-category-weapons -# description: Bones and silk combined together. -# icon: { sprite: Objects/Weapons/Melee/bone_spear.rsi, state: spear } -# objectType: Item +- type: construction + name: crude reinforced spear + id: SpearReinforced + graph: SpearReinforced + startNode: start + targetNode: spear + category: construction-category-weapons + description: A crude reinforced spear for when you need to put holes in somebody. + icon: { sprite: Objects/Weapons/Melee/reinforced_spear.rsi, state: spear } + objectType: Item + +- type: construction + name: crude plasma spear + id: SpearPlasma + graph: SpearPlasma + startNode: start + targetNode: spear + category: construction-category-weapons + description: A crude plasma spear for when you need to put holes in somebody. + icon: { sprite: Objects/Weapons/Melee/plasma_spear.rsi, state: spear } + objectType: Item + +- type: construction + name: crude uranium spear + id: SpearUranium + graph: SpearUranium + startNode: start + targetNode: spear + category: construction-category-weapons + description: A crude uranium spear for when you need to put holes in somebody. + icon: { sprite: Objects/Weapons/Melee/uranium_spear.rsi, state: spear } + objectType: Item + +- type: construction + name: makeshift bola + id: Bola + graph: Bola + startNode: start + targetNode: bola + category: construction-category-weapons + description: A simple weapon for tripping someone at a distance. + icon: { sprite: Objects/Weapons/Throwable/bola.rsi, state: icon } + objectType: Item + +- type: construction + name: wooden buckler + id: WoodenBuckler + graph: WoodenBuckler + startNode: start + targetNode: woodenBuckler + category: construction-category-weapons + description: A nicely carved wooden shield! + icon: { sprite: Objects/Weapons/Melee/shields.rsi, state: buckler-icon } + objectType: Item + +- type: construction + name: makeshift shield + id: MakeshiftShield + graph: MakeshiftShield + startNode: start + targetNode: makeshiftShield + category: construction-category-weapons + description: Crude and falling apart. Why would you make this? + icon: { sprite: Objects/Weapons/Melee/shields.rsi, state: makeshift-icon } + objectType: Item + +- type: construction + name: glass shard arrow + id: ImprovisedArrow + graph: ImprovisedArrow + startNode: start + targetNode: ImprovisedArrow + category: construction-category-weapons + description: An arrow tipped with pieces of a glass shard, for use with a bow. + icon: { sprite: Objects/Weapons/Guns/Bow/bow.rsi, state: wielded-arrow } + objectType: Item + +- type: construction + name: improvised bow + id: ImprovisedBow + graph: ImprovisedBow + startNode: start + targetNode: ImprovisedBow + category: construction-category-weapons + description: A shoddily constructed bow made out of wood and cloth. It's not much, but it's gotten the job done for millennia. + icon: { sprite: Objects/Weapons/Guns/Bow/bow.rsi, state: unwielded } + objectType: Item + +- type: construction + name: bone spear + id: SpearBone + graph: SpearBone + startNode: start + targetNode: spear + category: construction-category-weapons + description: Bones and silk combined together. + icon: { sprite: Objects/Weapons/Melee/bone_spear.rsi, state: spear } + objectType: Item diff --git a/Resources/Prototypes/Recipes/Construction/web.yml b/Resources/Prototypes/Recipes/Construction/web.yml index 7f131886fa..9a0d832d01 100644 --- a/Resources/Prototypes/Recipes/Construction/web.yml +++ b/Resources/Prototypes/Recipes/Construction/web.yml @@ -1,119 +1,119 @@ -#- type: construction -# name: web wall -# id: WallWeb -# graph: WebStructures -# startNode: start -# targetNode: wall -# category: construction-category-structures -# description: A fairly weak yet silky smooth wall. -# icon: -# sprite: Structures/Walls/web.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: false -# canBuildInImpassable: false -# entityWhitelist: -# tags: -# - SpiderCraft -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: web table -# id: TableWeb -# graph: WebStructures -# startNode: start -# targetNode: table -# category: construction-category-furniture -# description: Essential for any serious web development. -# icon: -# sprite: Structures/Furniture/Tables/web.rsi -# state: full -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: false -# canBuildInImpassable: false -# entityWhitelist: -# tags: -# - SpiderCraft -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: web bed -# id: WebBed -# graph: WebStructures -# startNode: start -# targetNode: bed -# category: construction-category-furniture -# description: Fun fact, you eating spiders in your sleep is false. -# icon: -# sprite: Structures/Web/bed.rsi -# state: icon -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: false -# canBuildInImpassable: false -# entityWhitelist: -# tags: -# - SpiderCraft -# conditions: -# - !type:TileNotBlocked -# -#- type: construction -# name: web chair -# id: ChairWeb -# graph: WebStructures -# startNode: start -# targetNode: chair -# category: construction-category-furniture -# description: You want to get serious about web development? Get this chair! -# icon: -# sprite: Structures/Web/chair.rsi -# state: icon -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# entityWhitelist: -# tags: -# - SpiderCraft -# -#- type: construction -# name: web crate -# id: CrateWeb -# graph: WebStructures -# startNode: start -# targetNode: crate -# category: construction-category-storage -# description: For containment of food and other things. Not as durable as a normal crate, and can't be welded shut. -# icon: -# sprite: Structures/Storage/Crates/web.rsi -# state: icon -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: false -# canBuildInImpassable: false -# entityWhitelist: -# tags: -# - SpiderCraft -# -#- type: construction -# name: web door -# id: WebDoor -# graph: WebStructures -# startNode: start -# targetNode: door -# category: construction-category-structures -# description: A manual door made from web, normally placed right before a pit or trap. -# icon: -# sprite: Structures/Doors/web_door.rsi -# state: closed -# objectType: Structure -# placementMode: SnapgridCenter -# canBuildInImpassable: false -# entityWhitelist: -# tags: -# - SpiderCraft -# conditions: -# - !type:TileNotBlocked +- type: construction + name: web wall + id: WallWeb + graph: WebStructures + startNode: start + targetNode: wall + category: construction-category-structures + description: A fairly weak yet silky smooth wall. + icon: + sprite: Structures/Walls/web.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canRotate: false + canBuildInImpassable: false + entityWhitelist: + tags: + - SpiderCraft + conditions: + - !type:TileNotBlocked + +- type: construction + name: web table + id: TableWeb + graph: WebStructures + startNode: start + targetNode: table + category: construction-category-furniture + description: Essential for any serious web development. + icon: + sprite: Structures/Furniture/Tables/web.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canRotate: false + canBuildInImpassable: false + entityWhitelist: + tags: + - SpiderCraft + conditions: + - !type:TileNotBlocked + +- type: construction + name: web bed + id: WebBed + graph: WebStructures + startNode: start + targetNode: bed + category: construction-category-furniture + description: Fun fact, you eating spiders in your sleep is false. + icon: + sprite: Structures/Web/bed.rsi + state: icon + objectType: Structure + placementMode: SnapgridCenter + canRotate: false + canBuildInImpassable: false + entityWhitelist: + tags: + - SpiderCraft + conditions: + - !type:TileNotBlocked + +- type: construction + name: web chair + id: ChairWeb + graph: WebStructures + startNode: start + targetNode: chair + category: construction-category-furniture + description: You want to get serious about web development? Get this chair! + icon: + sprite: Structures/Web/chair.rsi + state: icon + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + entityWhitelist: + tags: + - SpiderCraft + +- type: construction + name: web crate + id: CrateWeb + graph: WebStructures + startNode: start + targetNode: crate + category: construction-category-storage + description: For containment of food and other things. Not as durable as a normal crate, and can't be welded shut. + icon: + sprite: Structures/Storage/Crates/web.rsi + state: icon + objectType: Structure + placementMode: SnapgridCenter + canRotate: false + canBuildInImpassable: false + entityWhitelist: + tags: + - SpiderCraft + +- type: construction + name: web door + id: WebDoor + graph: WebStructures + startNode: start + targetNode: door + category: construction-category-structures + description: A manual door made from web, normally placed right before a pit or trap. + icon: + sprite: Structures/Doors/web_door.rsi + state: closed + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + entityWhitelist: + tags: + - SpiderCraft + conditions: + - !type:TileNotBlocked diff --git a/Resources/Prototypes/Recipes/Crafting/artifact.yml b/Resources/Prototypes/Recipes/Crafting/artifact.yml index c1045b9771..c627f00c16 100644 --- a/Resources/Prototypes/Recipes/Crafting/artifact.yml +++ b/Resources/Prototypes/Recipes/Crafting/artifact.yml @@ -1,12 +1,12 @@ -#- type: construction -# name: alien artifact -# id: Artifact -# graph: Artifact -# startNode: start -# targetNode: done -# category: construction-category-misc -# objectType: Item -# description: A strange alien artifact -# icon: -# sprite: Objects/Specific/Xenoarchaeology/item_artifacts.rsi -# state: ano01 +- type: construction + name: alien artifact + id: Artifact + graph: Artifact + startNode: start + targetNode: done + category: construction-category-misc + objectType: Item + description: A strange alien artifact + icon: + sprite: Objects/Specific/Xenoarchaeology/item_artifacts.rsi + state: ano01 diff --git a/Resources/Prototypes/Recipes/Crafting/bots.yml b/Resources/Prototypes/Recipes/Crafting/bots.yml index e06a300147..9a70a19c86 100644 --- a/Resources/Prototypes/Recipes/Crafting/bots.yml +++ b/Resources/Prototypes/Recipes/Crafting/bots.yml @@ -1,64 +1,64 @@ -#- type: construction -# name: cleanbot -# id: cleanbot -# graph: CleanBot -# startNode: start -# targetNode: bot -# category: construction-category-utilities -# objectType: Item -# description: This bot wanders around the station, mopping up any puddles it sees. -# icon: -# sprite: Mobs/Silicon/Bots/cleanbot.rsi -# state: cleanbot -# -#- type: construction -# name: honkbot -# id: honkbot -# graph: HonkBot -# startNode: start -# targetNode: bot -# category: construction-category-utilities -# objectType: Item -# description: This bot honks and slips people. -# icon: -# sprite: Mobs/Silicon/Bots/honkbot.rsi -# state: honkbot -# -#- type: construction -# name: jonkbot -# id: jonkbot -# graph: JonkBot -# startNode: start -# targetNode: bot -# category: construction-category-utilities -# objectType: Item -# description: This cursed bot honks, laughs and slips people. -# icon: -# sprite: Mobs/Silicon/Bots/honkbot.rsi -# state: jonkbot -# -#- type: construction -# name: medibot -# id: medibot -# graph: MediBot -# startNode: start -# targetNode: bot -# category: construction-category-utilities -# objectType: Item -# description: This bot can help supply basic healing. -# icon: -# sprite: Mobs/Silicon/Bots/medibot.rsi -# state: medibot -# -#- type: construction -# name: mimebot -# id: mimebot -# graph: MimeBot -# startNode: start -# targetNode: bot -# category: construction-category-utilities -# objectType: Item -# description: This bot knows how to wave. -# icon: -# sprite: Mobs/Silicon/Bots/mimebot.rsi -# state: mimebot +- type: construction + name: cleanbot + id: cleanbot + graph: CleanBot + startNode: start + targetNode: bot + category: construction-category-utilities + objectType: Item + description: This bot wanders around the station, mopping up any puddles it sees. + icon: + sprite: Mobs/Silicon/Bots/cleanbot.rsi + state: cleanbot + +- type: construction + name: honkbot + id: honkbot + graph: HonkBot + startNode: start + targetNode: bot + category: construction-category-utilities + objectType: Item + description: This bot honks and slips people. + icon: + sprite: Mobs/Silicon/Bots/honkbot.rsi + state: honkbot + +- type: construction + name: jonkbot + id: jonkbot + graph: JonkBot + startNode: start + targetNode: bot + category: construction-category-utilities + objectType: Item + description: This cursed bot honks, laughs and slips people. + icon: + sprite: Mobs/Silicon/Bots/honkbot.rsi + state: jonkbot + +- type: construction + name: medibot + id: medibot + graph: MediBot + startNode: start + targetNode: bot + category: construction-category-utilities + objectType: Item + description: This bot can help supply basic healing. + icon: + sprite: Mobs/Silicon/Bots/medibot.rsi + state: medibot + +- type: construction + name: mimebot + id: mimebot + graph: MimeBot + startNode: start + targetNode: bot + category: construction-category-utilities + objectType: Item + description: This bot knows how to wave. + icon: + sprite: Mobs/Silicon/Bots/mimebot.rsi + state: mimebot diff --git a/Resources/Prototypes/Recipes/Crafting/crates.yml b/Resources/Prototypes/Recipes/Crafting/crates.yml index 82adb5bb04..4177b3fa2a 100644 --- a/Resources/Prototypes/Recipes/Crafting/crates.yml +++ b/Resources/Prototypes/Recipes/Crafting/crates.yml @@ -1,76 +1,76 @@ -#- type: construction -# name: livestock crate -# id: CrateLivestock -# graph: CrateLivestock -# startNode: start -# targetNode: cratelivestock -# category: construction-category-storage -# description: A wooden crate for holding livestock. -# icon: { sprite: Structures/Storage/Crates/livestock.rsi, state: base } -# objectType: Structure -# -#- type: construction -# name: steel crate -# id: CrateGenericSteel -# graph: CrateGenericSteel -# startNode: start -# targetNode: crategenericsteel -# category: construction-category-storage -# description: A metal crate for storing things. -# icon: { sprite: Structures/Storage/Crates/generic.rsi, state: icon } -# objectType: Structure -# -#- type: construction -# name: secure crate -# id: CrateSecure -# graph: CrateSecure -# startNode: start -# targetNode: cratesecure -# category: construction-category-storage -# description: A secure metal crate for storing things. Requires no special access, can be configured with an Access Configurator. -# icon: { sprite: Structures/Storage/Crates/secure.rsi, state: icon } -# objectType: Structure -# -#- type: construction -# name: plastic crate -# id: CratePlastic -# graph: CratePlastic -# startNode: start -# targetNode: crateplastic -# category: construction-category-storage -# description: A plastic crate for storing things. -# icon: { sprite: Structures/Storage/Crates/plastic.rsi, state: icon } -# objectType: Structure -# -#- type: construction -# name: cardboard box -# id: BigBox -# graph: BaseBigBox -# startNode: start -# targetNode: basebigbox -# category: construction-category-storage -# description: A big box for storing things or hiding in. -# icon: { sprite: Structures/Storage/closet.rsi, state: cardboard } -# objectType: Structure -# -#- type: construction -# name: cardboard box -# id: BoxCardboard -# graph: BoxCardboard -# startNode: start -# targetNode: boxcardboard -# category: construction-category-storage -# description: A small box for storing things. -# icon: { sprite: Objects/Storage/boxes.rsi, state: box } -# objectType: Item -# -#- type: construction -# name: coffin -# id: CrateCoffin -# graph: CrateCoffin -# startNode: start -# targetNode: cratecoffin -# category: construction-category-storage -# description: A coffin for storing corpses. -# icon: { sprite: Structures/Storage/Crates/coffin.rsi, state: base } -# objectType: Structure +- type: construction + name: livestock crate + id: CrateLivestock + graph: CrateLivestock + startNode: start + targetNode: cratelivestock + category: construction-category-storage + description: A wooden crate for holding livestock. + icon: { sprite: Structures/Storage/Crates/livestock.rsi, state: base } + objectType: Structure + +- type: construction + name: steel crate + id: CrateGenericSteel + graph: CrateGenericSteel + startNode: start + targetNode: crategenericsteel + category: construction-category-storage + description: A metal crate for storing things. + icon: { sprite: Structures/Storage/Crates/generic.rsi, state: icon } + objectType: Structure + +- type: construction + name: secure crate + id: CrateSecure + graph: CrateSecure + startNode: start + targetNode: cratesecure + category: construction-category-storage + description: A secure metal crate for storing things. Requires no special access, can be configured with an Access Configurator. + icon: { sprite: Structures/Storage/Crates/secure.rsi, state: icon } + objectType: Structure + +- type: construction + name: plastic crate + id: CratePlastic + graph: CratePlastic + startNode: start + targetNode: crateplastic + category: construction-category-storage + description: A plastic crate for storing things. + icon: { sprite: Structures/Storage/Crates/plastic.rsi, state: icon } + objectType: Structure + +- type: construction + name: cardboard box + id: BigBox + graph: BaseBigBox + startNode: start + targetNode: basebigbox + category: construction-category-storage + description: A big box for storing things or hiding in. + icon: { sprite: Structures/Storage/closet.rsi, state: cardboard } + objectType: Structure + +- type: construction + name: cardboard box + id: BoxCardboard + graph: BoxCardboard + startNode: start + targetNode: boxcardboard + category: construction-category-storage + description: A small box for storing things. + icon: { sprite: Objects/Storage/boxes.rsi, state: box } + objectType: Item + +- type: construction + name: coffin + id: CrateCoffin + graph: CrateCoffin + startNode: start + targetNode: cratecoffin + category: construction-category-storage + description: A coffin for storing corpses. + icon: { sprite: Structures/Storage/Crates/coffin.rsi, state: base } + objectType: Structure diff --git a/Resources/Prototypes/Recipes/Crafting/improvised.yml b/Resources/Prototypes/Recipes/Crafting/improvised.yml index 2e8660e5e1..7414837592 100644 --- a/Resources/Prototypes/Recipes/Crafting/improvised.yml +++ b/Resources/Prototypes/Recipes/Crafting/improvised.yml @@ -1,242 +1,242 @@ -#- type: construction -# name: baseball bat -# id: bat -# graph: WoodenBat -# startNode: start -# targetNode: bat -# category: construction-category-weapons -# description: A robust baseball bat. -# icon: -# sprite: Objects/Weapons/Melee/baseball_bat.rsi -# state: icon -# objectType: Item -# -#- type: construction -# name: ghost sheet -# id: ghost_sheet -# graph: GhostSheet -# startNode: start -# targetNode: ghost_sheet -# category: construction-category-clothing -# description: Become a spooky ghost. Boo! -# icon: -# sprite: Clothing/OuterClothing/Misc/ghostsheet.rsi -# state: icon -# objectType: Item -# -#- type: construction -# name: makeshift handcuffs -# id: makeshifthandcuffs -# graph: makeshifthandcuffs -# startNode: start -# targetNode: cuffscable -# category: construction-category-tools -# description: "Homemade handcuffs crafted from spare cables." -# icon: { sprite: Objects/Misc/cablecuffs.rsi, state: cuff } -# objectType: Item -# -#- type: construction -# name: makeshift stunprod -# id: makeshiftstunprod -# graph: makeshiftstunprod -# startNode: start -# targetNode: msstunprod -# category: construction-category-weapons -# description: "Homemade stunprod." -# icon: { sprite: Objects/Weapons/Melee/stunprod.rsi, state: stunprod_off } -# objectType: Item -# -#- type: construction -# name: muzzle -# id: muzzle -# graph: Muzzle -# startNode: start -# targetNode: muzzle -# category: construction-category-tools -# objectType: Item -# description: "A muzzle to shut your victim up." -# icon: -# sprite: Clothing/Mask/muzzle.rsi -# state: icon -# -#- type: construction -# name: improvised pneumatic cannon -# id: pneumaticcannon -# graph: PneumaticCannon -# startNode: start -# targetNode: cannon -# category: construction-category-weapons -# objectType: Item -# description: This son of a gun can fire anything that fits in it using just a little gas. -# icon: -# sprite: Objects/Weapons/Guns/Cannons/pneumatic_cannon.rsi -# state: icon -# -#- type: construction -# name: gauze -# id: gauze -# graph: Gauze -# startNode: start -# targetNode: gauze -# category: construction-category-tools -# objectType: Item -# description: When you've really got nothing left. -# icon: -# sprite: Objects/Specific/Medical/medical.rsi -# state: gauze -# -#- type: construction -# name: blindfold -# id: blindfold -# graph: Blindfold -# startNode: start -# targetNode: blindfold -# category: construction-category-tools -# objectType: Item -# description: Better hope everyone turns a blind eye to you crafting this sussy item... -# icon: -# sprite: Clothing/Eyes/Misc/blindfold.rsi -# state: icon -# -#- type: construction -# name: hairflower -# id: hairflower -# graph: hairflower -# startNode: start -# targetNode: hairflower -# category: construction-category-clothing -# description: "A red flower for beautiful ladies." -# icon: -# sprite: Clothing/Head/Misc/hairflower.rsi -# state: icon -# objectType: Item -# -#- type: construction -# name: flower crown -# id: flowercrown -# graph: flowercrown -# startNode: start -# targetNode: flowercrown -# category: construction-category-clothing -# description: "A coronet of fresh and fragrant flowers." -# icon: -# sprite: Clothing/Head/Misc/flower-crown.rsi -# state: icon -# objectType: Item -# -#- type: construction -# name: flower wreath -# id: flowerwreath -# graph: flowerwreath -# startNode: start -# targetNode: flowerwreath -# category: construction-category-clothing -# description: "A wreath of colourful flowers." -# icon: -# sprite: Clothing/Neck/Misc/flower-wreath.rsi -# state: icon -# objectType: Item -# -#- type: construction -# name: damp rag -# id: rag -# graph: Rag -# startNode: start -# targetNode: rag -# category: construction-category-tools -# objectType: Item -# description: A damp rag to clean up the ground. Better than slipping around all day. -# icon: -# sprite: Objects/Specific/Janitorial/rag.rsi -# state: rag -# -#- type: construction -# name: improvised shotgun -# id: improvisedshotgun -# graph: ImprovisedShotgunGraph -# startNode: start -# targetNode: shotgun -# category: construction-category-weapons -# objectType: Item -# description: A shitty, single-shot shotgun made from salvaged and hand-crafted gun parts. Ammo not included. -# icon: -# sprite: Objects/Weapons/Guns/Shotguns/improvised_shotgun.rsi -# state: icon -# -#- type: construction -# name: improvised shotgun shell -# id: ShellShotgunImprovised -# graph: ImprovisedShotgunShellGraph -# startNode: start -# targetNode: shell -# category: construction-category-weapons -# objectType: Item -# description: A homemade shotgun shell that shoots painful glass shrapnel. The spread is so wide that it couldn't hit the broad side of a Barn -# icon: -# sprite: Objects/Weapons/Guns/Ammunition/Casings/shotgun_shell.rsi -# state: improvised -# -#- type: construction -# name: rifle stock -# id: riflestock -# graph: RifleStockGraph -# startNode: start -# targetNode: riflestock -# category: construction-category-weapons -# objectType: Item -# description: A stock carved out of wood, vital for improvised firearms. -# icon: -# sprite: Objects/Misc/rifle_stock.rsi -# state: icon -# -#- type: construction -# name: fire bomb -# id: firebomb -# graph: FireBomb -# startNode: start -# targetNode: firebomb -# category: construction-category-weapons -# objectType: Item -# description: A weak, improvised incendiary device. -# icon: -# sprite: Objects/Weapons/Bombs/ied.rsi -# state: icon -# -#- type: construction -# name: cotton woven cloth -# id: CottonWovenCloth -# graph: CottonObjects -# startNode: start -# targetNode: cottoncloth -# category: construction-category-misc -# description: "A homemade piece of cotton cloth, it feels coarse." -# icon: -# sprite: Objects/Materials/materials.rsi -# state: cloth_3 -# objectType: Item -# -#- type: construction -# name: straw hat -# id: strawHat -# graph: StrawHat -# startNode: start -# targetNode: strawhat -# category: construction-category-clothing -# description: A fancy hat for hot days! Not recommended to wear near fires. -# icon: -# sprite: Clothing/Head/Hats/straw_hat.rsi -# state: icon -# objectType: Item -# -#- type: construction -# name: pipe bomb -# id: pipebomb -# graph: PipeBomb -# startNode: start -# targetNode: pipebomb -# category: construction-category-weapons -# objectType: Item -# description: An improvised explosive made from pipes and wire. -# icon: -# sprite: Objects/Weapons/Bombs/pipebomb.rsi -# state: icon \ No newline at end of file +- type: construction + name: baseball bat + id: bat + graph: WoodenBat + startNode: start + targetNode: bat + category: construction-category-weapons + description: A robust baseball bat. + icon: + sprite: Objects/Weapons/Melee/baseball_bat.rsi + state: icon + objectType: Item + +- type: construction + name: ghost sheet + id: ghost_sheet + graph: GhostSheet + startNode: start + targetNode: ghost_sheet + category: construction-category-clothing + description: Become a spooky ghost. Boo! + icon: + sprite: Clothing/OuterClothing/Misc/ghostsheet.rsi + state: icon + objectType: Item + +- type: construction + name: makeshift handcuffs + id: makeshifthandcuffs + graph: makeshifthandcuffs + startNode: start + targetNode: cuffscable + category: construction-category-tools + description: "Homemade handcuffs crafted from spare cables." + icon: { sprite: Objects/Misc/cablecuffs.rsi, state: cuff } + objectType: Item + +- type: construction + name: makeshift stunprod + id: makeshiftstunprod + graph: makeshiftstunprod + startNode: start + targetNode: msstunprod + category: construction-category-weapons + description: "Homemade stunprod." + icon: { sprite: Objects/Weapons/Melee/stunprod.rsi, state: stunprod_off } + objectType: Item + +- type: construction + name: muzzle + id: muzzle + graph: Muzzle + startNode: start + targetNode: muzzle + category: construction-category-tools + objectType: Item + description: "A muzzle to shut your victim up." + icon: + sprite: Clothing/Mask/muzzle.rsi + state: icon + +- type: construction + name: improvised pneumatic cannon + id: pneumaticcannon + graph: PneumaticCannon + startNode: start + targetNode: cannon + category: construction-category-weapons + objectType: Item + description: This son of a gun can fire anything that fits in it using just a little gas. + icon: + sprite: Objects/Weapons/Guns/Cannons/pneumatic_cannon.rsi + state: icon + +- type: construction + name: gauze + id: gauze + graph: Gauze + startNode: start + targetNode: gauze + category: construction-category-tools + objectType: Item + description: When you've really got nothing left. + icon: + sprite: Objects/Specific/Medical/medical.rsi + state: gauze + +- type: construction + name: blindfold + id: blindfold + graph: Blindfold + startNode: start + targetNode: blindfold + category: construction-category-tools + objectType: Item + description: Better hope everyone turns a blind eye to you crafting this sussy item... + icon: + sprite: Clothing/Eyes/Misc/blindfold.rsi + state: icon + +- type: construction + name: hairflower + id: hairflower + graph: hairflower + startNode: start + targetNode: hairflower + category: construction-category-clothing + description: "A red flower for beautiful ladies." + icon: + sprite: Clothing/Head/Misc/hairflower.rsi + state: icon + objectType: Item + +- type: construction + name: flower crown + id: flowercrown + graph: flowercrown + startNode: start + targetNode: flowercrown + category: construction-category-clothing + description: "A coronet of fresh and fragrant flowers." + icon: + sprite: Clothing/Head/Misc/flower-crown.rsi + state: icon + objectType: Item + +- type: construction + name: flower wreath + id: flowerwreath + graph: flowerwreath + startNode: start + targetNode: flowerwreath + category: construction-category-clothing + description: "A wreath of colourful flowers." + icon: + sprite: Clothing/Neck/Misc/flower-wreath.rsi + state: icon + objectType: Item + +- type: construction + name: damp rag + id: rag + graph: Rag + startNode: start + targetNode: rag + category: construction-category-tools + objectType: Item + description: A damp rag to clean up the ground. Better than slipping around all day. + icon: + sprite: Objects/Specific/Janitorial/rag.rsi + state: rag + +- type: construction + name: improvised shotgun + id: improvisedshotgun + graph: ImprovisedShotgunGraph + startNode: start + targetNode: shotgun + category: construction-category-weapons + objectType: Item + description: A shitty, single-shot shotgun made from salvaged and hand-crafted gun parts. Ammo not included. + icon: + sprite: Objects/Weapons/Guns/Shotguns/improvised_shotgun.rsi + state: icon + +- type: construction + name: improvised shotgun shell + id: ShellShotgunImprovised + graph: ImprovisedShotgunShellGraph + startNode: start + targetNode: shell + category: construction-category-weapons + objectType: Item + description: A homemade shotgun shell that shoots painful glass shrapnel. The spread is so wide that it couldn't hit the broad side of a Barn + icon: + sprite: Objects/Weapons/Guns/Ammunition/Casings/shotgun_shell.rsi + state: improvised + +- type: construction + name: rifle stock + id: riflestock + graph: RifleStockGraph + startNode: start + targetNode: riflestock + category: construction-category-weapons + objectType: Item + description: A stock carved out of wood, vital for improvised firearms. + icon: + sprite: Objects/Misc/rifle_stock.rsi + state: icon + +- type: construction + name: fire bomb + id: firebomb + graph: FireBomb + startNode: start + targetNode: firebomb + category: construction-category-weapons + objectType: Item + description: A weak, improvised incendiary device. + icon: + sprite: Objects/Weapons/Bombs/ied.rsi + state: icon + +- type: construction + name: cotton woven cloth + id: CottonWovenCloth + graph: CottonObjects + startNode: start + targetNode: cottoncloth + category: construction-category-misc + description: "A homemade piece of cotton cloth, it feels coarse." + icon: + sprite: Objects/Materials/materials.rsi + state: cloth_3 + objectType: Item + +- type: construction + name: straw hat + id: strawHat + graph: StrawHat + startNode: start + targetNode: strawhat + category: construction-category-clothing + description: A fancy hat for hot days! Not recommended to wear near fires. + icon: + sprite: Clothing/Head/Hats/straw_hat.rsi + state: icon + objectType: Item + +- type: construction + name: pipe bomb + id: pipebomb + graph: PipeBomb + startNode: start + targetNode: pipebomb + category: construction-category-weapons + objectType: Item + description: An improvised explosive made from pipes and wire. + icon: + sprite: Objects/Weapons/Bombs/pipebomb.rsi + state: icon \ No newline at end of file diff --git a/Resources/Prototypes/Recipes/Crafting/potato.yml b/Resources/Prototypes/Recipes/Crafting/potato.yml index afe70fa8be..17f2cc4013 100644 --- a/Resources/Prototypes/Recipes/Crafting/potato.yml +++ b/Resources/Prototypes/Recipes/Crafting/potato.yml @@ -1,32 +1,32 @@ -#- type: construction -# name: potato battery -# id: PowerCellPotato -# graph: PowerCellPotato -# startNode: start -# targetNode: potatobattery -# category: construction-category-misc -# description: A truly ingenious source of power. -# icon: { sprite: Objects/Power/power_cells.rsi, state: potato } -# objectType: Item -# -#- type: construction -# name: potato artificial intelligence -# id: PotatoAI -# graph: PotatoAI -# startNode: start -# targetNode: potatoai -# category: construction-category-misc -# description: The potato happens to be the perfect power source for this chip. -# icon: { sprite: Objects/Fun/pai.rsi, state: icon-potato-off } -# objectType: Item -# -#- type: construction -# name: supercompact AI chip -# id: PotatoAIChip -# graph: PotatoAIChip -# startNode: start -# targetNode: potatoaichip -# category: construction-category-misc -# description: A masterfully(?) crafted AI chip, requiring a similarly improvised power source. -# icon: { sprite: Objects/Misc/potatoai_chip.rsi, state: icon } -# objectType: Item \ No newline at end of file +- type: construction + name: potato battery + id: PowerCellPotato + graph: PowerCellPotato + startNode: start + targetNode: potatobattery + category: construction-category-misc + description: A truly ingenious source of power. + icon: { sprite: Objects/Power/power_cells.rsi, state: potato } + objectType: Item + +- type: construction + name: potato artificial intelligence + id: PotatoAI + graph: PotatoAI + startNode: start + targetNode: potatoai + category: construction-category-misc + description: The potato happens to be the perfect power source for this chip. + icon: { sprite: Objects/Fun/pai.rsi, state: icon-potato-off } + objectType: Item + +- type: construction + name: supercompact AI chip + id: PotatoAIChip + graph: PotatoAIChip + startNode: start + targetNode: potatoaichip + category: construction-category-misc + description: A masterfully(?) crafted AI chip, requiring a similarly improvised power source. + icon: { sprite: Objects/Misc/potatoai_chip.rsi, state: icon } + objectType: Item \ No newline at end of file diff --git a/Resources/Prototypes/Recipes/Crafting/smokeables.yml b/Resources/Prototypes/Recipes/Crafting/smokeables.yml index 7a2804a3b7..6d7d4e30bc 100644 --- a/Resources/Prototypes/Recipes/Crafting/smokeables.yml +++ b/Resources/Prototypes/Recipes/Crafting/smokeables.yml @@ -1,58 +1,58 @@ -#- type: construction -# name: joint -# id: smokeableJoint -# graph: smokeableJoint -# startNode: start -# targetNode: joint -# category: construction-category-misc -# description: "A roll of dried plant matter wrapped in thin paper." -# icon: { sprite: Objects/Consumable/Smokeables/Cannabis/joint.rsi, state: unlit-icon } -# objectType: Item -# -#- type: construction -# name: blunt -# id: smokeableBlunt -# graph: smokeableBlunt -# startNode: start -# targetNode: blunt -# category: construction-category-misc -# description: "A roll of dried plant matter wrapped in a dried tobacco leaf." -# icon: { sprite: Objects/Consumable/Smokeables/Cannabis/blunt.rsi, state: unlit-icon } -# objectType: Item -# -#- type: construction -# name: cigarette -# id: smokeableCigarette -# graph: smokeableCigarette -# startNode: start -# targetNode: cigarette -# category: construction-category-misc -# description: "A roll of tobacco and nicotine." -# icon: { sprite: Objects/Consumable/Smokeables/Cigarettes/cigarette.rsi, state: unlit-icon } -# objectType: Item +- type: construction + name: joint + id: smokeableJoint + graph: smokeableJoint + startNode: start + targetNode: joint + category: construction-category-misc + description: "A roll of dried plant matter wrapped in thin paper." + icon: { sprite: Objects/Consumable/Smokeables/Cannabis/joint.rsi, state: unlit-icon } + objectType: Item + +- type: construction + name: blunt + id: smokeableBlunt + graph: smokeableBlunt + startNode: start + targetNode: blunt + category: construction-category-misc + description: "A roll of dried plant matter wrapped in a dried tobacco leaf." + icon: { sprite: Objects/Consumable/Smokeables/Cannabis/blunt.rsi, state: unlit-icon } + objectType: Item + +- type: construction + name: cigarette + id: smokeableCigarette + graph: smokeableCigarette + startNode: start + targetNode: cigarette + category: construction-category-misc + description: "A roll of tobacco and nicotine." + icon: { sprite: Objects/Consumable/Smokeables/Cigarettes/cigarette.rsi, state: unlit-icon } + objectType: Item # I wanted to put a hand-grinder here but we need construction graphs that use non-consumed catalysts first. -#- type: construction -# name: ground cannabis -# id: smokeableGroundCannabis -# graph: smokeableGroundCannabis -# startNode: start -# targetNode: ground -# category: construction-category-misc -# description: "Ground cannabis, ready to take you on a trip." -# icon: { sprite: Objects/Misc/reagent_fillings.rsi, state: powderpile } -## color: darkgreen -# objectType: Item -# -#- type: construction -# name: ground tobacco -# id: smokeableGroundTobacco -# graph: smokeableGroundTobacco -# startNode: start -# targetNode: ground -# category: construction-category-misc -# description: "Ground tobacco, perfect for hand-rolled cigarettes." -# icon: { sprite: Objects/Misc/reagent_fillings.rsi, state: powderpile } -## color: brown -# objectType: Item +- type: construction + name: ground cannabis + id: smokeableGroundCannabis + graph: smokeableGroundCannabis + startNode: start + targetNode: ground + category: construction-category-misc + description: "Ground cannabis, ready to take you on a trip." + icon: { sprite: Objects/Misc/reagent_fillings.rsi, state: powderpile } +# color: darkgreen + objectType: Item + +- type: construction + name: ground tobacco + id: smokeableGroundTobacco + graph: smokeableGroundTobacco + startNode: start + targetNode: ground + category: construction-category-misc + description: "Ground tobacco, perfect for hand-rolled cigarettes." + icon: { sprite: Objects/Misc/reagent_fillings.rsi, state: powderpile } +# color: brown + objectType: Item diff --git a/Resources/Prototypes/Recipes/Crafting/tallbox.yml b/Resources/Prototypes/Recipes/Crafting/tallbox.yml index 65ef65d6a9..21a7ec8225 100644 --- a/Resources/Prototypes/Recipes/Crafting/tallbox.yml +++ b/Resources/Prototypes/Recipes/Crafting/tallbox.yml @@ -1,37 +1,37 @@ -#- type: construction -# id: ClosetSteel -# name: closet -# graph: ClosetSteel -# startNode: start -# targetNode: done -# category: construction-category-storage -# description: A tall steel box that cannot be locked. -# icon: { sprite: Structures/Storage/closet.rsi, state: generic_icon } -# objectType: Structure -# -#- type: construction -# id: ClosetSteelSecure -# name: secure closet -# graph: ClosetSteelSecure -# startNode: start -# targetNode: done -# category: construction-category-storage -# description: A tall steel box that can be locked. -# icon: { sprite: Structures/Storage/closet.rsi, state: secure_icon } -# objectType: Structure -# -#- type: construction -# id: ClosetWall -# name: wall closet -# graph: ClosetWall -# startNode: start -# targetNode: done -# category: construction-category-storage -# description: A standard-issue Nanotrasen storage unit, now on walls. -# icon: { sprite: Structures/Storage/wall_locker.rsi, state: generic_icon } -# objectType: Structure -# placementMode: SnapgridCenter -# canRotate: true -# canBuildInImpassable: true -# conditions: -# - !type:WallmountCondition \ No newline at end of file +- type: construction + id: ClosetSteel + name: closet + graph: ClosetSteel + startNode: start + targetNode: done + category: construction-category-storage + description: A tall steel box that cannot be locked. + icon: { sprite: Structures/Storage/closet.rsi, state: generic_icon } + objectType: Structure + +- type: construction + id: ClosetSteelSecure + name: secure closet + graph: ClosetSteelSecure + startNode: start + targetNode: done + category: construction-category-storage + description: A tall steel box that can be locked. + icon: { sprite: Structures/Storage/closet.rsi, state: secure_icon } + objectType: Structure + +- type: construction + id: ClosetWall + name: wall closet + graph: ClosetWall + startNode: start + targetNode: done + category: construction-category-storage + description: A standard-issue Nanotrasen storage unit, now on walls. + icon: { sprite: Structures/Storage/wall_locker.rsi, state: generic_icon } + objectType: Structure + placementMode: SnapgridCenter + canRotate: true + canBuildInImpassable: true + conditions: + - !type:WallmountCondition \ No newline at end of file diff --git a/Resources/Prototypes/Recipes/Crafting/tiles.yml b/Resources/Prototypes/Recipes/Crafting/tiles.yml index 0e017f22ec..433a3bec29 100644 --- a/Resources/Prototypes/Recipes/Crafting/tiles.yml +++ b/Resources/Prototypes/Recipes/Crafting/tiles.yml @@ -1,81 +1,81 @@ # These should be lathe recipes but lathe code sucks so hard rn so they'll be crafted by hand. -#- type: construction -# name: steel tile -# id: TileSteel -# graph: TileSteel -# startNode: start -# targetNode: steeltile -# category: construction-category-tiles -# description: "Four steel station tiles." -# icon: { sprite: Objects/Tiles/tile.rsi, state: steel } -# objectType: Item -# -#- type: construction -# name: wood floor -# id: TileWood -# graph: TileWood -# startNode: start -# targetNode: woodtile -# category: construction-category-tiles -# description: "Four pieces of wooden station flooring." -# icon: { sprite: Objects/Tiles/tile.rsi, state: wood } -# objectType: Item -# -#- type: construction -# name: filled brass plate -# id: TileBrassFilled -# graph: TilesBrass -# startNode: start -# targetNode: filledPlate -# category: construction-category-tiles -# description: "Four pieces of brass station flooring, only compatible with brass plating." -# icon: { sprite: Objects/Tiles/tile.rsi, state: brass-filled } -# objectType: Item -# -#- type: construction -# name: smooth brass plate -# id: TileBrassReebe -# graph: TilesBrass -# startNode: start -# targetNode: reebe -# category: construction-category-tiles -# description: "Four pieces of smooth brass station flooring, only compatible with brass plating." -# icon: { sprite: Objects/Tiles/tile.rsi, state: reebe } -# objectType: Item -# -#- type: construction -# name: white tile -# id: TileWhite -# graph: TileWhite -# startNode: start -# targetNode: whitetile -# category: construction-category-tiles -# description: "Four white station tiles." -# icon: { sprite: Objects/Tiles/tile.rsi, state: white } -# objectType: Item -# -#- type: construction -# name: dark tile -# id: TileDark -# graph: TileDark -# startNode: start -# targetNode: darktile -# category: construction-category-tiles -# description: "Four dark station tiles." -# icon: { sprite: Objects/Tiles/tile.rsi, state: dark } -# objectType: Item -# -#- type: construction -# name: flesh tile -# id: TileFlesh -# graph: TileFlesh -# startNode: start -# targetNode: fleshTile -# category: construction-category-tiles -# description: "Four fleshy tiles." -# icon: { sprite: Objects/Tiles/tile.rsi, state: meat } -# objectType: Item +- type: construction + name: steel tile + id: TileSteel + graph: TileSteel + startNode: start + targetNode: steeltile + category: construction-category-tiles + description: "Four steel station tiles." + icon: { sprite: Objects/Tiles/tile.rsi, state: steel } + objectType: Item + +- type: construction + name: wood floor + id: TileWood + graph: TileWood + startNode: start + targetNode: woodtile + category: construction-category-tiles + description: "Four pieces of wooden station flooring." + icon: { sprite: Objects/Tiles/tile.rsi, state: wood } + objectType: Item + +- type: construction + name: filled brass plate + id: TileBrassFilled + graph: TilesBrass + startNode: start + targetNode: filledPlate + category: construction-category-tiles + description: "Four pieces of brass station flooring, only compatible with brass plating." + icon: { sprite: Objects/Tiles/tile.rsi, state: brass-filled } + objectType: Item + +- type: construction + name: smooth brass plate + id: TileBrassReebe + graph: TilesBrass + startNode: start + targetNode: reebe + category: construction-category-tiles + description: "Four pieces of smooth brass station flooring, only compatible with brass plating." + icon: { sprite: Objects/Tiles/tile.rsi, state: reebe } + objectType: Item + +- type: construction + name: white tile + id: TileWhite + graph: TileWhite + startNode: start + targetNode: whitetile + category: construction-category-tiles + description: "Four white station tiles." + icon: { sprite: Objects/Tiles/tile.rsi, state: white } + objectType: Item + +- type: construction + name: dark tile + id: TileDark + graph: TileDark + startNode: start + targetNode: darktile + category: construction-category-tiles + description: "Four dark station tiles." + icon: { sprite: Objects/Tiles/tile.rsi, state: dark } + objectType: Item + +- type: construction + name: flesh tile + id: TileFlesh + graph: TileFlesh + startNode: start + targetNode: fleshTile + category: construction-category-tiles + description: "Four fleshy tiles." + icon: { sprite: Objects/Tiles/tile.rsi, state: meat } + objectType: Item # - type: construction # name: techmaint floor @@ -187,13 +187,13 @@ # icon: { sprite: Objects/Tiles/tile.rsi, state: dirty } # objectType: Item -#- type: construction -# name: large wood floor -# id: TileWoodLarge -# graph: TileWoodLarge -# startNode: start -# targetNode: woodtilelarge -# category: construction-category-tiles -# description: "Four pieces of wooden station flooring." -# icon: { sprite: Objects/Tiles/tile.rsi, state: wood-large } -# objectType: Item \ No newline at end of file +- type: construction + name: large wood floor + id: TileWoodLarge + graph: TileWoodLarge + startNode: start + targetNode: woodtilelarge + category: construction-category-tiles + description: "Four pieces of wooden station flooring." + icon: { sprite: Objects/Tiles/tile.rsi, state: wood-large } + objectType: Item \ No newline at end of file diff --git a/Resources/Prototypes/Recipes/Crafting/toys.yml b/Resources/Prototypes/Recipes/Crafting/toys.yml index afd37a3432..4fd91bdb69 100644 --- a/Resources/Prototypes/Recipes/Crafting/toys.yml +++ b/Resources/Prototypes/Recipes/Crafting/toys.yml @@ -1,25 +1,25 @@ -#- type: construction -# name: revenant plushie -# id: PlushieGhostRevenant -# graph: PlushieGhostRevenant -# startNode: start -# targetNode: plushie -# category: construction-category-misc -# objectType: Item -# description: A toy to scare the medbay with. -# icon: -# sprite: Mobs/Ghosts/revenant.rsi -# state: icon -# -#- type: construction -# name: ian suit -# id: ClothingOuterSuitIan -# graph: ClothingOuterSuitIan -# startNode: start -# targetNode: suit -# category: construction-category-misc -# objectType: Item -# description: Make yourself look just like Ian! -# icon: -# sprite: Clothing/OuterClothing/Suits/iansuit.rsi -# state: icon +- type: construction + name: revenant plushie + id: PlushieGhostRevenant + graph: PlushieGhostRevenant + startNode: start + targetNode: plushie + category: construction-category-misc + objectType: Item + description: A toy to scare the medbay with. + icon: + sprite: Mobs/Ghosts/revenant.rsi + state: icon + +- type: construction + name: ian suit + id: ClothingOuterSuitIan + graph: ClothingOuterSuitIan + startNode: start + targetNode: suit + category: construction-category-misc + objectType: Item + description: Make yourself look just like Ian! + icon: + sprite: Clothing/OuterClothing/Suits/iansuit.rsi + state: icon diff --git a/Resources/Prototypes/Recipes/Crafting/web.yml b/Resources/Prototypes/Recipes/Crafting/web.yml index 7268a4e607..5fe9d1b85a 100644 --- a/Resources/Prototypes/Recipes/Crafting/web.yml +++ b/Resources/Prototypes/Recipes/Crafting/web.yml @@ -1,111 +1,111 @@ -#- type: construction -# name: web tile -# id: TileWeb -# graph: WebObjects -# startNode: start -# targetNode: tile -# category: construction-category-tiles -# description: "Nice and smooth." -# entityWhitelist: -# tags: -# - SpiderCraft -# icon: -# sprite: Objects/Tiles/web.rsi -# state: icon -# objectType: Item -# -#- type: construction -# name: web winter coat -# id: ClothingOuterWinterWeb -# graph: WebObjects -# startNode: start -# targetNode: coat -# category: construction-category-clothing -# description: "Surprisingly warm and durable." -# entityWhitelist: -# tags: -# - SpiderCraft -# icon: -# sprite: Clothing/OuterClothing/WinterCoats/coatweb.rsi -# state: icon -# objectType: Item -# -#- type: construction -# name: web jumpsuit -# id: ClothingUniformJumpsuitWeb -# graph: WebObjects -# startNode: start -# targetNode: jumpsuit -# category: construction-category-clothing -# description: "At least it's something." -# entityWhitelist: -# tags: -# - SpiderCraft -# icon: -# sprite: Clothing/Uniforms/Jumpsuit/web.rsi -# state: icon -# objectType: Item -# -#- type: construction -# name: web jumpskirt -# id: ClothingUniformJumpskirtWeb -# graph: WebObjects -# startNode: start -# targetNode: jumpskirt -# category: construction-category-clothing -# description: "At least it's something." -# entityWhitelist: -# tags: -# - SpiderCraft -# icon: -# sprite: Clothing/Uniforms/Jumpskirt/web.rsi -# state: icon -# objectType: Item -# -#- type: construction -# name: silk woven cloth -# id: SilkWovenCloth -# graph: WebObjects -# startNode: start -# targetNode: cloth -# category: construction-category-materials -# description: "Feels just like cloth, strangely enough." -# entityWhitelist: -# tags: -# - SpiderCraft -# icon: -# sprite: Objects/Materials/materials.rsi -# state: cloth_3 -# objectType: Item -# -#- type: construction -# name: web shield -# id: WebShield -# graph: WebObjects -# startNode: start -# targetNode: shield -# category: construction-category-clothing -# description: "It's thick enough to handle a few blows, but probably not heat." -# entityWhitelist: -# tags: -# - SpiderCraft -# icon: -# sprite: Objects/Weapons/Melee/web-shield.rsi -# state: icon -# objectType: Item -# -#- type: construction -# name: web winter boots -# id: ClothingShoesBootsWinterWeb -# graph: WebObjects -# startNode: start -# targetNode: boots -# category: construction-category-clothing -# description: "Tightly woven web should protect against the cold" -# entityWhitelist: -# tags: -# - SpiderCraft -# icon: -# sprite: Clothing/Shoes/Boots/winterbootsweb.rsi -# state: icon -# objectType: Item +- type: construction + name: web tile + id: TileWeb + graph: WebObjects + startNode: start + targetNode: tile + category: construction-category-tiles + description: "Nice and smooth." + entityWhitelist: + tags: + - SpiderCraft + icon: + sprite: Objects/Tiles/web.rsi + state: icon + objectType: Item + +- type: construction + name: web winter coat + id: ClothingOuterWinterWeb + graph: WebObjects + startNode: start + targetNode: coat + category: construction-category-clothing + description: "Surprisingly warm and durable." + entityWhitelist: + tags: + - SpiderCraft + icon: + sprite: Clothing/OuterClothing/WinterCoats/coatweb.rsi + state: icon + objectType: Item + +- type: construction + name: web jumpsuit + id: ClothingUniformJumpsuitWeb + graph: WebObjects + startNode: start + targetNode: jumpsuit + category: construction-category-clothing + description: "At least it's something." + entityWhitelist: + tags: + - SpiderCraft + icon: + sprite: Clothing/Uniforms/Jumpsuit/web.rsi + state: icon + objectType: Item + +- type: construction + name: web jumpskirt + id: ClothingUniformJumpskirtWeb + graph: WebObjects + startNode: start + targetNode: jumpskirt + category: construction-category-clothing + description: "At least it's something." + entityWhitelist: + tags: + - SpiderCraft + icon: + sprite: Clothing/Uniforms/Jumpskirt/web.rsi + state: icon + objectType: Item + +- type: construction + name: silk woven cloth + id: SilkWovenCloth + graph: WebObjects + startNode: start + targetNode: cloth + category: construction-category-materials + description: "Feels just like cloth, strangely enough." + entityWhitelist: + tags: + - SpiderCraft + icon: + sprite: Objects/Materials/materials.rsi + state: cloth_3 + objectType: Item + +- type: construction + name: web shield + id: WebShield + graph: WebObjects + startNode: start + targetNode: shield + category: construction-category-clothing + description: "It's thick enough to handle a few blows, but probably not heat." + entityWhitelist: + tags: + - SpiderCraft + icon: + sprite: Objects/Weapons/Melee/web-shield.rsi + state: icon + objectType: Item + +- type: construction + name: web winter boots + id: ClothingShoesBootsWinterWeb + graph: WebObjects + startNode: start + targetNode: boots + category: construction-category-clothing + description: "Tightly woven web should protect against the cold" + entityWhitelist: + tags: + - SpiderCraft + icon: + sprite: Clothing/Shoes/Boots/winterbootsweb.rsi + state: icon + objectType: Item diff --git a/Resources/Prototypes/Recipes/Lathes/electronics.yml b/Resources/Prototypes/Recipes/Lathes/electronics.yml index c4417f868b..29ba973f10 100644 --- a/Resources/Prototypes/Recipes/Lathes/electronics.yml +++ b/Resources/Prototypes/Recipes/Lathes/electronics.yml @@ -962,6 +962,4 @@ result: ReagentGrinderIndustrialMachineCircuitboard completetime: 5 materials: - Steel: 100 - Glass: 900 - Gold: 100 + Steel: 100 \ No newline at end of file diff --git a/Resources/Prototypes/_CP14/Entities/Structures/Decoration/bonfire.yml b/Resources/Prototypes/_CP14/Entities/Structures/Decoration/bonfire.yml index 63c85d7436..3b6e4ed5bf 100644 --- a/Resources/Prototypes/_CP14/Entities/Structures/Decoration/bonfire.yml +++ b/Resources/Prototypes/_CP14/Entities/Structures/Decoration/bonfire.yml @@ -9,6 +9,9 @@ sprite: CrystallPunk/Structures/Decoration/bonfire.rsi layers: - state: bonfire + - type: Construction + graph: CPBonfire + node: CPBonfire - type: Fixtures fixtures: fix1: diff --git a/Resources/Prototypes/_CP14/Entities/Structures/Furniture/chairs.yml b/Resources/Prototypes/_CP14/Entities/Structures/Furniture/chairs.yml index 3ced1b8377..9ff83a2490 100644 --- a/Resources/Prototypes/_CP14/Entities/Structures/Furniture/chairs.yml +++ b/Resources/Prototypes/_CP14/Entities/Structures/Furniture/chairs.yml @@ -1,12 +1,15 @@ - type: entity name: деревянный стул description: Сколочен из самых обычных досок. Просто и эффективно! - id: ChairCPWooden + id: CPChairWooden parent: UnanchoredChairBase components: - type: Sprite sprite: CrystallPunk/Structures/Furniture/chairs.rsi state: wooden + - type: Construction + graph: CPSeat + node: CPChairWooden - type: Damageable damageModifierSet: Wood - type: Destructible diff --git a/Resources/Prototypes/_CP14/Entities/Structures/Furniture/tables.yml b/Resources/Prototypes/_CP14/Entities/Structures/Furniture/tables.yml index 3ec270990b..cfb82034e3 100644 --- a/Resources/Prototypes/_CP14/Entities/Structures/Furniture/tables.yml +++ b/Resources/Prototypes/_CP14/Entities/Structures/Furniture/tables.yml @@ -1,6 +1,6 @@ - type: entity parent: TableBase - id: TableWooden + id: CPTableWooden name: деревянный стол description: Простой стол, сколоченный из досок. components: @@ -8,6 +8,9 @@ sprite: CrystallPunk/Structures/Furniture/Tables/wood.rsi - type: Icon sprite: CrystallPunk/Structures/Furniture/Tables/wood.rsi + - type: Construction + graph: CPTable + node: CPTableWooden - type: Damageable damageModifierSet: Wood - type: Destructible diff --git a/Resources/Prototypes/_CP14/Recipes/Construction/Graphs/Furniture/bonfire.yml b/Resources/Prototypes/_CP14/Recipes/Construction/Graphs/Furniture/bonfire.yml new file mode 100644 index 0000000000..c0765116cf --- /dev/null +++ b/Resources/Prototypes/_CP14/Recipes/Construction/Graphs/Furniture/bonfire.yml @@ -0,0 +1,16 @@ +- type: constructionGraph + id: CPBonfire + start: start + graph: + - node: start + actions: + - !type:DestroyEntity {} + edges: + - to: CPBonfire + steps: + - material: WoodPlank + amount: 5 + doAfter: 3 + + - node: CPBonfire + entity: CPBonfire \ No newline at end of file diff --git a/Resources/Prototypes/_CP14/Recipes/Construction/Graphs/Furniture/seats.yml b/Resources/Prototypes/_CP14/Recipes/Construction/Graphs/Furniture/seats.yml new file mode 100644 index 0000000000..f9796fd8e6 --- /dev/null +++ b/Resources/Prototypes/_CP14/Recipes/Construction/Graphs/Furniture/seats.yml @@ -0,0 +1,16 @@ +- type: constructionGraph + id: CPSeat + start: start + graph: + - node: start + actions: + - !type:DestroyEntity {} + edges: + - to: CPChairWooden + steps: + - material: WoodPlank + amount: 4 + doAfter: 2 + + - node: CPChairWooden + entity: CPChairWooden \ No newline at end of file diff --git a/Resources/Prototypes/_CP14/Recipes/Construction/Graphs/Furniture/tables.yml b/Resources/Prototypes/_CP14/Recipes/Construction/Graphs/Furniture/tables.yml new file mode 100644 index 0000000000..c26ef4e5a2 --- /dev/null +++ b/Resources/Prototypes/_CP14/Recipes/Construction/Graphs/Furniture/tables.yml @@ -0,0 +1,16 @@ +- type: constructionGraph + id: CPTable + start: start + graph: + - node: start + actions: + - !type:DestroyEntity {} + edges: + - to: CPTableWooden + steps: + - material: WoodPlank + amount: 3 + doAfter: 2 + + - node: CPTableWooden + entity: CPTableWooden \ No newline at end of file diff --git a/Resources/Prototypes/_CP14/Recipes/Construction/furniture.yml b/Resources/Prototypes/_CP14/Recipes/Construction/furniture.yml new file mode 100644 index 0000000000..44f38fa5d2 --- /dev/null +++ b/Resources/Prototypes/_CP14/Recipes/Construction/furniture.yml @@ -0,0 +1,53 @@ +- type: construction + crystallPunkAllowed: true + name: Деревянный стул + description: Сколочен из самых обычных досок. Просто и эффективно! + id: CPChairWooden + graph: CPSeat + startNode: start + targetNode: CPChairWooden + category: construction-category-furniture + icon: + sprite: CrystallPunk/Structures/Furniture/chairs.rsi + state: wooden + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + crystallPunkAllowed: true + name: Деревянный стол + description: Простой стол, сколоченный из досок. + id: CPTableWooden + graph: CPTable + startNode: start + targetNode: CPTableWooden + category: construction-category-furniture + icon: + sprite: CrystallPunk/Structures/Furniture/Tables/wood.rsi + state: full + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked + +- type: construction + crystallPunkAllowed: true + name: Костёр + description: Груда бревен, сложенных вместе, и готовых вспыхнуть от малейшей искры. + id: CPBonfire + graph: CPBonfire + startNode: start + targetNode: CPBonfire + category: construction-category-furniture + icon: + sprite: CrystallPunk/Structures/Decoration/bonfire.rsi + state: bonfire + objectType: Structure + placementMode: SnapgridCenter + canBuildInImpassable: false + conditions: + - !type:TileNotBlocked \ No newline at end of file From 802af538a827e86671354fee314d6c953c045a31 Mon Sep 17 00:00:00 2001 From: Ed <96445749+TheShuEd@users.noreply.github.com> Date: Wed, 3 Apr 2024 10:33:34 +0300 Subject: [PATCH 4/7] Upstream, Yay (#27) * Make BaseMedicalPDA abstract (#26567) * Fix GasMixers/Filters not working (#26568) * Fix GasMixers/Filters not working * OKAY GAS FILTERS TOO --------- Co-authored-by: Plykiya * Industrial Reagent Grinder Hotfix (#26571) fixed * Give stores the ability to check for owner only (#26573) adds a check if the store belongs to the user * Fix round start crash (causing instant restart) (#26579) * Fix round start crash * Make `TryCreateObjective` more error tolerant * Update engine to v217.1.0 (#26588) * Fix initial infected icon hiding (#26585) * Fix Meta evac shuttle name (#26587) * Make timer ignore client predict setting (#26554) * Make timer ignore client predict setting * making tests run --------- Co-authored-by: wrexbe * Make advertise system survive no map inits (#26553) * Make advertise system survive no map inits * Add comment to try prevent future bugs * Update Credits (#26589) Co-authored-by: PJBot * Fix fox spawn on reach (#26584) Co-authored-by: wrexbe * Removes SCAF armor (#26566) * removes scaf armor * replace maint loot spawner spot with basic helmet * Update Patrons.yml (#26578) * Automatic changelog update * Make aghost command work on other players using optional argument (#26546) * Translations * Make aghost command work on other players using optional argument * Reviews * Automatic changelog update * Add new component to Make sound on interact (#26523) * Adds new Component: EmitSoundOnInteractUsing * Missed an import * File-scoping * Replace ID check with Prototype check * Moved component and system to shared. Set prediction to true. * Removed impoper imports and changed namespace of component to reflect changed folder. * Following function naming theme * All this code is basically deltanedas's, but it was a learning experience for me * Update Content.Shared/Sound/Components/EmitSoundOnInteractUsingComponent.cs * Update Content.Shared/Sound/Components/EmitSoundOnInteractUsingComponent.cs --------- Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> * Increase syndi duffelbag storage (#26565) * Increase syndi duffelbag storage * weh * Automatic changelog update * Adds construction/decon graphs for plastic flaps (#26341) * Adds construction/decon graphs for plastic flaps * Dang arbitrage * undo conflict --------- Co-authored-by: Velcroboy * Automatic changelog update * Makes secglasses roundstart (#26487) * makes secglasses roundstart * fix epic fail * fix tests questionmark? * Update Resources/Prototypes/Entities/Clothing/Eyes/glasses.yml Co-authored-by: Nemanja <98561806+EmoGarbage404@users.noreply.github.com> --------- Co-authored-by: Nemanja <98561806+EmoGarbage404@users.noreply.github.com> * Automatic changelog update * Toilet Upgrade (needs review) (#22133) * Toilet Draft * fixes * toilets now have secret stash to place items in cistern. * fixes * plungers now unblock toilets. * fix sprite * new sprites and fix * fixes * improve seat sprites. * fix * removed visualisersystem changed to genericvisualizers * flush sound for toilets and copyright for toilet sprites. * fix atrributions * fixes * fix datafield flushtime * sprite improvements * fixes * multiple changes * fix * fix * fixes remove vv * moved stash related functions to secret stash system from toilet. * fix * fix * changes for recent review. * fix * fix * Automatic changelog update * Uplink store interface searchable with a searchbar. (#24287) * Can now search the uplink store interface with a searchbar. * Search text updates no longer send server messages. Persists listings locally. * Formatting fixes and tidying. * Added helper method to get localised name and description (or otherwise, entity name and description) of store listing items. * Update Content.Client/Store/Ui/StoreMenu.xaml * Review change; moved localisation helper functions to their own class. * Prevent thread-unsafe behaviour as-per review. * Remove dummy boxcontainer --------- Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Co-authored-by: metalgearsloth * Automatic changelog update * Improved RCDs (#22799) * Initial radial menu prototyping for the RCD * Radial UI buttons can send messages to the server * Beginning to update RCDSystem * RCD building system in progress * Further updates * Added extra effects, RCDSystem now reads RCD prototype data * Replacing tiles is instant, multiple constructions are allowed, deconstruction is broken * Added extra functionality to RadialContainers plus documentation * Fixed localization of RCD UI strings * Menu opens near cursor, added basic RCD * Avoiding merge conflict * Implemented atomized construction / deconstruction rules * Increased RCD ammo base charges * Moved input context definition to content * Removed obsoleted code * Updates to system * Switch machine and computer frames for electrical cabling * Added construction ghosts * Fixed issue with keybind detection code * Fixed RCD construction ghost mispredications * Code clean up * Updated deconstruction effects * RCDs effects don't rotate * Code clean up * Balancing for ammo counts * Code clean up * Added missing localized strings * More clean up * Made directional window handling more robust * Added documentation to radial menus and made them no longer dependent on Content * Made radial containers more robust * Further robustness to the radial menu * The RCD submenu buttons are only shown when the destination layer has at least one children * Expanded upon deconstructing plus construction balance * Fixed line endings * Updated list of RCD deconstructable entities. Now needs a component to deconstruct instead of a tag * Bug fixes * Revert unnecessary change * Updated RCD strings * Fixed bug * More fixes * Deconstructed tiles/subflooring convert to lattice instead * Fixed failed tests (Linux doesn't like invalid spritespecifer paths) * Fixing merge conflict * Updated airlock assembly * Fixing merge conflict * Fixing merge conflict * More fixing... * Removed erroneous project file change * Fixed string handling issue * Trying to fix merge conflict * Still fixing merge conflicts * Balancing * Hidden RCD construction ghosts when in 'build' mode * Fixing merge conflict * Implemented requested changes (Part 1) * Added more requested changes * Fix for failed test. Removed sussy null suppression * Made requested changes - custom construction ghost system was replaced * Fixing merge conflict * Fixed merge conflict * Fixed bug in RCD construction ghost validation * Fixing merge conflict * Merge conflict fixed * Made required update * Removed lingering RCD deconstruct tag * Fixing merge conflict * Merge conflict fixed * Made requested changes * Bug fixes and balancing * Made string names more consistent * Can no longer stack catwalks * Automatic changelog update * Update submodule to 217.2.0 (#26592) * Southern accent (#26543) * created the AccentComponent and the AccentSystem * word replacement schtuhff * made it a trait fr ongg!!1 * Update Content.Server/Speech/EntitySystems/SouthernAccentSystem.cs --------- Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> * Prevent storing liquids in equipped buckets (#24412) * Block access to solutions in equipped spillables. * Stop Drink verb appearing if the solution can't be accessed. * Automatic changelog update * Fix 'Hypopen shouldn't display solution examine text' (#26453) * stealthy hypo * ExaminableSolution hand check when in covert implement. ExaminableSolution now has 'hidden' datafield to enable chemical inspection only in hand. * cleaning code * more cleaning * Hidden datafield renamed to HeldOnly * review --------- Co-authored-by: metalgearsloth * Automatic changelog update * Revert Paint (#26593) * Revert "Fix build (#26258)" This reverts commit 6de5fbfafbde700d711a566f6a43f05f7a99e455. * Revert "Spray Paint (Review Ready) (#23003)" This reverts commit e4d5e7f1aebfc37b1bc3453fdb39578f3897b6a1. # Conflicts: # Resources/Prototypes/Entities/Structures/Holographic/projections.yml * Fix: Prevent single-use hyposprays from getting the toggle draw verb (#26595) Prevent single-use hyposprays from getting the toggle draw verb Co-authored-by: Plykiya * MeleeHitSoundSystem (#25005) * Began work to unscrew melee noises * finished * cleanup * cleanup * Update Content.Server/Weapons/Melee/MeleeWeaponSystem.cs Co-authored-by: Ed <96445749+TheShuEd@users.noreply.github.com> * _Style * Fix merge --------- Co-authored-by: Ed <96445749+TheShuEd@users.noreply.github.com> Co-authored-by: metalgearsloth * Remove physics comp from VendingMachineWallmount (#25632) * Remove physics comp from VendingMachineWallmount * Fixtures removal --------- Co-authored-by: Jeff Co-authored-by: metalgearsloth * Remake hairflowers (#25475) * Add more lily usage (orange hairflower and flowercrown) * comit 2 * ee * more fixes * w * im stupid * bring poppy in authodrobe * weh --------- Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> * Automatic changelog update * Injector UI shows TransferAmount change, Spilling liquid changes Injector mode (#26596) * Injector UI shows TransferAmount change, spill changes mode * Update Content.Shared/Fluids/SharedPuddleSystem.Spillable.cs * Update Content.Shared/Fluids/SharedPuddleSystem.Spillable.cs --------- Co-authored-by: Plykiya Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> * Update submodule to 217.2.1 (#26599) * disallow unanchoring or opening panels on locked emitters/APEs (#26600) * disallow unanchoring or opening panels on locked emitters/APEs * no locking open panels * oops * needback feedback * Update Content.Shared/Lock/LockSystem.cs * Update Content.Shared/Lock/LockSystem.cs * Update Content.Shared/Lock/LockSystem.cs * sanity --------- Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Co-authored-by: metalgearsloth * Automatic changelog update * Fix grave digging sound indefinitely playing if dug by aghost. (#26420) Admins bypass doafters. As such, the code that runs on doafter completion is ran before the sound is actually created. This then leads to the sound never being stopped, and as such it would infinitely play. This commit gets around the issue by manually stopping the sound should the doafter fail to start. If we could be sure that the doafter would never fail, then we could just move the call to StartDigging above starting the doafter but this is currently not possible. Co-authored-by: metalgearsloth * Make the buttons on the map ui not squished (#26604) Make the map ui work Co-authored-by: wrexbe * Combine flower crown and wreath (#26605) * Combine flower crown and wreath * huh * huuh :trollface: * Automatic changelog update * Add AP damage to throwing knives (#26380) * add * ap * no more stam dmg * Automatic changelog update * cancelable brig timers (#26557) brig timers now cancelable. also some screensystem yakshave * Fix orientation of roller skate sprites (#26627) Co-authored-by: Eoin Mcloughlin * Automatic changelog update * Fix GastTileOverlay sending redundant data (#26623) Fix GastTileOverlay not updating properly * Auto DeAdmin sooner (#26551) Co-authored-by: wrexbe * Add briefcase to curadrobe and lawdrobe, and some briefcases cleanup (#26527) * Add briefcase to curadrobe and some briefcases cleanup * also add to lawdrobe * Automatic changelog update * Fix some text overflow bugs in HUD (#26615) * Don't clip text in item status * Fix overflow in examine tooltip --------- Co-authored-by: Eoin Mcloughlin * Adds two milk cartons to the BoozeOMat (#26635) * Automatic changelog update * made the hover text less vague (sorry) (#26630) * blacklisted throwing knifes from pneumatic cannon (#26628) * Fix radio jammer not blocking suit sensors. (#26632) As it turns out, they are not in fact on their own netid. They are actually just on wireless. The way I had tested my previous pr led to this mistake being made. I originally had the radio jammer block wireless as well, but decided to take out under the flase assumption that it suit sensors were actually on their own netid and did not require the ability to block all wireless packets at the last moment. * Fix dirt decals in reach not being cleanable (#26636) made all dirt decals cleanable Co-authored-by: hamurlik * Automatic changelog update * Replace drill_hit.ogg and drill_use.ogg with better sounds (#26622) * Replace drill_hit.ogg and drill_use.ogg with better sounds * Fix attribution source for drill_hit.ogg * Update Resources/Audio/Items/attributions.yml Co-authored-by: Kara * Update Resources/Audio/Items/attributions.yml Co-authored-by: Kara --------- Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Co-authored-by: Kara * Gave Blast door access permissions (#26606) Added access reader to all blast doors. Added pre configured blast doors for engineering and science. * Gives all wheeled objects low friction (#26601) * gives all wheeled objects friction * adjustments to sum stuff * Automatic changelog update * Combine solution injection systems; Fix embeddable injectors (#26268) * Combine injection systems * Update Content.Server/Chemistry/EntitySystems/SolutionInjectOnEventSystem.cs --------- Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> * Automatic changelog update * Add ValueList import (#26640) * Change assault borg modules texture (#26502) * Update borg_modules.yml * Fix borg_modules.yml? * Uh --------- Co-authored-by: metalgearsloth * Automatic changelog update * Add Cyborg Emote Sounds (#26594) * Hal 9000's first emote * Add Chime emote & Change variation to 0.05 * Modify Buzz emote * Add Buzz-two emote * modified Horn * add ping emote * add slowclap emote * Convert slowclap.ogg to mono, reflect change in attribution.yml * fix capitalization for all chatMessages && change all catagory to category * remove all traces of slowclap.ogg * forgor one file smh * collating copywrite * spelling mistakes will be the death of me * more spelling mistakes * change yml string to list * Automatic changelog update * Coordinates Disks & Shuttle FTL Travel (#23240) * Adds the CentComm Disk and configures it to work with direct-use shuttles * Added functionality for drone shuttles (i.e. cargo shuttle) * Adds support for pods, and a disk console object for disks to be inserted into. Also sprites. * Added the disk to HoP's locker * Removed leftover logs & comments * Fix for integration test * Apply suggestions from code review (formatting & proper DataField) Co-authored-by: 0x6273 <0x40@keemail.me> * Fix integration test & changes based on code review * Includes Disk Cases to contain Coordinate Disks, which are now CDs instead of Floppy Disks * Check pods & non-evac shuttles for CentCom travel, even in FTL * Import * Remove CentCom travel restrictions & pod disk consoles * Major changes that changes the coordinates disk system to work with salvage expeditions * Missed CC diskcase removal * Fix build * Review suggestions and changes * Major additional changes after merge * Minor tag miss * Integration test fix * review --------- Co-authored-by: 0x6273 <0x40@keemail.me> Co-authored-by: metalgearsloth * Automatic changelog update * Add door electronics access configuration menu (#17778) * Add door electronics configuration menu * Use file-scoped namespaces Signed-off-by: c4llv07e * Open door electronics configuration menu only with network configurator Signed-off-by: c4llv07e * Doors will now try to move their AccessReaderComponent to their door electronics when the map is initialized Signed-off-by: c4llv07e * Make the access list in the id card computer a separate control Signed-off-by: c4llv07e * Fix merge conflict Signed-off-by: c4llv07e * Remove DoorElectronics tag Signed-off-by: c4llv07e * Integrate doors with #17927 Signed-off-by: c4llv07e * Move door electornics ui stuff to the right place Signed-off-by: c4llv07e * Some review fixes Signed-off-by: c4llv07e * More fixes Signed-off-by: c4llv07e * review fix Signed-off-by: c4llv07e * move all accesses from airlock prototypes to door electronics Signed-off-by: c4llv07e * rework door electronics config access list Signed-off-by: c4llv07e * Remove Linq from the door electronics user interface * [WIP] Add EntityWhitelist to the activatable ui component Signed-off-by: c4llv07e * Better interaction system Signed-off-by: c4llv07e * Refactor Signed-off-by: c4llv07e * Fix some door electronics not working without AccessReaderComponent Signed-off-by: c4llv07e * Move AccessReaderComponent update code to the AccessReaderSystem Signed-off-by: c4llv07e * Remove unnecesary newlines in the door access prototypes Signed-off-by: c4llv07e * Remove unused variables in access level control Signed-off-by: c4llv07e * Remove unnecessary method from the door electronics configuration menu Signed-off-by: c4llv07e * [WIP] change access type from string to ProtoId Signed-off-by: c4llv07e * Remove unused methods Signed-off-by: c4llv07e * Newline fix Signed-off-by: c4llv07e * Restored to a functional state Signed-off-by: c4llv07e * Fix access configurator not working with door electronics AccessReaderComponent Signed-off-by: c4llv07e * Replace all string access fields with ProtoId Signed-off-by: c4llv07e * move access level control initialization into Populate method Signed-off-by: c4llv07e * Review --------- Signed-off-by: c4llv07e Co-authored-by: metalgearsloth * Automatic changelog update * scoopable ash and foam, solution transfer prediction (#25832) * move SolutionTransfer to shared and predict as much as possible * fully move OpenableSystem to shared now that SolutionTransfer is * fix imports for everything * doc for solution transfer system * trolling * add scoopable system * make ash and foam scoopable * untroll * untroll real * make clickable it work * troll * the scooping room --------- Co-authored-by: deltanedas <@deltanedas:kde.org> Co-authored-by: metalgearsloth * Replace the teleportation logic on the SCRAM implant! (#26429) * Replace the teleportation logic on the SCRAM implant! Now instead of just trying to pick a random tile in range 20 times, the scram teleportation logic now: - Gets a list of grids in range - Until a suitable tile is picked it picks a random grid - From that grid it picks a random tile. - If the tile is suitable, then it is set as the target and the user will be teleported there. - Grids and tiles are randomly picked as outlined above until a valid tile is found, or all valid grids and tiles are exhausted. - Should no suitable tile be found then they get teleported to the same position they are at. Effectively not teleporting them. * Actually make the defaults sane which I forgor in the last commit * Extract tile section to its own function. Bias selection for current grid. Use proper coords for box. * Address reviews as much as possible * Address reviews * Refactored AdvertiseComponent (#26598) * Made it better * ok * alright --------- Co-authored-by: wrexbe * Bartender "Essentials" (#25367) * drinks round 1 saving my progress before my hard drive explodes * test 2 please work * name fixes whoops * Update drinks.yml * various fixes am dumb * add sol dry to vends more fixes and changes, yippee! * more fixes & ingame testing shrimple tests * last fixes :trollface: should be ready for pr now * Update soda.yml sate thirst * Automatic changelog update * Add ERT Chaplain (#25956) * ERT Chaplain * Make BibleUser * It was not intended * reword my poor words * 1984 a comment that I decided was unnecessary. * Update Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml --------- Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> * Changes in chemicals page in guidebook (#25831) * Added pages to chemical categories The chemical categories have their own page now. Added the "Chemical Tabs" in /ServerInfo/Guidebook. Moved the Chemicals code from shiftsandjobs.yml to its own .yml file which is "chemicals.yml". * Update guides.ftl * Update chemicals.yml Changed the guide entry's ID for the medical tab from Medicine to Medicinal. Hope this works... * Update Resources/ServerInfo/Guidebook/Chemical Tabs/Biological.xml Co-authored-by: exincore * Update Resources/ServerInfo/Guidebook/Chemical Tabs/Foods.xml Co-authored-by: exincore * Update Resources/ServerInfo/Guidebook/Chemical Tabs/Elements.xml Co-authored-by: exincore * Update Resources/ServerInfo/Guidebook/Chemical Tabs/Narcotics.xml Co-authored-by: exincore * Update Resources/ServerInfo/Guidebook/Chemical Tabs/Toxins.xml Co-authored-by: exincore * Fixed a few errors and stuff! A few typos have been fixed thanks to exincore. Added dedicated .xml files to be used for the dedicated category pages (Medicinal and Botanical pages). Made it so it doesn't use any duplicated IDs anymore. If there's more problems, please do tell so I can fix it! * Update settings.json * Fix? --------- Co-authored-by: exincore * Automatic changelog update * Anomalies behaviours (#24683) * Added new anomaly particle * Add basic anomaly behaviour * +2 parametres * add functional to new particle * add components to behaviours * big content * add shuffle, moved thing to server * clean up * fixes * random pick redo * bonjour behavioUr * fix AJCM * fix * add some new behaviours * power modifier behaviour * rmeove timer * new event for update ui fix * refactor! * fixes * enum * Fix mapinit * Minor touches --------- Co-authored-by: metalgearsloth * Automatic changelog update * Fix clipping/overlap in lathe machine UIs (#26646) * Add scrollbars to lathe material list when necessary * Fix bug where shrinking window would cause elements to overlap --------- Co-authored-by: Eoin Mcloughlin * Added chat window transparency slider to options (#24990) * Adds a new slider to the misc tab in options that lets the player set chat window transparency * Tweaked variable names * Fixed order to match UI * Renamed set chat window transparency function * Changed and refactored to opacity instead of transparency * Remove unnecessary int to float conversions Slider used to be 0-100 while the CCVar was 0.0-1.0f. This is confusing and was only used for rounding to 2 decimal points. * Round the value to two decimal points * Remove rounding for now * Rename * Unhardcode chat color by moving to stylesheet * Fix indent * Make opacity slider only change opacity --------- Co-authored-by: Your Name Co-authored-by: ShadowCommander <10494922+ShadowCommander@users.noreply.github.com> * Automatic changelog update * Infinity books (#25840) * setup text data * roundstart reshuffling keywords with gibberish words * saved data categorized * add book with hints * start redrawing books * +4 book design * +books +random visual upgrade * finish first file * finish lore file * finish with books.rsi now authorbooks.rsi... * aurora! and some fix * nuke author books * speelbuke update * finish respriting work * fix scientist guide visual * setup datasets * setup stupid funny random story * restore author books, upgrade hint generation * add variety to story generator * add learning system * minor textgen edit * file restruct, hint count variation * more restruct * more renaming add basis learning system logic. Spears locked for special book for test. * nuke all systems, for splitting PR gods * typo fix * update migration with deleted books * add random story books to maint * Update construction-system.ftl * Update Resources/Prototypes/Datasets/Names/books.yml Co-authored-by: chromiumboy <50505512+chromiumboy@users.noreply.github.com> * Update Resources/Prototypes/Datasets/Names/books.yml Co-authored-by: chromiumboy <50505512+chromiumboy@users.noreply.github.com> * Update Resources/Prototypes/Datasets/Names/books.yml Co-authored-by: chromiumboy <50505512+chromiumboy@users.noreply.github.com> * Update Resources/Prototypes/Datasets/Names/books.yml Co-authored-by: chromiumboy <50505512+chromiumboy@users.noreply.github.com> * Update Resources/Prototypes/Datasets/Names/books.yml Co-authored-by: chromiumboy <50505512+chromiumboy@users.noreply.github.com> * Update Resources/Prototypes/Datasets/Names/books.yml Co-authored-by: chromiumboy <50505512+chromiumboy@users.noreply.github.com> * Update Resources/Prototypes/Datasets/Names/books.yml Co-authored-by: Hrosts <35345601+Hrosts@users.noreply.github.com> * Update Resources/Prototypes/Datasets/Names/books.yml Co-authored-by: chromiumboy <50505512+chromiumboy@users.noreply.github.com> * Update Resources/Prototypes/Datasets/Names/books.yml Co-authored-by: chromiumboy <50505512+chromiumboy@users.noreply.github.com> * Update Resources/Prototypes/Datasets/Names/books.yml Co-authored-by: chromiumboy <50505512+chromiumboy@users.noreply.github.com> * Update Resources/Prototypes/Datasets/Names/books.yml Co-authored-by: chromiumboy <50505512+chromiumboy@users.noreply.github.com> * Update Resources/Prototypes/Datasets/Names/books.yml Co-authored-by: chromiumboy <50505512+chromiumboy@users.noreply.github.com> * typo fix * interchangeably * final * Update Resources/Prototypes/Datasets/Names/books.yml Co-authored-by: Hrosts <35345601+Hrosts@users.noreply.github.com> * "." * Update Content.Server/Paper/PaperRandomStorySystem.cs Co-authored-by: Hrosts <35345601+Hrosts@users.noreply.github.com> * Ubazer fix * inadequate * localized * Update meta.json * fuck merge conflicts * fix jani book --------- Co-authored-by: chromiumboy <50505512+chromiumboy@users.noreply.github.com> Co-authored-by: Hrosts <35345601+Hrosts@users.noreply.github.com> * Automatic changelog update * Resprite ambuzol plus pills (#26651) * Automatic changelog update * Fixed air injector visuals (#26654) * Make cyborgs hands explosion proof. (#26515) * Make the advanced treatment modules beakers explosion-proof. * undo changes * Epic rename fail * Explosion recursion data field * Logic for data field * Automatic changelog update * Automatic changelog update * Make typing indicator shaded (#26678) * Automatic changelog update * Validate wire layout prototypes and remove invalid WiresComponents (#26682) Validate wire layout prototypes; delete invalid wirescomponents. * Increase time inbetween anomaly pulses (#26677) nerf anomaly pulse delays * Automatic changelog update * Fix for items dropped being rotated to world north (#26662) * Fix rotation of dropped items * combined world position rotation function for dumpable * scuffed implementation? * less scuffed? * even less scuffed... I guess * capital D --------- Co-authored-by: Plykiya * Automatic changelog update * fix typo --------- Signed-off-by: c4llv07e Co-authored-by: lzk <124214523+lzk228@users.noreply.github.com> Co-authored-by: Plykiya <58439124+Plykiya@users.noreply.github.com> Co-authored-by: Plykiya Co-authored-by: Boaz1111 <149967078+Boaz1111@users.noreply.github.com> Co-authored-by: keronshb <54602815+keronshb@users.noreply.github.com> Co-authored-by: Wrexbe (Josh) <81056464+wrexbe@users.noreply.github.com> Co-authored-by: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com> Co-authored-by: wrexbe Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: PJBot Co-authored-by: Flareguy <78941145+Flareguy@users.noreply.github.com> Co-authored-by: DrSmugleaf Co-authored-by: Simon <63975668+Simyon264@users.noreply.github.com> Co-authored-by: blueDev2 <89804215+blueDev2@users.noreply.github.com> Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Co-authored-by: Velcroboy <107660393+IamVelcroboy@users.noreply.github.com> Co-authored-by: Velcroboy Co-authored-by: Nemanja <98561806+EmoGarbage404@users.noreply.github.com> Co-authored-by: brainfood1183 <113240905+brainfood1183@users.noreply.github.com> Co-authored-by: J. Brown Co-authored-by: metalgearsloth Co-authored-by: chromiumboy <50505512+chromiumboy@users.noreply.github.com> Co-authored-by: UBlueberry <161545003+UBlueberry@users.noreply.github.com> Co-authored-by: Tayrtahn Co-authored-by: drteaspoon420 <87363733+drteaspoon420@users.noreply.github.com> Co-authored-by: Bixkitts <72874643+Bixkitts@users.noreply.github.com> Co-authored-by: nikthechampiongr <32041239+nikthechampiongr@users.noreply.github.com> Co-authored-by: Ubaser <134914314+UbaserB@users.noreply.github.com> Co-authored-by: avery <51971268+graevy@users.noreply.github.com> Co-authored-by: eoineoineoin Co-authored-by: Eoin Mcloughlin Co-authored-by: RiceMar1244 <138547931+RiceMar1244@users.noreply.github.com> Co-authored-by: Zealith-Gamer <61980908+Zealith-Gamer@users.noreply.github.com> Co-authored-by: hamurlik <75280571+hamurlik@users.noreply.github.com> Co-authored-by: hamurlik Co-authored-by: no <165581243+pissdemon@users.noreply.github.com> Co-authored-by: Kara Co-authored-by: SoulFN <164462467+SoulFN@users.noreply.github.com> Co-authored-by: Keer-Sar <144283718+Keer-Sar@users.noreply.github.com> Co-authored-by: SlamBamActionman <83650252+SlamBamActionman@users.noreply.github.com> Co-authored-by: 0x6273 <0x40@keemail.me> Co-authored-by: c4llv07e <38111072+c4llv07e@users.noreply.github.com> Co-authored-by: deltanedas <39013340+deltanedas@users.noreply.github.com> Co-authored-by: Firewatch <54725557+musicmanvr@users.noreply.github.com> Co-authored-by: IProduceWidgets <107586145+IProduceWidgets@users.noreply.github.com> Co-authored-by: f0x-n3rd <150924715+f0x-n3rd@users.noreply.github.com> Co-authored-by: exincore Co-authored-by: Sk1tch Co-authored-by: Your Name Co-authored-by: ShadowCommander <10494922+ShadowCommander@users.noreply.github.com> Co-authored-by: Hrosts <35345601+Hrosts@users.noreply.github.com> Co-authored-by: osjarw <62134478+osjarw@users.noreply.github.com> --- .../Access/UI/AccessLevelControl.xaml | 4 + .../Access/UI/AccessLevelControl.xaml.cs | 52 ++ .../UI/AccessOverriderBoundUserInterface.cs | 2 +- .../Access/UI/AccessOverriderWindow.xaml.cs | 17 +- .../UI/IdCardConsoleBoundUserInterface.cs | 4 +- .../Access/UI/IdCardConsoleWindow.xaml | 6 +- .../Access/UI/IdCardConsoleWindow.xaml.cs | 51 +- .../Anomaly/Ui/AnomalyScannerMenu.xaml | 6 +- .../Chemistry/UI/InjectorStatusControl.cs | 3 + .../Disposal/Systems/DisposalUnitSystem.cs | 24 +- .../DoorElectronicsBoundUserInterface.cs | 59 ++ .../DoorElectronicsConfigurationMenu.xaml | 6 + .../DoorElectronicsConfigurationMenu.xaml.cs | 41 + Content.Client/Examine/ExamineSystem.cs | 27 +- Content.Client/Input/ContentContexts.cs | 3 + Content.Client/Lathe/UI/LatheMenu.xaml | 4 +- .../Materials/UI/MaterialStorageControl.xaml | 9 +- .../UI/MaterialStorageControl.xaml.cs | 8 +- .../Nutrition/EntitySystems/OpenableSystem.cs | 7 - Content.Client/Options/UI/Tabs/MiscTab.xaml | 11 +- .../Options/UI/Tabs/MiscTab.xaml.cs | 12 + Content.Client/Paint/PaintVisualizerSystem.cs | 116 --- Content.Client/Pinpointer/UI/NavMapControl.cs | 13 +- Content.Client/Popups/PopupSystem.cs | 7 +- Content.Client/RCD/AlignRCDConstruction.cs | 122 +++ .../RCD/RCDConstructionGhostSystem.cs | 78 ++ Content.Client/RCD/RCDMenu.xaml | 47 ++ Content.Client/RCD/RCDMenu.xaml.cs | 137 ++++ .../RCD/RCDMenuBoundUserInterface.cs | 49 ++ Content.Client/Shuttles/UI/MapScreen.xaml.cs | 12 +- .../Store/Ui/StoreBoundUserInterface.cs | 40 +- Content.Client/Store/Ui/StoreMenu.xaml | 3 +- Content.Client/Store/Ui/StoreMenu.xaml.cs | 25 +- Content.Client/Stylesheets/StyleNano.cs | 76 +- Content.Client/TextScreen/TextScreenSystem.cs | 16 +- Content.Client/Toilet/ToiletVisualsSystem.cs | 25 - .../UserInterface/Controls/RadialContainer.cs | 105 +++ .../UserInterface/Controls/RadialMenu.cs | 255 +++++++ .../Systems/Chat/ChatUIController.cs | 43 +- .../{ChatInputBox.cs => ChatInputBox.xaml.cs} | 4 +- .../Systems/Chat/Widgets/ChatBox.xaml | 7 +- .../Inventory/Controls/ItemStatusPanel.xaml | 4 +- Content.Client/Zombies/ZombieSystem.cs | 2 +- .../Tests/Access/AccessReaderTest.cs | 60 +- .../Access/Systems/AccessOverriderSystem.cs | 42 +- .../Access/Systems/IdCardConsoleSystem.cs | 17 +- .../Administration/Commands/AGhost.cs | 172 +++-- .../Systems/AdminVerbSystem.Tools.cs | 5 +- .../Components/AdvertiseComponent.cs | 6 - .../EntitySystems/AdvertiseSystem.cs | 112 +-- .../Anomaly/AnomalySystem.Scanner.cs | 106 ++- Content.Server/Anomaly/AnomalySystem.cs | 115 ++- .../Components/AnomalousParticleComponent.cs | 24 +- .../Components/SecretDataAnomalyComponent.cs | 45 ++ .../ShuffleParticlesAnomalyComponent.cs | 28 + .../Anomaly/Effects/BluespaceAnomalySystem.cs | 6 +- .../Effects/ElectricityAnomalySystem.cs | 4 +- .../Anomaly/Effects/EntityAnomalySystem.cs | 14 +- .../Anomaly/Effects/InjectionAnomalySystem.cs | 4 +- .../Effects/ProjectileAnomalySystem.cs | 4 +- .../Effects/PuddleCreateAnomalySystem.cs | 3 +- .../Effects/PyroclasticAnomalySystem.cs | 6 +- .../Effects/SecretDataAnomalySystem.cs | 40 + .../Effects/ShuffleParticlesAnomalySystem.cs | 41 + .../Anomaly/Effects/TileAnomalySystem.cs | 14 +- .../EntitySystems/GasTileOverlaySystem.cs | 10 +- .../Trinary/EntitySystems/GasFilterSystem.cs | 2 +- .../BaseSolutionInjectOnEventComponent.cs | 60 ++ .../MeleeChemicalInjectorComponent.cs | 37 +- .../SolutionInjectOnCollideComponent.cs | 28 - .../SolutionInjectOnEmbedComponent.cs | 8 + .../SolutionInjectOnProjectileHitComponent.cs | 8 + .../EntitySystems/ReagentDispenserSystem.cs | 3 +- .../SolutionInjectOnCollideSystem.cs | 49 -- .../SolutionInjectOnEventSystem.cs | 148 ++++ .../EntitySystems/SolutionTransferSystem.cs | 234 ------ .../Conditions/ToiletLidClosed.cs | 39 - .../Thresholds/Behaviors/OpenBehavior.cs | 2 +- .../Components/SignalTimerComponent.cs | 6 + .../Systems/SignalTimerSystem.cs | 23 +- .../Unit/EntitySystems/DisposalUnitSystem.cs | 7 +- .../Systems/DoorElectronicsSystem.cs | 69 ++ .../Extinguisher/FireExtinguisherSystem.cs | 1 + .../EntitySystems/PuddleSystem.Spillable.cs | 15 +- .../GameTicking/GameTicker.RoundFlow.cs | 35 +- .../GameTicking/GameTicker.Spawning.cs | 4 - .../GameTicking/Rules/NukeopsRuleSystem.cs | 4 - Content.Server/Glue/GlueSystem.cs | 2 +- Content.Server/Hands/Systems/HandsSystem.cs | 3 + .../Components/ScramImplantComponent.cs | 6 - .../Implants/SubdermalImplantSystem.cs | 120 ++- Content.Server/Lube/LubeSystem.cs | 2 +- .../Materials/MaterialReclaimerSystem.cs | 4 +- .../NPC/Systems/NPCUtilitySystem.cs | 1 + .../EntitySystems/NodeContainerSystem.cs | 2 +- .../Nutrition/EntitySystems/DrinkSystem.cs | 5 + .../Nutrition/EntitySystems/FoodSystem.cs | 1 + .../Nutrition/EntitySystems/OpenableSystem.cs | 27 - Content.Server/Paint/PaintSystem.cs | 178 ----- .../Paper/PaperRandomStoryComponent.cs | 14 + .../Paper/PaperRandomStorySystem.cs | 29 + Content.Server/Popups/PopupSystem.cs | 2 +- .../Radio/EntitySystems/JammerSystem.cs | 12 +- .../RandomMetadata/RandomMetadataSystem.cs | 6 +- .../Resist/EscapeInventorySystem.cs | 2 +- .../SalvageSystem.ExpeditionConsole.cs | 13 +- .../Salvage/SalvageSystem.Expeditions.cs | 5 +- Content.Server/Salvage/SalvageSystem.cs | 3 + .../Salvage/SpawnSalvageMissionJob.cs | 26 +- Content.Server/Sandbox/SandboxSystem.cs | 3 +- .../Screens/Systems/ScreenSystem.cs | 1 + .../Shuttles/Components/EscapePodComponent.cs | 2 +- .../Components/ShuttleConsoleComponent.cs | 6 + .../Systems/EmergencyShuttleSystem.cs | 2 +- .../Systems/ShuttleConsoleSystem.FTL.cs | 6 +- .../Components/SouthernAccentComponent.cs | 8 + .../EntitySystems/SouthernAccentSystem.cs | 28 + .../Components/SecretStashComponent.cs | 39 - .../EntitySystems/BluespaceLockerSystem.cs | 4 +- .../EntitySystems/SpawnItemsOnUseSystem.cs | 6 +- .../Store/Components/StoreComponent.cs | 7 + .../Store/Systems/StoreSystem.Ui.cs | 4 +- Content.Server/Store/Systems/StoreSystem.cs | 17 + Content.Server/Toilet/ToiletSystem.cs | 197 +---- .../UserInterface/ActivatableUIComponent.cs | 13 +- .../UserInterface/ActivatableUISystem.cs | 11 +- .../Weapons/Melee/MeleeWeaponSystem.cs | 60 +- .../Weapons/Ranged/Systems/GunSystem.cs | 2 +- Content.Server/Wires/WiresComponent.cs | 3 +- Content.Shared/Access/AccessGroupPrototype.cs | 4 +- Content.Shared/Access/AccessLevelPrototype.cs | 8 + .../Access/Components/AccessComponent.cs | 12 +- .../Components/AccessOverriderComponent.cs | 16 +- .../Components/AccessReaderComponent.cs | 20 +- .../Components/IdCardConsoleComponent.cs | 20 +- .../Access/Systems/AccessReaderSystem.cs | 51 +- .../Access/Systems/SharedAccessSystem.cs | 6 +- .../Systems/SharedIdCardConsoleSystem.cs | 14 + .../Anomaly/Components/AnomalyComponent.cs | 48 +- .../Effects/SharedGravityAnomalySystem.cs | 10 +- .../Prototypes/AnomalyBehaviorPrototype.cs | 45 ++ Content.Shared/Anomaly/SharedAnomaly.cs | 1 + Content.Shared/Anomaly/SharedAnomalySystem.cs | 49 +- .../Buckle/Components/StrapComponent.cs | 11 +- .../Buckle/SharedBuckleSystem.Buckle.cs | 4 +- Content.Shared/Burial/BurialSystem.cs | 18 +- Content.Shared/CCVar/CCVars.cs | 7 + .../Charges/Systems/SharedChargesSystem.cs | 22 + .../TypingIndicatorPrototype.cs | 2 +- .../BlockSolutionAccessComponent.cs | 11 + .../Components/HyposprayComponent.cs | 7 + .../Components/ScoopableSolutionComponent.cs | 31 + .../ExaminableSolutionComponent.cs | 6 + .../EntitySystems/ScoopableSolutionSystem.cs | 53 ++ .../EntitySystems/SharedHypospraySystem.cs | 2 +- .../SharedSolutionContainerSystem.cs | 35 + .../EntitySystems/SolutionTransferSystem.cs | 223 ++++++ .../Components/ComputerBoardComponent.cs | 4 +- .../Components/SharedDisposalUnitComponent.cs | 50 +- .../Disposal/SharedDisposalUnitSystem.cs | 19 +- .../Electronics/DoorElectronicsComponent.cs | 42 ++ .../Fluids/SharedPuddleSystem.Spillable.cs | 9 +- .../Hands/Components/HandsComponent.cs | 6 + .../EntitySystems/SharedHandsSystem.Drop.cs | 4 +- Content.Shared/Lock/LockSystem.cs | 71 +- .../Lock/LockedAnchorableComponent.cs | 13 + .../Lock/LockedWiresPanelComponent.cs | 13 + .../Nutrition/Components/OpenableComponent.cs | 2 +- ...redOpenableSystem.cs => OpenableSystem.cs} | 13 +- .../Nutrition/EntitySystems/SealableSystem.cs | 2 +- .../Systems/SharedObjectivesSystem.cs | 5 + Content.Shared/Paint/PaintComponent.cs | 60 -- Content.Shared/Paint/PaintDoAfterEvent.cs | 9 - Content.Shared/Paint/PaintRemoverComponent.cs | 24 - .../Paint/PaintRemoverDoAfterEvent.cs | 9 - Content.Shared/Paint/PaintRemoverSystem.cs | 94 --- Content.Shared/Paint/PaintedComponent.cs | 41 - Content.Shared/Paint/SharedPaintSystem.cs | 11 - .../Plants}/PottedPlantHideComponent.cs | 5 +- .../Plants}/PottedPlantHideSystem.cs | 13 +- .../Plunger/Components/PlungerComponent.cs | 18 + .../Plunger/Components/PlungerUseComponent.cs | 42 ++ Content.Shared/Plunger/PlungerDoAfterEvent.cs | 10 + .../Plunger/Systems/PlungerSystem.cs | 79 ++ Content.Shared/Popups/SharedPopupSystem.cs | 2 +- .../RCD/Components/RCDAmmoComponent.cs | 4 +- Content.Shared/RCD/Components/RCDComponent.cs | 75 +- .../Components/RCDDeconstructibleComponent.cs | 34 + Content.Shared/RCD/RCDEvents.cs | 34 + Content.Shared/RCD/RCDPrototype.cs | 144 ++++ Content.Shared/RCD/Systems/RCDSystem.cs | 708 +++++++++++++----- Content.Shared/Random/RulesPrototype.cs | 4 +- Content.Shared/Roles/JobPrototype.cs | 16 +- .../Salvage/Expeditions/SalvageExpeditions.cs | 7 +- .../Components/FTLDestinationComponent.cs | 6 + .../SharedShuttleConsoleComponent.cs | 2 +- .../ShuttleDestinationCoordinatesComponent.cs | 15 + .../Shuttles/Systems/SharedShuttleSystem.cs | 42 +- .../EmitSoundOnInteractUsingComponent.cs | 15 + Content.Shared/Sound/SharedEmitSoundSystem.cs | 8 + .../SprayPainter/SharedSprayPainterSystem.cs | 3 - .../Components/SecretStashComponent.cs | 90 +++ .../Storage/EntitySystems/DumpableSystem.cs | 4 +- .../EntitySystems/SecretStashSystem.cs | 107 ++- .../Store/ListingLocalisationHelpers.cs | 42 ++ .../Toilet/Components/ToiletComponent.cs | 40 + .../Toilet/Systems/SharedToiletSystem.cs | 109 +++ Content.Shared/Toilet/ToiletComponent.cs | 32 - Content.Shared/Toilet/ToiletVisuals.cs | 10 - .../Weapons/Melee/MeleeSoundSystem.cs | 108 +++ .../Weapons/Melee/SharedMeleeWeaponSystem.cs | 117 +-- Content.Shared/Wires/SharedWiresSystem.cs | 24 +- Content.Shared/Wires/WiresPanelComponent.cs | 6 + .../Audio/Effects/Fluids/attributions.yml | 10 + Resources/Audio/Effects/Fluids/flush.ogg | Bin 0 -> 132202 bytes Resources/Audio/Effects/Fluids/splash.ogg | Bin 0 -> 44679 bytes Resources/Audio/Items/attributions.yml | 10 + Resources/Audio/Items/drill_hit.ogg | Bin 40866 -> 40108 bytes Resources/Audio/Items/drill_use.ogg | Bin 45403 -> 54931 bytes Resources/Audio/Machines/attributions.yml | 9 + Resources/Audio/Machines/buzz-sigh.ogg | Bin 0 -> 8972 bytes Resources/Audio/Machines/buzz-two.ogg | Bin 0 -> 12724 bytes Resources/Audio/Machines/chime.ogg | Bin 0 -> 8240 bytes Resources/Audio/Machines/twobeep.ogg | Bin 0 -> 6851 bytes Resources/Audio/Weapons/glug.ogg | Bin 0 -> 27517 bytes Resources/Changelog/Admin.yml | 8 + Resources/Changelog/Changelog.yml | 538 ++++++------- Resources/Credits/GitHub.txt | 2 +- Resources/Credits/Patrons.yml | 36 +- Resources/Locale/en-US/accent/southern.ftl | 17 + .../en-US/administration/commands/aghost.ftl | 3 + Resources/Locale/en-US/anomaly/anomaly.ftl | 29 + .../components/scoopable-component.ftl | 1 + .../en-US/escape-menu/ui/options-menu.ftl | 2 + .../Locale/en-US/flavors/flavor-profiles.ftl | 7 + .../ghost/roles/ghost-role-component.ftl | 3 + Resources/Locale/en-US/guidebook/guides.ftl | 8 + .../Locale/en-US/job/job-description.ftl | 1 + Resources/Locale/en-US/job/job-names.ftl | 2 + .../Locale/en-US/lock/lock-component.ftl | 3 +- .../en-US/machine-linking/receiver_ports.ftl | 3 + Resources/Locale/en-US/paint/paint.ftl | 8 - .../Locale/en-US/paper/story-generation.ftl | 244 ++++++ .../en-US/rcd/components/rcd-component.ftl | 68 +- .../meta/consumable/drink/alcohol.ftl | 15 + .../reagents/meta/consumable/drink/drinks.ftl | 13 +- .../reagents/meta/consumable/drink/soda.ftl | 9 + Resources/Locale/en-US/shell.ftl | 1 + .../components/secret-stash-component.ftl | 1 + Resources/Locale/en-US/store/store.ftl | 2 + .../Locale/en-US/toilet/toilet-component.ftl | 2 + Resources/Locale/en-US/traits/traits.ftl | 3 + Resources/Locale/en-US/ui/general.ftl | 3 + Resources/Maps/Shuttles/emergency_meta.yml | 2 +- Resources/Maps/reach.yml | 9 +- .../Prototypes/Accents/word_replacements.yml | 9 + Resources/Prototypes/Anomaly/behaviours.yml | 208 +++++ .../Prototypes/Catalog/Cargo/cargo_fun.yml | 10 - .../Catalog/Cargo/cargo_service.yml | 4 +- .../Fills/Backpacks/StarterGear/backpack.yml | 21 + .../Catalog/Fills/Books/bookshelf.yml | 158 ++-- .../Prototypes/Catalog/Fills/Books/lore.yml | 122 --- .../Catalog/Fills/Crates/engineering.yml | 6 +- .../Prototypes/Catalog/Fills/Crates/fun.yml | 48 +- .../Catalog/Fills/Items/briefcases.yml | 6 +- .../Catalog/Fills/Lockers/heads.yml | 6 +- .../Prototypes/Catalog/Fills/Lockers/misc.yml | 6 +- .../Catalog/Fills/Lockers/security.yml | 13 +- .../Catalog/ReagentDispensers/beverage.yml | 2 +- .../VendingMachines/Inventories/boozeomat.yml | 3 + .../VendingMachines/Inventories/cola.yml | 1 + .../VendingMachines/Inventories/curadrobe.yml | 3 +- .../VendingMachines/Inventories/gib.yml | 1 + .../VendingMachines/Inventories/lawdrobe.yml | 1 + .../VendingMachines/Inventories/pwrgame.yml | 1 + .../Inventories/shamblersjuice.yml | 1 + .../VendingMachines/Inventories/soda.yml | 1 + .../VendingMachines/Inventories/spaceup.yml | 1 + .../VendingMachines/Inventories/starkist.yml | 1 + .../VendingMachines/Inventories/theater.yml | 2 +- .../Prototypes/Datasets/story_generation.yml | 266 +++++++ .../Prototypes/DeviceLinking/sink_ports.yml | 5 + .../Entities/Clothing/Back/backpacks.yml | 9 + .../Entities/Clothing/Back/duffel.yml | 3 + .../Entities/Clothing/Eyes/glasses.yml | 8 + .../Clothing/Head/hardsuit-helmets.yml | 15 + .../Entities/Clothing/Head/helmets.yml | 23 - .../Entities/Clothing/Head/misc.yml | 31 +- .../Entities/Clothing/Neck/misc.yml | 14 - .../Entities/Clothing/OuterClothing/armor.yml | 26 - .../Clothing/OuterClothing/hardsuits.yml | 14 + .../Entities/Clothing/Uniforms/jumpsuits.yml | 11 + .../Entities/Effects/chemistry_effects.yml | 10 +- Resources/Prototypes/Entities/Effects/rcd.yml | 107 ++- .../Random/Food_Drinks/drinks_glass.yml | 8 + .../Random/Food_Drinks/drinks_soda.yml | 1 + .../Markers/Spawners/Random/crates.yml | 1 - .../Markers/Spawners/Random/maintenance.yml | 7 +- .../Entities/Markers/Spawners/jobs.yml | 12 + .../Entities/Markers/construction_ghost.yml | 2 +- .../Mobs/Cyborgs/base_borg_chassis.yml | 9 +- .../Prototypes/Entities/Mobs/NPCs/carp.yml | 1 - .../Entities/Mobs/NPCs/revenant.yml | 3 - .../Entities/Mobs/Player/guardian.yml | 2 - .../Entities/Mobs/Player/humanoid.yml | 60 ++ .../Consumable/Drinks/drinks-cartons.yml | 18 + .../Objects/Consumable/Drinks/drinks.yml | 157 ++++ .../Consumable/Drinks/drinks_bottles.yml | 17 + .../Objects/Consumable/Drinks/drinks_cans.yml | 18 + .../Objects/Consumable/Food/produce.yml | 4 + .../Entities/Objects/Decoration/present.yml | 4 +- .../Objects/Devices/Electronics/door.yml | 12 +- .../Devices/Electronics/door_access.yml | 264 +++++++ .../Entities/Objects/Devices/cartridges.yml | 2 +- .../Entities/Objects/Devices/pda.yml | 1 + .../Instruments/instruments_structures.yml | 3 - .../Prototypes/Entities/Objects/Fun/darts.yml | 9 +- .../Entities/Objects/Fun/spray_paint.yml | 292 -------- .../Entities/Objects/Magic/books.yml | 96 ++- .../Objects/Materials/Sheets/glass.yml | 1 - .../Objects/Materials/Sheets/metal.yml | 1 - .../Objects/Materials/Sheets/other.yml | 3 - .../Entities/Objects/Materials/materials.yml | 1 - .../Entities/Objects/Misc/books.yml | 329 +++++--- .../{authorbooks.yml => books_author.yml} | 374 +++++++-- .../Entities/Objects/Misc/briefcases.yml | 23 +- .../Prototypes/Entities/Objects/Misc/cds.yml | 19 + .../Entities/Objects/Misc/diskcases.yml | 21 + .../Entities/Objects/Misc/tiles.yml | 3 - .../Objects/Specific/Janitorial/janitor.yml | 411 +--------- .../Objects/Specific/Janitorial/soap.yml | 1 - .../Entities/Objects/Specific/Mech/mechs.yml | 3 - .../Objects/Specific/Medical/healing.yml | 4 + .../Objects/Specific/Medical/hypospray.yml | 9 + .../Objects/Specific/Medical/morgue.yml | 2 + .../Specific/Robotics/borg_modules.yml | 26 +- .../Entities/Objects/Tools/tools.yml | 71 +- .../Guns/Ammunition/Projectiles/shotgun.yml | 8 +- .../Weapons/Guns/Battery/battery_guns.yml | 5 + .../Weapons/Guns/Projectiles/arrows.yml | 4 +- .../Weapons/Guns/Projectiles/projectiles.yml | 50 ++ .../Objects/Weapons/Melee/e_sword.yml | 4 - .../Entities/Objects/Weapons/Melee/knife.yml | 2 + .../Entities/Objects/Weapons/Melee/spear.yml | 5 +- .../Prototypes/Entities/Stations/base.yml | 2 +- .../Structures/Decoration/bonfire.yml | 3 - .../Dispensers/base_structuredispensers.yml | 1 - .../Entities/Structures/Dispensers/booze.yml | 3 - .../Entities/Structures/Dispensers/chem.yml | 3 - .../Entities/Structures/Dispensers/soda.yml | 3 - .../Structures/Doors/Airlocks/access.yml | 642 +++++++--------- .../Structures/Doors/Airlocks/airlocks.yml | 44 +- .../Doors/Airlocks/base_assembly.yml | 4 + .../Doors/Airlocks/base_structureairlocks.yml | 57 +- .../Structures/Doors/Airlocks/external.yml | 2 +- .../Structures/Doors/Airlocks/highsec.yml | 1 + .../Structures/Doors/Airlocks/shuttle.yml | 2 +- .../Structures/Doors/Firelocks/firelock.yml | 7 +- .../Structures/Doors/Firelocks/frame.yml | 4 + .../Doors/MaterialDoors/material_doors.yml | 4 + .../Doors/SecretDoor/secret_door.yml | 8 + .../Structures/Doors/Shutter/blast_door.yml | 1 + .../Doors/Shutter/blast_door_autolink.yml | 44 ++ .../Structures/Doors/Windoors/assembly.yml | 4 + .../Doors/Windoors/base_structurewindoors.yml | 6 +- .../Entities/Structures/Furniture/toilet.yml | 100 ++- .../Structures/Holographic/projections.yml | 3 - .../Structures/Lighting/base_lighting.yml | 6 +- .../Machines/Computers/computers.yml | 16 + .../Machines/Medical/chemistry_machines.yml | 2 - .../Structures/Machines/anomaly_equipment.yml | 15 +- .../Structures/Machines/artifact_analyzer.yml | 3 - .../Structures/Machines/chem_master.yml | 3 - .../Structures/Machines/cloning_machine.yml | 3 - .../Structures/Machines/fatextractor.yml | 3 - .../Structures/Machines/flatpacker.yml | 3 - .../Structures/Machines/gravity_generator.yml | 3 - .../Entities/Structures/Machines/lathe.yml | 7 - .../Machines/material_reclaimer.yml | 3 - .../Structures/Machines/medical_scanner.yml | 3 - .../Devices => Structures/Machines}/nuke.yml | 4 +- .../Structures/Machines/reagent_grinder.yml | 6 +- .../Entities/Structures/Machines/research.yml | 2 - .../Structures/Machines/telecomms.yml | 3 - .../Structures/Machines/vending_machines.yml | 3 - .../Piping/Atmospherics/portable.yml | 2 +- .../Structures/Piping/Atmospherics/unary.yml | 8 +- .../Structures/Piping/Disposal/units.yml | 20 +- .../Power/Generation/Singularity/emitter.yml | 2 + .../Power/Generation/portable_generator.yml | 12 +- .../Entities/Structures/Power/apc.yml | 3 - .../Structures/Power/cable_terminal.yml | 4 + .../Entities/Structures/Power/cables.yml | 4 + .../Entities/Structures/Power/chargers.yml | 5 - .../Entities/Structures/Power/smes.yml | 3 - .../Entities/Structures/Power/substation.yml | 3 - .../Structures/Specific/Anomaly/anomalies.yml | 16 +- .../Structures/Specific/Janitor/drain.yml | 62 ++ .../Structures/Specific/Janitor/janicart.yml | 324 ++++++++ .../Structures/Storage/Crates/crates.yml | 2 +- .../Storage/Tanks/base_structuretanks.yml | 18 + .../Structures/Storage/Tanks/tanks.yml | 18 +- .../Entities/Structures/Walls/fence_metal.yml | 7 +- .../Entities/Structures/Walls/fence_wood.yml | 5 +- .../Entities/Structures/Walls/grille.yml | 14 +- .../Entities/Structures/Walls/railing.yml | 18 +- .../Entities/Structures/Walls/walls.yml | 58 +- .../Entities/Structures/Windows/mining.yml | 2 +- .../Entities/Structures/Windows/plasma.yml | 4 +- .../Structures/Windows/reinforced.yml | 8 + .../Entities/Structures/Windows/rplasma.yml | 4 +- .../Entities/Structures/Windows/ruranium.yml | 2 +- .../Entities/Structures/Windows/shuttle.yml | 2 +- .../Entities/Structures/Windows/uranium.yml | 2 +- .../Entities/Structures/Windows/window.yml | 25 +- .../Entities/Structures/base_structure.yml | 8 + .../Entities/Structures/catwalk.yml | 4 + .../Entities/Structures/hydro_tray.yml | 6 - .../Entities/Structures/plastic_flaps.yml | 17 +- Resources/Prototypes/Flavors/flavors.yml | 35 + Resources/Prototypes/Guidebook/chemicals.yml | 63 ++ Resources/Prototypes/Guidebook/medical.yml | 2 +- .../Prototypes/Guidebook/shiftandcrew.yml | 7 - .../Prototypes/Objectives/objectiveGroups.yml | 1 - Resources/Prototypes/RCD/rcd.yml | 294 ++++++++ .../Reagents/Consumable/Drink/alcohol.yml | 92 +++ .../Reagents/Consumable/Drink/drinks.yml | 48 ++ .../Reagents/Consumable/Drink/soda.yml | 46 ++ .../Graphs/clothing/glasses_sechud.yml | 25 + .../Construction/Graphs/furniture/toilet.yml | 1 - .../Graphs/structures/airlock.yml | 2 +- .../Graphs/structures/plastic_flaps.yml | 71 ++ .../Graphs/structures/shutter.yml | 2 +- .../Graphs/structures/shuttle.yml | 2 +- .../Graphs/structures/windoor.yml | 4 +- .../Recipes/Construction/clothing.yml | 11 + .../Recipes/Construction/furniture.yml | 2 +- .../Recipes/Construction/structures.yml | 53 +- .../Graphs/improvised/flowercrown.yml | 26 - .../Graphs/improvised/flowerwreath.yml | 2 +- .../Crafting/Graphs/improvised/hairflower.yml | 16 - .../Recipes/Crafting/improvised.yml | 32 +- .../Prototypes/Recipes/Lathes/security.yml | 8 - .../Prototypes/Recipes/Reactions/drinks.yml | 124 +++ Resources/Prototypes/Research/arsenal.yml | 1 - .../Roles/Jobs/Fun/emergencyresponseteam.yml | 55 ++ .../Roles/Jobs/Security/detective.yml | 2 +- .../Roles/Jobs/Security/head_of_security.yml | 2 +- .../Roles/Jobs/Security/security_officer.yml | 2 +- .../Prototypes/Roles/Jobs/Security/warden.yml | 2 +- .../Prototypes/Roles/play_time_trackers.yml | 3 + Resources/Prototypes/Traits/neutral.yml | 7 + .../Prototypes/Voice/speech_emote_sounds.yml | 18 + Resources/Prototypes/Voice/speech_emotes.yml | 104 +++ Resources/Prototypes/tags.yml | 12 +- .../Guidebook/ChemicalTabs/Biological.xml | 9 + .../Guidebook/ChemicalTabs/Botany.xml | 14 + .../Guidebook/ChemicalTabs/Elements.xml | 9 + .../Guidebook/ChemicalTabs/Foods.xml | 8 + .../Guidebook/ChemicalTabs/Narcotics.xml | 5 + .../Guidebook/ChemicalTabs/Other.xml | 5 + .../Guidebook/ChemicalTabs/Pyrotechnic.xml | 5 + .../Guidebook/ChemicalTabs/Toxins.xml | 5 + .../ertchaplain.rsi/equipped-BACKPACK.png | Bin 0 -> 806 bytes .../Back/Backpacks/ertchaplain.rsi/icon.png | Bin 0 -> 553 bytes .../Backpacks/ertchaplain.rsi/inhand-left.png | Bin 0 -> 654 bytes .../ertchaplain.rsi/inhand-right.png | Bin 0 -> 708 bytes .../Backpacks/ertchaplain.rsi}/meta.json | 6 +- .../ERThelmets/ertchaplain.rsi/icon-flash.png | Bin 0 -> 374 bytes .../ERThelmets/ertchaplain.rsi/icon.png | Bin 0 -> 386 bytes .../ERThelmets/ertchaplain.rsi/meta.json | 41 + .../ertchaplain.rsi/off-equipped-HELMET.png | Bin 0 -> 828 bytes .../ertchaplain.rsi/off-inhand-left.png | Bin 0 -> 677 bytes .../ertchaplain.rsi/off-inhand-right.png | Bin 0 -> 707 bytes .../ertchaplain.rsi/on-equipped-HELMET.png | Bin 0 -> 796 bytes .../ertchaplain.rsi/on-inhand-left.png | Bin 0 -> 685 bytes .../ertchaplain.rsi/on-inhand-right.png | Bin 0 -> 706 bytes .../Head/Helmets/scaf.rsi/equipped-HELMET.png | Bin 890 -> 0 bytes .../Clothing/Head/Helmets/scaf.rsi/icon.png | Bin 569 -> 0 bytes .../Head/Helmets/scaf.rsi/inhand-left.png | Bin 753 -> 0 bytes .../Head/Helmets/scaf.rsi/inhand-right.png | Bin 774 -> 0 bytes .../equipped-HELMET.png | Bin .../Misc/flower-wreath.rsi/equipped-NECK.png | Bin .../Misc/flower-wreath.rsi/icon.png | Bin .../meta.json | 6 +- .../Head/Misc/hairflower.rsi/icon.png | Bin 259 -> 0 bytes .../Head/Misc/hairflower.rsi/inhand-left.png | Bin 291 -> 0 bytes .../Head/Misc/hairflower.rsi/inhand-right.png | Bin 266 -> 0 bytes .../Head/Misc/hairflower.rsi/meta.json | 26 - .../Armor/scaf.rsi/equipped-OUTERCLOTHING.png | Bin 1487 -> 0 bytes .../OuterClothing/Armor/scaf.rsi/icon.png | Bin 667 -> 0 bytes .../Armor/scaf.rsi/inhand-left.png | Bin 691 -> 0 bytes .../Armor/scaf.rsi/inhand-right.png | Bin 680 -> 0 bytes .../equipped-OUTERCLOTHING.png | Bin 0 -> 1793 bytes .../ERTSuits/ertchaplain.rsi/icon.png | Bin 0 -> 637 bytes .../ERTSuits/ertchaplain.rsi/inhand-left.png | Bin 0 -> 541 bytes .../ERTSuits/ertchaplain.rsi/inhand-right.png | Bin 0 -> 528 bytes .../ERTSuits/ertchaplain.rsi}/meta.json | 2 +- .../Specific/skates.rsi/equipped-FEET.png | Bin 21114 -> 773 bytes .../Shoes/Specific/skates.rsi/inhand-left.png | Bin 20591 -> 630 bytes .../Specific/skates.rsi/inhand-right.png | Bin 20584 -> 651 bytes .../equipped-INNERCLOTHING-monkey.png | Bin 0 -> 974 bytes .../equipped-INNERCLOTHING.png | Bin 0 -> 1393 bytes .../Jumpsuit/ert_chaplain.rsi/icon.png | Bin 0 -> 421 bytes .../Jumpsuit/ert_chaplain.rsi/inhand-left.png | Bin 0 -> 551 bytes .../ert_chaplain.rsi/inhand-right.png | Bin 0 -> 544 bytes .../Jumpsuit/ert_chaplain.rsi/meta.json | 30 + .../Textures/Effects/rcd.rsi/construct.png | Bin 3612 -> 0 bytes .../Textures/Effects/rcd.rsi/construct0.png | Bin 0 -> 1095 bytes .../Textures/Effects/rcd.rsi/construct1.png | Bin 0 -> 3663 bytes .../Textures/Effects/rcd.rsi/construct2.png | Bin 0 -> 3663 bytes .../Textures/Effects/rcd.rsi/construct3.png | Bin 0 -> 3663 bytes .../Textures/Effects/rcd.rsi/construct4.png | Bin 0 -> 6200 bytes .../Textures/Effects/rcd.rsi/deconstruct2.png | Bin 0 -> 4964 bytes .../Textures/Effects/rcd.rsi/deconstruct4.png | Bin 0 -> 8158 bytes .../Textures/Effects/rcd.rsi/deconstruct6.png | Bin 0 -> 8158 bytes .../Textures/Effects/rcd.rsi/deconstruct8.png | Bin 0 -> 7941 bytes .../Effects/rcd.rsi/deconstructPreview.png | Bin 0 -> 47364 bytes Resources/Textures/Effects/rcd.rsi/meta.json | 411 +++++++++- .../Textures/Interface/Radial/RCD/airlock.png | Bin 0 -> 710 bytes .../Interface/Radial/RCD/airlocks.png | Bin 0 -> 776 bytes .../Interface/Radial/RCD/bulb_light.png | Bin 0 -> 283 bytes .../Interface/Radial/RCD/cable_terminal.png | Bin 0 -> 646 bytes .../Textures/Interface/Radial/RCD/catwalk.png | Bin 0 -> 404 bytes .../Interface/Radial/RCD/computer_frame.png | Bin 0 -> 467 bytes .../Radial/RCD/computers_and_frames.png | Bin 0 -> 775 bytes .../Interface/Radial/RCD/deconstruct.png | Bin 0 -> 1200 bytes .../Interface/Radial/RCD/directional.png | Bin 0 -> 312 bytes .../Radial/RCD/directional_reinforced.png | Bin 0 -> 296 bytes .../Interface/Radial/RCD/firelock.png | Bin 0 -> 637 bytes .../Interface/Radial/RCD/glass_airlock.png | Bin 0 -> 698 bytes .../Textures/Interface/Radial/RCD/grille.png | Bin 0 -> 223 bytes .../Textures/Interface/Radial/RCD/hv_coil.png | Bin 0 -> 856 bytes .../Interface/Radial/RCD/lighting.png | Bin 0 -> 901 bytes .../Textures/Interface/Radial/RCD/lv_coil.png | Bin 0 -> 850 bytes .../Interface/Radial/RCD/machine_frame.png | Bin 0 -> 655 bytes .../Interface/Radial/RCD/metal_tile.png | Bin 0 -> 297 bytes .../Interface/Radial/RCD/multicoil.png | Bin 0 -> 976 bytes .../Textures/Interface/Radial/RCD/mv_coil.png | Bin 0 -> 833 bytes .../Textures/Interface/Radial/RCD/plating.png | Bin 0 -> 436 bytes .../Interface/Radial/RCD/reinforced_wall.png | Bin 0 -> 2312 bytes .../Interface/Radial/RCD/solid_wall.png | Bin 0 -> 448 bytes .../Interface/Radial/RCD/tube_light.png | Bin 0 -> 266 bytes .../Radial/RCD/walls_and_flooring.png | Bin 0 -> 431 bytes .../Textures/Interface/Radial/RCD/window.png | Bin 0 -> 739 bytes .../Radial/RCD/window_reinforced.png | Bin 0 -> 1175 bytes .../Radial/RCD/windows_and_grilles.png | Bin 0 -> 1205 bytes .../Textures/Interface/Radial/back_hover.png | Bin 0 -> 495 bytes .../Textures/Interface/Radial/back_normal.png | Bin 0 -> 525 bytes .../Interface/Radial/button_hover.png | Bin 0 -> 211 bytes .../Interface/Radial/button_normal.png | Bin 0 -> 186 bytes .../Textures/Interface/Radial/close_hover.png | Bin 0 -> 389 bytes .../Interface/Radial/close_normal.png | Bin 0 -> 391 bytes .../Textures/Interface/VerbIcons/paint.svg | 39 - .../VerbIcons/paint.svg.192dpi.png.yml | 2 - .../Drinks/arnoldpalmer.rsi/icon.png | Bin 0 -> 4790 bytes .../Drinks/arnoldpalmer.rsi/meta.json | 14 + .../Drinks/bluehawaiian.rsi/icon.png | Bin 0 -> 4796 bytes .../Drinks/bluehawaiian.rsi/meta.json | 14 + .../Consumable/Drinks/coconutrum.rsi/icon.png | Bin 0 -> 4451 bytes .../Drinks/coconutrum.rsi/meta.json | 14 + .../Drinks/coconutwater.rsi/icon.png | Bin 0 -> 4497 bytes .../Drinks/coconutwater.rsi/icon_open.png | Bin 0 -> 4474 bytes .../Drinks/coconutwater.rsi/meta.json | 17 + .../Drinks/cosmopolitan.rsi/icon.png | Bin 0 -> 4363 bytes .../Drinks/cosmopolitan.rsi/meta.json | 14 + .../Drinks/painkiller.rsi}/icon.png | Bin 5190 -> 4729 bytes .../Drinks/painkiller.rsi/meta.json | 14 + .../Consumable/Drinks/pinacolada.rsi/icon.png | Bin 0 -> 4454 bytes .../Drinks/pinacolada.rsi/meta.json | 14 + .../Consumable/Drinks/royrogers.rsi/icon.png | Bin 0 -> 4915 bytes .../Consumable/Drinks/royrogers.rsi/meta.json | 22 + .../Drinks/shirleytemple.rsi/icon.png | Bin 0 -> 929 bytes .../Drinks/shirleytemple.rsi/meta.json | 14 + .../Consumable/Drinks/sol_dry.rsi/icon.png | Bin 0 -> 4764 bytes .../Drinks/sol_dry.rsi/icon_open.png | Bin 0 -> 4776 bytes .../Drinks/sol_dry.rsi/inhand-left.png | Bin 0 -> 4557 bytes .../Drinks/sol_dry.rsi/inhand-right.png | Bin 0 -> 4565 bytes .../Consumable/Drinks/sol_dry.rsi/meta.json | 53 ++ .../Drinks/sol_dry_glass.rsi/icon.png | Bin 0 -> 4367 bytes .../Drinks/sol_dry_glass.rsi/meta.json | 14 + .../Objects/Fun/spraycans.rsi/meta.json | 19 +- .../Objects/Fun/spraycans.rsi/spray_cap.png | Bin 0 -> 246 bytes .../Magic/spellbooks.rsi/bookfireball.png | Bin 652 -> 0 bytes .../Magic/spellbooks.rsi/bookforcewall.png | Bin 532 -> 0 bytes .../Magic/spellbooks.rsi/bookknock.png | Bin 693 -> 0 bytes .../Objects/Magic/spellbooks.rsi/meta.json | 47 -- .../Magic/spellbooks.rsi/spellbook.png | Bin 743 -> 0 bytes .../Misc/authorbooks.rsi/book_aurora.png | Bin 358 -> 0 bytes .../Misc/authorbooks.rsi/book_cafe.png | Bin 517 -> 0 bytes .../Misc/authorbooks.rsi/book_earth.png | Bin 498 -> 0 bytes .../authorbooks.rsi/book_ian_antarctica.png | Bin 756 -> 0 bytes .../Misc/authorbooks.rsi/book_ian_arctic.png | Bin 531 -> 0 bytes .../Misc/authorbooks.rsi/book_ian_city.png | Bin 538 -> 0 bytes .../Misc/authorbooks.rsi/book_ian_desert.png | Bin 557 -> 0 bytes .../authorbooks.rsi/book_ian_mountain.png | Bin 603 -> 0 bytes .../Misc/authorbooks.rsi/book_ian_ocean.png | Bin 542 -> 0 bytes .../Misc/authorbooks.rsi/book_ian_ranch.png | Bin 530 -> 0 bytes .../Misc/authorbooks.rsi/book_ian_wolfpup.png | Bin 552 -> 0 bytes .../Misc/authorbooks.rsi/book_journ_mount.png | Bin 445 -> 0 bytes .../Objects/Misc/authorbooks.rsi/book_map.png | Bin 379 -> 0 bytes .../Misc/authorbooks.rsi/book_medical.png | Bin 356 -> 0 bytes .../Misc/authorbooks.rsi/book_morgue.png | Bin 630 -> 0 bytes .../Misc/authorbooks.rsi/book_names.png | Bin 317 -> 0 bytes .../authorbooks.rsi/book_narsie_legend.png | Bin 570 -> 0 bytes .../Misc/authorbooks.rsi/book_possum.png | Bin 468 -> 0 bytes .../Misc/authorbooks.rsi/book_rufus.png | Bin 410 -> 0 bytes .../Misc/authorbooks.rsi/book_scmmd.png | Bin 452 -> 0 bytes .../Misc/authorbooks.rsi/book_scpz.png | Bin 438 -> 0 bytes .../Misc/authorbooks.rsi/book_scsss.png | Bin 351 -> 0 bytes .../Misc/authorbooks.rsi/book_struck.png | Bin 480 -> 0 bytes .../Objects/Misc/authorbooks.rsi/book_sun.png | Bin 643 -> 0 bytes .../Misc/authorbooks.rsi/book_temple.png | Bin 553 -> 0 bytes .../Misc/authorbooks.rsi/book_truth.png | Bin 556 -> 0 bytes .../Misc/authorbooks.rsi/book_watched.png | Bin 421 -> 0 bytes .../Misc/authorbooks.rsi/book_world.png | Bin 526 -> 0 bytes .../Objects/Misc/authorbooks.rsi/meta.json | 95 --- .../Textures/Objects/Misc/books.rsi/book0.png | Bin 593 -> 0 bytes .../Textures/Objects/Misc/books.rsi/book1.png | Bin 802 -> 0 bytes .../Textures/Objects/Misc/books.rsi/book2.png | Bin 270 -> 0 bytes .../Textures/Objects/Misc/books.rsi/book3.png | Bin 265 -> 0 bytes .../Textures/Objects/Misc/books.rsi/book4.png | Bin 266 -> 0 bytes .../Textures/Objects/Misc/books.rsi/book5.png | Bin 255 -> 0 bytes .../Textures/Objects/Misc/books.rsi/book6.png | Bin 266 -> 0 bytes .../Textures/Objects/Misc/books.rsi/book7.png | Bin 341 -> 0 bytes .../Textures/Objects/Misc/books.rsi/book8.png | Bin 289 -> 0 bytes .../Objects/Misc/books.rsi/book_bar.png | Bin 371 -> 0 bytes .../Misc/books.rsi/book_boneworking.png | Bin 687 -> 0 bytes .../Objects/Misc/books.rsi/book_borg.png | Bin 515 -> 0 bytes .../Objects/Misc/books.rsi/book_chemistry.png | Bin 360 -> 0 bytes .../Objects/Misc/books.rsi/book_cloning.png | Bin 352 -> 0 bytes .../Objects/Misc/books.rsi/book_cooking.png | Bin 500 -> 0 bytes .../Misc/books.rsi/book_demonomicon.png | Bin 1015 -> 0 bytes .../Objects/Misc/books.rsi/book_detective.png | Bin 396 -> 0 bytes .../Misc/books.rsi/book_engineering.png | Bin 585 -> 0 bytes .../Misc/books.rsi/book_engineering2.png | Bin 672 -> 0 bytes .../Objects/Misc/books.rsi/book_fish.png | Bin 514 -> 0 bytes .../Objects/Misc/books.rsi/book_hacking.png | Bin 487 -> 0 bytes .../books.rsi/book_hydroponics_pod_people.png | Bin 593 -> 0 bytes .../Objects/Misc/books.rsi/book_icon.png | Bin 0 -> 652 bytes .../Misc/books.rsi/book_infections.png | Bin 427 -> 0 bytes .../Objects/Misc/books.rsi/book_medical.png | Bin 361 -> 0 bytes .../Objects/Misc/books.rsi/book_nuclear.png | Bin 809 -> 0 bytes .../Objects/Misc/books.rsi/book_origami.png | Bin 376 -> 0 bytes .../books.rsi/book_particle_accelerator.png | Bin 402 -> 0 bytes .../Objects/Misc/books.rsi/book_science.png | Bin 291 -> 0 bytes .../Objects/Misc/books.rsi/book_security.png | Bin 319 -> 0 bytes .../Objects/Misc/books.rsi/book_space_law.png | Bin 434 -> 0 bytes .../Objects/Misc/books.rsi/cover_base.png | Bin 0 -> 288 bytes .../Objects/Misc/books.rsi/cover_old.png | Bin 0 -> 578 bytes .../Objects/Misc/books.rsi/cover_strong.png | Bin 0 -> 470 bytes .../Objects/Misc/books.rsi/decor_bottom.png | Bin 0 -> 220 bytes .../Objects/Misc/books.rsi/decor_diagonal.png | Bin 0 -> 246 bytes .../Objects/Misc/books.rsi/decor_middle.png | Bin 0 -> 173 bytes .../Objects/Misc/books.rsi/decor_spine.png | Bin 0 -> 195 bytes .../Misc/books.rsi/decor_vertical_middle.png | Bin 0 -> 196 bytes .../Objects/Misc/books.rsi/decor_wingette.png | Bin 0 -> 179 bytes .../Misc/books.rsi/decor_wingette_circle.png | Bin 0 -> 213 bytes .../Misc/books.rsi/decor_wingette_flat.png | Bin 0 -> 138 bytes .../Misc/books.rsi/detail_bookmark.png | Bin 0 -> 169 bytes .../Objects/Misc/books.rsi/detail_rivets.png | Bin 0 -> 142 bytes .../Objects/Misc/books.rsi/icon_apple.png | Bin 0 -> 218 bytes .../Objects/Misc/books.rsi/icon_atmos.png | Bin 0 -> 246 bytes .../Objects/Misc/books.rsi/icon_aurora.png | Bin 0 -> 248 bytes .../Objects/Misc/books.rsi/icon_banana.png | Bin 0 -> 193 bytes .../Objects/Misc/books.rsi/icon_bar.png | Bin 0 -> 218 bytes .../Objects/Misc/books.rsi/icon_biohazard.png | Bin 0 -> 179 bytes .../Objects/Misc/books.rsi/icon_borg.png | Bin 0 -> 293 bytes .../Objects/Misc/books.rsi/icon_briefcase.png | Bin 0 -> 194 bytes .../Objects/Misc/books.rsi/icon_bucket.png | Bin 0 -> 212 bytes .../Objects/Misc/books.rsi/icon_cabbage.png | Bin 0 -> 439 bytes .../Objects/Misc/books.rsi/icon_chemical.png | Bin 0 -> 218 bytes .../Objects/Misc/books.rsi/icon_corner.png | Bin 0 -> 137 bytes .../Objects/Misc/books.rsi/icon_diamond.png | Bin 0 -> 193 bytes .../Objects/Misc/books.rsi/icon_dna.png | Bin 0 -> 163 bytes .../Objects/Misc/books.rsi/icon_eye.png | Bin 0 -> 172 bytes .../Objects/Misc/books.rsi/icon_fish.png | Bin 0 -> 342 bytes .../Objects/Misc/books.rsi/icon_glow.png | Bin 0 -> 230 bytes .../Objects/Misc/books.rsi/icon_hacking.png | Bin 0 -> 306 bytes .../Objects/Misc/books.rsi/icon_ian.png | Bin 0 -> 390 bytes .../Objects/Misc/books.rsi/icon_law.png | Bin 0 -> 240 bytes .../Objects/Misc/books.rsi/icon_letter_N.png | Bin 0 -> 164 bytes .../Objects/Misc/books.rsi/icon_letter_P.png | Bin 0 -> 179 bytes .../Objects/Misc/books.rsi/icon_lightning.png | Bin 0 -> 181 bytes .../Objects/Misc/books.rsi/icon_magic.png | Bin 0 -> 184 bytes .../Misc/books.rsi/icon_magic_fireball.png | Bin 0 -> 342 bytes .../Misc/books.rsi/icon_magic_forcewall.png | Bin 0 -> 334 bytes .../Misc/books.rsi/icon_magic_knock.png | Bin 0 -> 368 bytes .../Objects/Misc/books.rsi/icon_magnifier.png | Bin 0 -> 266 bytes .../Objects/Misc/books.rsi/icon_medical.png | Bin 0 -> 180 bytes .../Misc/books.rsi/icon_medical_cross.png | Bin 0 -> 215 bytes .../Objects/Misc/books.rsi/icon_mount.png | Bin 0 -> 311 bytes .../Objects/Misc/books.rsi/icon_nuclear.png | Bin 0 -> 316 bytes .../Objects/Misc/books.rsi/icon_origami.png | Bin 0 -> 215 bytes .../Misc/books.rsi/icon_pentagramm.png | Bin 0 -> 201 bytes .../Objects/Misc/books.rsi/icon_planet.png | Bin 0 -> 311 bytes .../Objects/Misc/books.rsi/icon_possum.png | Bin 0 -> 337 bytes .../Objects/Misc/books.rsi/icon_question.png | Bin 0 -> 256 bytes .../Objects/Misc/books.rsi/icon_scmmd.png | Bin 0 -> 280 bytes .../Objects/Misc/books.rsi/icon_skull.png | Bin 0 -> 270 bytes .../Objects/Misc/books.rsi/icon_stars.png | Bin 0 -> 181 bytes .../Objects/Misc/books.rsi/icon_stars2.png | Bin 0 -> 160 bytes .../Objects/Misc/books.rsi/icon_stunbaton.png | Bin 0 -> 183 bytes .../Objects/Misc/books.rsi/icon_temple.png | Bin 0 -> 381 bytes .../Objects/Misc/books.rsi/icon_text.png | Bin 0 -> 182 bytes .../Objects/Misc/books.rsi/icon_text2.png | Bin 0 -> 167 bytes .../Objects/Misc/books.rsi/icon_text3.png | Bin 0 -> 160 bytes .../Objects/Misc/books.rsi/icon_time.png | Bin 0 -> 205 bytes .../Objects/Misc/books.rsi/icon_tree.png | Bin 0 -> 417 bytes .../Objects/Misc/books.rsi/icon_wrench.png | Bin 0 -> 473 bytes .../Textures/Objects/Misc/books.rsi/meta.json | 202 ++++- .../Objects/Misc/books.rsi/overlay_blood.png | Bin 0 -> 335 bytes .../Objects/Misc/books.rsi/overlay_dirt.png | Bin 0 -> 608 bytes .../Objects/Misc/books.rsi/overlay_null.png | Bin 0 -> 96 bytes .../Textures/Objects/Misc/books.rsi/paper.png | Bin 0 -> 327 bytes .../Objects/Misc/books.rsi/paper_blood.png | Bin 0 -> 686 bytes .../Textures/Objects/Misc/cd.rsi/icon.png | Bin 0 -> 361 bytes .../Misc/cd.rsi}/meta.json | 7 +- .../Objects/Misc/diskcases.rsi/icon_base.png | Bin 0 -> 240 bytes .../Objects/Misc/diskcases.rsi/icon_cargo.png | Bin 0 -> 234 bytes .../Objects/Misc/diskcases.rsi/icon_cc.png | Bin 0 -> 239 bytes .../Objects/Misc/diskcases.rsi/meta.json | 20 + .../Hydroponics/lily.rsi/equipped-HELMET.png | Bin 0 -> 341 bytes .../Specific/Hydroponics/lily.rsi/meta.json | 6 +- .../poppy.rsi}/equipped-HELMET.png | Bin .../Specific/Hydroponics/poppy.rsi/meta.json | 6 +- .../toilet.rsi/closed_toilet_seat_down.png | Bin 1445 -> 0 bytes .../toilet.rsi/closed_toilet_seat_up.png | Bin 1553 -> 0 bytes .../Furniture/toilet.rsi/condisposal.png | Bin 0 -> 31043 bytes .../toilet.rsi/disposal-charging.png | Bin 0 -> 31052 bytes .../Furniture/toilet.rsi/disposal-closed.png | Bin 0 -> 29675 bytes .../Furniture/toilet.rsi/disposal-down.png | Bin 0 -> 29554 bytes .../Furniture/toilet.rsi/disposal-flush.png | Bin 0 -> 25461 bytes .../Furniture/toilet.rsi/disposal-open.png} | Bin 20783 -> 28502 bytes .../Furniture/toilet.rsi/disposal-up.png | Bin 0 -> 29203 bytes .../Furniture/toilet.rsi/disposal.png | Bin 0 -> 31095 bytes .../Furniture/toilet.rsi/dispover-charge.png} | Bin 21199 -> 28316 bytes .../Furniture/toilet.rsi/dispover-full.png} | Bin 15653 -> 17416 bytes .../Furniture/toilet.rsi/dispover-handle.png} | Bin 20773 -> 17416 bytes .../Furniture/toilet.rsi/dispover-ready.png} | Bin 21213 -> 28318 bytes .../Structures/Furniture/toilet.rsi/meta.json | 238 +++++- .../toilet.rsi/open_toilet_seat_down.png | Bin 1437 -> 0 bytes .../toilet.rsi/open_toilet_seat_up.png | Bin 1535 -> 0 bytes Resources/migration.yml | 30 +- RobustToolbox | 2 +- 745 files changed, 11345 insertions(+), 4987 deletions(-) create mode 100644 Content.Client/Access/UI/AccessLevelControl.xaml create mode 100644 Content.Client/Access/UI/AccessLevelControl.xaml.cs create mode 100644 Content.Client/Doors/Electronics/DoorElectronicsBoundUserInterface.cs create mode 100644 Content.Client/Doors/Electronics/DoorElectronicsConfigurationMenu.xaml create mode 100644 Content.Client/Doors/Electronics/DoorElectronicsConfigurationMenu.xaml.cs delete mode 100644 Content.Client/Nutrition/EntitySystems/OpenableSystem.cs delete mode 100644 Content.Client/Paint/PaintVisualizerSystem.cs create mode 100644 Content.Client/RCD/AlignRCDConstruction.cs create mode 100644 Content.Client/RCD/RCDConstructionGhostSystem.cs create mode 100644 Content.Client/RCD/RCDMenu.xaml create mode 100644 Content.Client/RCD/RCDMenu.xaml.cs create mode 100644 Content.Client/RCD/RCDMenuBoundUserInterface.cs delete mode 100644 Content.Client/Toilet/ToiletVisualsSystem.cs create mode 100644 Content.Client/UserInterface/Controls/RadialContainer.cs create mode 100644 Content.Client/UserInterface/Controls/RadialMenu.cs rename Content.Client/UserInterface/Systems/Chat/Controls/{ChatInputBox.cs => ChatInputBox.xaml.cs} (95%) create mode 100644 Content.Server/Anomaly/Components/SecretDataAnomalyComponent.cs create mode 100644 Content.Server/Anomaly/Components/ShuffleParticlesAnomalyComponent.cs create mode 100644 Content.Server/Anomaly/Effects/SecretDataAnomalySystem.cs create mode 100644 Content.Server/Anomaly/Effects/ShuffleParticlesAnomalySystem.cs create mode 100644 Content.Server/Chemistry/Components/BaseSolutionInjectOnEventComponent.cs delete mode 100644 Content.Server/Chemistry/Components/SolutionInjectOnCollideComponent.cs create mode 100644 Content.Server/Chemistry/Components/SolutionInjectOnEmbedComponent.cs create mode 100644 Content.Server/Chemistry/Components/SolutionInjectOnProjectileHitComponent.cs delete mode 100644 Content.Server/Chemistry/EntitySystems/SolutionInjectOnCollideSystem.cs create mode 100644 Content.Server/Chemistry/EntitySystems/SolutionInjectOnEventSystem.cs delete mode 100644 Content.Server/Chemistry/EntitySystems/SolutionTransferSystem.cs delete mode 100644 Content.Server/Construction/Conditions/ToiletLidClosed.cs create mode 100644 Content.Server/Doors/Electronics/Systems/DoorElectronicsSystem.cs delete mode 100644 Content.Server/Nutrition/EntitySystems/OpenableSystem.cs delete mode 100644 Content.Server/Paint/PaintSystem.cs create mode 100644 Content.Server/Paper/PaperRandomStoryComponent.cs create mode 100644 Content.Server/Paper/PaperRandomStorySystem.cs create mode 100644 Content.Server/Speech/Components/SouthernAccentComponent.cs create mode 100644 Content.Server/Speech/EntitySystems/SouthernAccentSystem.cs delete mode 100644 Content.Server/Storage/Components/SecretStashComponent.cs create mode 100644 Content.Shared/Anomaly/Prototypes/AnomalyBehaviorPrototype.cs create mode 100644 Content.Shared/Chemistry/Components/BlockSolutionAccessComponent.cs create mode 100644 Content.Shared/Chemistry/Components/ScoopableSolutionComponent.cs create mode 100644 Content.Shared/Chemistry/EntitySystems/ScoopableSolutionSystem.cs create mode 100644 Content.Shared/Chemistry/EntitySystems/SolutionTransferSystem.cs create mode 100644 Content.Shared/Doors/Electronics/DoorElectronicsComponent.cs create mode 100644 Content.Shared/Lock/LockedAnchorableComponent.cs create mode 100644 Content.Shared/Lock/LockedWiresPanelComponent.cs rename Content.Shared/Nutrition/EntitySystems/{SharedOpenableSystem.cs => OpenableSystem.cs} (91%) delete mode 100644 Content.Shared/Paint/PaintComponent.cs delete mode 100644 Content.Shared/Paint/PaintDoAfterEvent.cs delete mode 100644 Content.Shared/Paint/PaintRemoverComponent.cs delete mode 100644 Content.Shared/Paint/PaintRemoverDoAfterEvent.cs delete mode 100644 Content.Shared/Paint/PaintRemoverSystem.cs delete mode 100644 Content.Shared/Paint/PaintedComponent.cs delete mode 100644 Content.Shared/Paint/SharedPaintSystem.cs rename {Content.Server/Plants/Components => Content.Shared/Plants}/PottedPlantHideComponent.cs (80%) rename {Content.Server/Plants/Systems => Content.Shared/Plants}/PottedPlantHideSystem.cs (86%) create mode 100644 Content.Shared/Plunger/Components/PlungerComponent.cs create mode 100644 Content.Shared/Plunger/Components/PlungerUseComponent.cs create mode 100644 Content.Shared/Plunger/PlungerDoAfterEvent.cs create mode 100644 Content.Shared/Plunger/Systems/PlungerSystem.cs create mode 100644 Content.Shared/RCD/Components/RCDDeconstructibleComponent.cs create mode 100644 Content.Shared/RCD/RCDEvents.cs create mode 100644 Content.Shared/RCD/RCDPrototype.cs create mode 100644 Content.Shared/Shuttles/Components/ShuttleDestinationCoordinatesComponent.cs create mode 100644 Content.Shared/Sound/Components/EmitSoundOnInteractUsingComponent.cs create mode 100644 Content.Shared/Storage/Components/SecretStashComponent.cs rename {Content.Server => Content.Shared}/Storage/EntitySystems/SecretStashSystem.cs (55%) create mode 100644 Content.Shared/Store/ListingLocalisationHelpers.cs create mode 100644 Content.Shared/Toilet/Components/ToiletComponent.cs create mode 100644 Content.Shared/Toilet/Systems/SharedToiletSystem.cs delete mode 100644 Content.Shared/Toilet/ToiletComponent.cs delete mode 100644 Content.Shared/Toilet/ToiletVisuals.cs create mode 100644 Content.Shared/Weapons/Melee/MeleeSoundSystem.cs create mode 100644 Resources/Audio/Effects/Fluids/flush.ogg create mode 100644 Resources/Audio/Effects/Fluids/splash.ogg create mode 100644 Resources/Audio/Machines/buzz-sigh.ogg create mode 100644 Resources/Audio/Machines/buzz-two.ogg create mode 100644 Resources/Audio/Machines/chime.ogg create mode 100644 Resources/Audio/Machines/twobeep.ogg create mode 100644 Resources/Audio/Weapons/glug.ogg create mode 100644 Resources/Locale/en-US/accent/southern.ftl create mode 100644 Resources/Locale/en-US/administration/commands/aghost.ftl create mode 100644 Resources/Locale/en-US/chemistry/components/scoopable-component.ftl delete mode 100644 Resources/Locale/en-US/paint/paint.ftl create mode 100644 Resources/Locale/en-US/paper/story-generation.ftl create mode 100644 Resources/Locale/en-US/ui/general.ftl create mode 100644 Resources/Prototypes/Anomaly/behaviours.yml delete mode 100644 Resources/Prototypes/Catalog/Fills/Books/lore.yml create mode 100644 Resources/Prototypes/Datasets/story_generation.yml create mode 100644 Resources/Prototypes/Entities/Objects/Devices/Electronics/door_access.yml delete mode 100644 Resources/Prototypes/Entities/Objects/Fun/spray_paint.yml rename Resources/Prototypes/Entities/Objects/Misc/{authorbooks.yml => books_author.yml} (68%) create mode 100644 Resources/Prototypes/Entities/Objects/Misc/cds.yml create mode 100644 Resources/Prototypes/Entities/Objects/Misc/diskcases.yml rename Resources/Prototypes/Entities/{Objects/Devices => Structures/Machines}/nuke.yml (95%) create mode 100644 Resources/Prototypes/Entities/Structures/Specific/Janitor/drain.yml create mode 100644 Resources/Prototypes/Entities/Structures/Specific/Janitor/janicart.yml create mode 100644 Resources/Prototypes/Guidebook/chemicals.yml create mode 100644 Resources/Prototypes/RCD/rcd.yml create mode 100644 Resources/Prototypes/Recipes/Construction/Graphs/clothing/glasses_sechud.yml delete mode 100644 Resources/Prototypes/Recipes/Crafting/Graphs/improvised/flowercrown.yml delete mode 100644 Resources/Prototypes/Recipes/Crafting/Graphs/improvised/hairflower.yml create mode 100644 Resources/ServerInfo/Guidebook/ChemicalTabs/Biological.xml create mode 100644 Resources/ServerInfo/Guidebook/ChemicalTabs/Botany.xml create mode 100644 Resources/ServerInfo/Guidebook/ChemicalTabs/Elements.xml create mode 100644 Resources/ServerInfo/Guidebook/ChemicalTabs/Foods.xml create mode 100644 Resources/ServerInfo/Guidebook/ChemicalTabs/Narcotics.xml create mode 100644 Resources/ServerInfo/Guidebook/ChemicalTabs/Other.xml create mode 100644 Resources/ServerInfo/Guidebook/ChemicalTabs/Pyrotechnic.xml create mode 100644 Resources/ServerInfo/Guidebook/ChemicalTabs/Toxins.xml create mode 100644 Resources/Textures/Clothing/Back/Backpacks/ertchaplain.rsi/equipped-BACKPACK.png create mode 100644 Resources/Textures/Clothing/Back/Backpacks/ertchaplain.rsi/icon.png create mode 100644 Resources/Textures/Clothing/Back/Backpacks/ertchaplain.rsi/inhand-left.png create mode 100644 Resources/Textures/Clothing/Back/Backpacks/ertchaplain.rsi/inhand-right.png rename Resources/Textures/Clothing/{Head/Helmets/scaf.rsi => Back/Backpacks/ertchaplain.rsi}/meta.json (60%) create mode 100644 Resources/Textures/Clothing/Head/Hardsuits/ERThelmets/ertchaplain.rsi/icon-flash.png create mode 100644 Resources/Textures/Clothing/Head/Hardsuits/ERThelmets/ertchaplain.rsi/icon.png create mode 100644 Resources/Textures/Clothing/Head/Hardsuits/ERThelmets/ertchaplain.rsi/meta.json create mode 100644 Resources/Textures/Clothing/Head/Hardsuits/ERThelmets/ertchaplain.rsi/off-equipped-HELMET.png create mode 100644 Resources/Textures/Clothing/Head/Hardsuits/ERThelmets/ertchaplain.rsi/off-inhand-left.png create mode 100644 Resources/Textures/Clothing/Head/Hardsuits/ERThelmets/ertchaplain.rsi/off-inhand-right.png create mode 100644 Resources/Textures/Clothing/Head/Hardsuits/ERThelmets/ertchaplain.rsi/on-equipped-HELMET.png create mode 100644 Resources/Textures/Clothing/Head/Hardsuits/ERThelmets/ertchaplain.rsi/on-inhand-left.png create mode 100644 Resources/Textures/Clothing/Head/Hardsuits/ERThelmets/ertchaplain.rsi/on-inhand-right.png delete mode 100644 Resources/Textures/Clothing/Head/Helmets/scaf.rsi/equipped-HELMET.png delete mode 100644 Resources/Textures/Clothing/Head/Helmets/scaf.rsi/icon.png delete mode 100644 Resources/Textures/Clothing/Head/Helmets/scaf.rsi/inhand-left.png delete mode 100644 Resources/Textures/Clothing/Head/Helmets/scaf.rsi/inhand-right.png rename Resources/Textures/Clothing/Head/Misc/{flower-crown.rsi => flower-wreath.rsi}/equipped-HELMET.png (100%) rename Resources/Textures/Clothing/{Neck => Head}/Misc/flower-wreath.rsi/equipped-NECK.png (100%) rename Resources/Textures/Clothing/{Neck => Head}/Misc/flower-wreath.rsi/icon.png (100%) rename Resources/Textures/Clothing/Head/Misc/{flower-crown.rsi => flower-wreath.rsi}/meta.json (59%) delete mode 100644 Resources/Textures/Clothing/Head/Misc/hairflower.rsi/icon.png delete mode 100644 Resources/Textures/Clothing/Head/Misc/hairflower.rsi/inhand-left.png delete mode 100644 Resources/Textures/Clothing/Head/Misc/hairflower.rsi/inhand-right.png delete mode 100644 Resources/Textures/Clothing/Head/Misc/hairflower.rsi/meta.json delete mode 100644 Resources/Textures/Clothing/OuterClothing/Armor/scaf.rsi/equipped-OUTERCLOTHING.png delete mode 100644 Resources/Textures/Clothing/OuterClothing/Armor/scaf.rsi/icon.png delete mode 100644 Resources/Textures/Clothing/OuterClothing/Armor/scaf.rsi/inhand-left.png delete mode 100644 Resources/Textures/Clothing/OuterClothing/Armor/scaf.rsi/inhand-right.png create mode 100644 Resources/Textures/Clothing/OuterClothing/Hardsuits/ERTSuits/ertchaplain.rsi/equipped-OUTERCLOTHING.png create mode 100644 Resources/Textures/Clothing/OuterClothing/Hardsuits/ERTSuits/ertchaplain.rsi/icon.png create mode 100644 Resources/Textures/Clothing/OuterClothing/Hardsuits/ERTSuits/ertchaplain.rsi/inhand-left.png create mode 100644 Resources/Textures/Clothing/OuterClothing/Hardsuits/ERTSuits/ertchaplain.rsi/inhand-right.png rename Resources/Textures/Clothing/OuterClothing/{Armor/scaf.rsi => Hardsuits/ERTSuits/ertchaplain.rsi}/meta.json (71%) create mode 100644 Resources/Textures/Clothing/Uniforms/Jumpsuit/ert_chaplain.rsi/equipped-INNERCLOTHING-monkey.png create mode 100644 Resources/Textures/Clothing/Uniforms/Jumpsuit/ert_chaplain.rsi/equipped-INNERCLOTHING.png create mode 100644 Resources/Textures/Clothing/Uniforms/Jumpsuit/ert_chaplain.rsi/icon.png create mode 100644 Resources/Textures/Clothing/Uniforms/Jumpsuit/ert_chaplain.rsi/inhand-left.png create mode 100644 Resources/Textures/Clothing/Uniforms/Jumpsuit/ert_chaplain.rsi/inhand-right.png create mode 100644 Resources/Textures/Clothing/Uniforms/Jumpsuit/ert_chaplain.rsi/meta.json delete mode 100644 Resources/Textures/Effects/rcd.rsi/construct.png create mode 100644 Resources/Textures/Effects/rcd.rsi/construct0.png create mode 100644 Resources/Textures/Effects/rcd.rsi/construct1.png create mode 100644 Resources/Textures/Effects/rcd.rsi/construct2.png create mode 100644 Resources/Textures/Effects/rcd.rsi/construct3.png create mode 100644 Resources/Textures/Effects/rcd.rsi/construct4.png create mode 100644 Resources/Textures/Effects/rcd.rsi/deconstruct2.png create mode 100644 Resources/Textures/Effects/rcd.rsi/deconstruct4.png create mode 100644 Resources/Textures/Effects/rcd.rsi/deconstruct6.png create mode 100644 Resources/Textures/Effects/rcd.rsi/deconstruct8.png create mode 100644 Resources/Textures/Effects/rcd.rsi/deconstructPreview.png create mode 100644 Resources/Textures/Interface/Radial/RCD/airlock.png create mode 100644 Resources/Textures/Interface/Radial/RCD/airlocks.png create mode 100644 Resources/Textures/Interface/Radial/RCD/bulb_light.png create mode 100644 Resources/Textures/Interface/Radial/RCD/cable_terminal.png create mode 100644 Resources/Textures/Interface/Radial/RCD/catwalk.png create mode 100644 Resources/Textures/Interface/Radial/RCD/computer_frame.png create mode 100644 Resources/Textures/Interface/Radial/RCD/computers_and_frames.png create mode 100644 Resources/Textures/Interface/Radial/RCD/deconstruct.png create mode 100644 Resources/Textures/Interface/Radial/RCD/directional.png create mode 100644 Resources/Textures/Interface/Radial/RCD/directional_reinforced.png create mode 100644 Resources/Textures/Interface/Radial/RCD/firelock.png create mode 100644 Resources/Textures/Interface/Radial/RCD/glass_airlock.png create mode 100644 Resources/Textures/Interface/Radial/RCD/grille.png create mode 100644 Resources/Textures/Interface/Radial/RCD/hv_coil.png create mode 100644 Resources/Textures/Interface/Radial/RCD/lighting.png create mode 100644 Resources/Textures/Interface/Radial/RCD/lv_coil.png create mode 100644 Resources/Textures/Interface/Radial/RCD/machine_frame.png create mode 100644 Resources/Textures/Interface/Radial/RCD/metal_tile.png create mode 100644 Resources/Textures/Interface/Radial/RCD/multicoil.png create mode 100644 Resources/Textures/Interface/Radial/RCD/mv_coil.png create mode 100644 Resources/Textures/Interface/Radial/RCD/plating.png create mode 100644 Resources/Textures/Interface/Radial/RCD/reinforced_wall.png create mode 100644 Resources/Textures/Interface/Radial/RCD/solid_wall.png create mode 100644 Resources/Textures/Interface/Radial/RCD/tube_light.png create mode 100644 Resources/Textures/Interface/Radial/RCD/walls_and_flooring.png create mode 100644 Resources/Textures/Interface/Radial/RCD/window.png create mode 100644 Resources/Textures/Interface/Radial/RCD/window_reinforced.png create mode 100644 Resources/Textures/Interface/Radial/RCD/windows_and_grilles.png create mode 100644 Resources/Textures/Interface/Radial/back_hover.png create mode 100644 Resources/Textures/Interface/Radial/back_normal.png create mode 100644 Resources/Textures/Interface/Radial/button_hover.png create mode 100644 Resources/Textures/Interface/Radial/button_normal.png create mode 100644 Resources/Textures/Interface/Radial/close_hover.png create mode 100644 Resources/Textures/Interface/Radial/close_normal.png delete mode 100644 Resources/Textures/Interface/VerbIcons/paint.svg delete mode 100644 Resources/Textures/Interface/VerbIcons/paint.svg.192dpi.png.yml create mode 100644 Resources/Textures/Objects/Consumable/Drinks/arnoldpalmer.rsi/icon.png create mode 100644 Resources/Textures/Objects/Consumable/Drinks/arnoldpalmer.rsi/meta.json create mode 100644 Resources/Textures/Objects/Consumable/Drinks/bluehawaiian.rsi/icon.png create mode 100644 Resources/Textures/Objects/Consumable/Drinks/bluehawaiian.rsi/meta.json create mode 100644 Resources/Textures/Objects/Consumable/Drinks/coconutrum.rsi/icon.png create mode 100644 Resources/Textures/Objects/Consumable/Drinks/coconutrum.rsi/meta.json create mode 100644 Resources/Textures/Objects/Consumable/Drinks/coconutwater.rsi/icon.png create mode 100644 Resources/Textures/Objects/Consumable/Drinks/coconutwater.rsi/icon_open.png create mode 100644 Resources/Textures/Objects/Consumable/Drinks/coconutwater.rsi/meta.json create mode 100644 Resources/Textures/Objects/Consumable/Drinks/cosmopolitan.rsi/icon.png create mode 100644 Resources/Textures/Objects/Consumable/Drinks/cosmopolitan.rsi/meta.json rename Resources/Textures/{Clothing/Head/Misc/flower-crown.rsi => Objects/Consumable/Drinks/painkiller.rsi}/icon.png (53%) create mode 100644 Resources/Textures/Objects/Consumable/Drinks/painkiller.rsi/meta.json create mode 100644 Resources/Textures/Objects/Consumable/Drinks/pinacolada.rsi/icon.png create mode 100644 Resources/Textures/Objects/Consumable/Drinks/pinacolada.rsi/meta.json create mode 100644 Resources/Textures/Objects/Consumable/Drinks/royrogers.rsi/icon.png create mode 100644 Resources/Textures/Objects/Consumable/Drinks/royrogers.rsi/meta.json create mode 100644 Resources/Textures/Objects/Consumable/Drinks/shirleytemple.rsi/icon.png create mode 100644 Resources/Textures/Objects/Consumable/Drinks/shirleytemple.rsi/meta.json create mode 100644 Resources/Textures/Objects/Consumable/Drinks/sol_dry.rsi/icon.png create mode 100644 Resources/Textures/Objects/Consumable/Drinks/sol_dry.rsi/icon_open.png create mode 100644 Resources/Textures/Objects/Consumable/Drinks/sol_dry.rsi/inhand-left.png create mode 100644 Resources/Textures/Objects/Consumable/Drinks/sol_dry.rsi/inhand-right.png create mode 100644 Resources/Textures/Objects/Consumable/Drinks/sol_dry.rsi/meta.json create mode 100644 Resources/Textures/Objects/Consumable/Drinks/sol_dry_glass.rsi/icon.png create mode 100644 Resources/Textures/Objects/Consumable/Drinks/sol_dry_glass.rsi/meta.json create mode 100644 Resources/Textures/Objects/Fun/spraycans.rsi/spray_cap.png delete mode 100644 Resources/Textures/Objects/Magic/spellbooks.rsi/bookfireball.png delete mode 100644 Resources/Textures/Objects/Magic/spellbooks.rsi/bookforcewall.png delete mode 100644 Resources/Textures/Objects/Magic/spellbooks.rsi/bookknock.png delete mode 100644 Resources/Textures/Objects/Magic/spellbooks.rsi/meta.json delete mode 100644 Resources/Textures/Objects/Magic/spellbooks.rsi/spellbook.png delete mode 100644 Resources/Textures/Objects/Misc/authorbooks.rsi/book_aurora.png delete mode 100644 Resources/Textures/Objects/Misc/authorbooks.rsi/book_cafe.png delete mode 100644 Resources/Textures/Objects/Misc/authorbooks.rsi/book_earth.png delete mode 100644 Resources/Textures/Objects/Misc/authorbooks.rsi/book_ian_antarctica.png delete mode 100644 Resources/Textures/Objects/Misc/authorbooks.rsi/book_ian_arctic.png delete mode 100644 Resources/Textures/Objects/Misc/authorbooks.rsi/book_ian_city.png delete mode 100644 Resources/Textures/Objects/Misc/authorbooks.rsi/book_ian_desert.png delete mode 100644 Resources/Textures/Objects/Misc/authorbooks.rsi/book_ian_mountain.png delete mode 100644 Resources/Textures/Objects/Misc/authorbooks.rsi/book_ian_ocean.png delete mode 100644 Resources/Textures/Objects/Misc/authorbooks.rsi/book_ian_ranch.png delete mode 100644 Resources/Textures/Objects/Misc/authorbooks.rsi/book_ian_wolfpup.png delete mode 100644 Resources/Textures/Objects/Misc/authorbooks.rsi/book_journ_mount.png delete mode 100644 Resources/Textures/Objects/Misc/authorbooks.rsi/book_map.png delete mode 100644 Resources/Textures/Objects/Misc/authorbooks.rsi/book_medical.png delete mode 100644 Resources/Textures/Objects/Misc/authorbooks.rsi/book_morgue.png delete mode 100644 Resources/Textures/Objects/Misc/authorbooks.rsi/book_names.png delete mode 100644 Resources/Textures/Objects/Misc/authorbooks.rsi/book_narsie_legend.png delete mode 100644 Resources/Textures/Objects/Misc/authorbooks.rsi/book_possum.png delete mode 100644 Resources/Textures/Objects/Misc/authorbooks.rsi/book_rufus.png delete mode 100644 Resources/Textures/Objects/Misc/authorbooks.rsi/book_scmmd.png delete mode 100644 Resources/Textures/Objects/Misc/authorbooks.rsi/book_scpz.png delete mode 100644 Resources/Textures/Objects/Misc/authorbooks.rsi/book_scsss.png delete mode 100644 Resources/Textures/Objects/Misc/authorbooks.rsi/book_struck.png delete mode 100644 Resources/Textures/Objects/Misc/authorbooks.rsi/book_sun.png delete mode 100644 Resources/Textures/Objects/Misc/authorbooks.rsi/book_temple.png delete mode 100644 Resources/Textures/Objects/Misc/authorbooks.rsi/book_truth.png delete mode 100644 Resources/Textures/Objects/Misc/authorbooks.rsi/book_watched.png delete mode 100644 Resources/Textures/Objects/Misc/authorbooks.rsi/book_world.png delete mode 100644 Resources/Textures/Objects/Misc/authorbooks.rsi/meta.json delete mode 100644 Resources/Textures/Objects/Misc/books.rsi/book0.png delete mode 100644 Resources/Textures/Objects/Misc/books.rsi/book1.png delete mode 100644 Resources/Textures/Objects/Misc/books.rsi/book2.png delete mode 100644 Resources/Textures/Objects/Misc/books.rsi/book3.png delete mode 100644 Resources/Textures/Objects/Misc/books.rsi/book4.png delete mode 100644 Resources/Textures/Objects/Misc/books.rsi/book5.png delete mode 100644 Resources/Textures/Objects/Misc/books.rsi/book6.png delete mode 100644 Resources/Textures/Objects/Misc/books.rsi/book7.png delete mode 100644 Resources/Textures/Objects/Misc/books.rsi/book8.png delete mode 100644 Resources/Textures/Objects/Misc/books.rsi/book_bar.png delete mode 100644 Resources/Textures/Objects/Misc/books.rsi/book_boneworking.png delete mode 100644 Resources/Textures/Objects/Misc/books.rsi/book_borg.png delete mode 100644 Resources/Textures/Objects/Misc/books.rsi/book_chemistry.png delete mode 100644 Resources/Textures/Objects/Misc/books.rsi/book_cloning.png delete mode 100644 Resources/Textures/Objects/Misc/books.rsi/book_cooking.png delete mode 100644 Resources/Textures/Objects/Misc/books.rsi/book_demonomicon.png delete mode 100644 Resources/Textures/Objects/Misc/books.rsi/book_detective.png delete mode 100644 Resources/Textures/Objects/Misc/books.rsi/book_engineering.png delete mode 100644 Resources/Textures/Objects/Misc/books.rsi/book_engineering2.png delete mode 100644 Resources/Textures/Objects/Misc/books.rsi/book_fish.png delete mode 100644 Resources/Textures/Objects/Misc/books.rsi/book_hacking.png delete mode 100644 Resources/Textures/Objects/Misc/books.rsi/book_hydroponics_pod_people.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/book_icon.png delete mode 100644 Resources/Textures/Objects/Misc/books.rsi/book_infections.png delete mode 100644 Resources/Textures/Objects/Misc/books.rsi/book_medical.png delete mode 100644 Resources/Textures/Objects/Misc/books.rsi/book_nuclear.png delete mode 100644 Resources/Textures/Objects/Misc/books.rsi/book_origami.png delete mode 100644 Resources/Textures/Objects/Misc/books.rsi/book_particle_accelerator.png delete mode 100644 Resources/Textures/Objects/Misc/books.rsi/book_science.png delete mode 100644 Resources/Textures/Objects/Misc/books.rsi/book_security.png delete mode 100644 Resources/Textures/Objects/Misc/books.rsi/book_space_law.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/cover_base.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/cover_old.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/cover_strong.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/decor_bottom.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/decor_diagonal.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/decor_middle.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/decor_spine.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/decor_vertical_middle.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/decor_wingette.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/decor_wingette_circle.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/decor_wingette_flat.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/detail_bookmark.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/detail_rivets.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_apple.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_atmos.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_aurora.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_banana.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_bar.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_biohazard.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_borg.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_briefcase.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_bucket.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_cabbage.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_chemical.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_corner.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_diamond.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_dna.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_eye.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_fish.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_glow.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_hacking.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_ian.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_law.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_letter_N.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_letter_P.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_lightning.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_magic.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_magic_fireball.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_magic_forcewall.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_magic_knock.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_magnifier.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_medical.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_medical_cross.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_mount.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_nuclear.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_origami.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_pentagramm.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_planet.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_possum.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_question.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_scmmd.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_skull.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_stars.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_stars2.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_stunbaton.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_temple.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_text.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_text2.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_text3.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_time.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_tree.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/icon_wrench.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/overlay_blood.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/overlay_dirt.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/overlay_null.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/paper.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/paper_blood.png create mode 100644 Resources/Textures/Objects/Misc/cd.rsi/icon.png rename Resources/Textures/{Clothing/Neck/Misc/flower-wreath.rsi => Objects/Misc/cd.rsi}/meta.json (58%) create mode 100644 Resources/Textures/Objects/Misc/diskcases.rsi/icon_base.png create mode 100644 Resources/Textures/Objects/Misc/diskcases.rsi/icon_cargo.png create mode 100644 Resources/Textures/Objects/Misc/diskcases.rsi/icon_cc.png create mode 100644 Resources/Textures/Objects/Misc/diskcases.rsi/meta.json create mode 100644 Resources/Textures/Objects/Specific/Hydroponics/lily.rsi/equipped-HELMET.png rename Resources/Textures/{Clothing/Head/Misc/hairflower.rsi => Objects/Specific/Hydroponics/poppy.rsi}/equipped-HELMET.png (100%) delete mode 100644 Resources/Textures/Structures/Furniture/toilet.rsi/closed_toilet_seat_down.png delete mode 100644 Resources/Textures/Structures/Furniture/toilet.rsi/closed_toilet_seat_up.png create mode 100644 Resources/Textures/Structures/Furniture/toilet.rsi/condisposal.png create mode 100644 Resources/Textures/Structures/Furniture/toilet.rsi/disposal-charging.png create mode 100644 Resources/Textures/Structures/Furniture/toilet.rsi/disposal-closed.png create mode 100644 Resources/Textures/Structures/Furniture/toilet.rsi/disposal-down.png create mode 100644 Resources/Textures/Structures/Furniture/toilet.rsi/disposal-flush.png rename Resources/Textures/{Objects/Fun/spraycans.rsi/clown-inhand-right.png => Structures/Furniture/toilet.rsi/disposal-open.png} (64%) create mode 100644 Resources/Textures/Structures/Furniture/toilet.rsi/disposal-up.png create mode 100644 Resources/Textures/Structures/Furniture/toilet.rsi/disposal.png rename Resources/Textures/{Objects/Fun/spraycans.rsi/spray-inhand-left.png => Structures/Furniture/toilet.rsi/dispover-charge.png} (66%) rename Resources/Textures/{Interface/VerbIcons/paint.svg.192dpi.png => Structures/Furniture/toilet.rsi/dispover-full.png} (79%) rename Resources/Textures/{Objects/Fun/spraycans.rsi/clown-inhand-left.png => Structures/Furniture/toilet.rsi/dispover-handle.png} (74%) rename Resources/Textures/{Objects/Fun/spraycans.rsi/spray-inhand-right.png => Structures/Furniture/toilet.rsi/dispover-ready.png} (66%) delete mode 100644 Resources/Textures/Structures/Furniture/toilet.rsi/open_toilet_seat_down.png delete mode 100644 Resources/Textures/Structures/Furniture/toilet.rsi/open_toilet_seat_up.png diff --git a/Content.Client/Access/UI/AccessLevelControl.xaml b/Content.Client/Access/UI/AccessLevelControl.xaml new file mode 100644 index 0000000000..56968d8983 --- /dev/null +++ b/Content.Client/Access/UI/AccessLevelControl.xaml @@ -0,0 +1,4 @@ + + diff --git a/Content.Client/Access/UI/AccessLevelControl.xaml.cs b/Content.Client/Access/UI/AccessLevelControl.xaml.cs new file mode 100644 index 0000000000..34db80b7af --- /dev/null +++ b/Content.Client/Access/UI/AccessLevelControl.xaml.cs @@ -0,0 +1,52 @@ +using System.Linq; +using Robust.Client.AutoGenerated; +using Robust.Client.UserInterface; +using Robust.Client.UserInterface.Controls; +using Robust.Client.UserInterface.XAML; +using Robust.Shared.Prototypes; +using Content.Shared.Access; +using Content.Shared.Access.Systems; + +namespace Content.Client.Access.UI; + +[GenerateTypedNameReferences] +public sealed partial class AccessLevelControl : GridContainer +{ + public readonly Dictionary, Button> ButtonsList = new(); + + public AccessLevelControl() + { + RobustXamlLoader.Load(this); + } + + public void Populate(List> accessLevels, IPrototypeManager prototypeManager) + { + foreach (var access in accessLevels) + { + if (!prototypeManager.TryIndex(access, out var accessLevel)) + { + Logger.Error($"Unable to find accesslevel for {access}"); + continue; + } + + var newButton = new Button + { + Text = accessLevel.GetAccessLevelName(), + ToggleMode = true, + }; + AddChild(newButton); + ButtonsList.Add(accessLevel.ID, newButton); + } + } + + public void UpdateState( + List> pressedList, + List>? enabledList = null) + { + foreach (var (accessName, button) in ButtonsList) + { + button.Pressed = pressedList.Contains(accessName); + button.Disabled = !(enabledList?.Contains(accessName) ?? true); + } + } +} diff --git a/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs b/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs index 0c23542f79..c1b63dc4d0 100644 --- a/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs +++ b/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs @@ -64,7 +64,7 @@ namespace Content.Client.Access.UI _window?.UpdateState(castState); } - public void SubmitData(List newAccessList) + public void SubmitData(List> newAccessList) { SendMessage(new WriteToTargetAccessReaderIdMessage(newAccessList)); } diff --git a/Content.Client/Access/UI/AccessOverriderWindow.xaml.cs b/Content.Client/Access/UI/AccessOverriderWindow.xaml.cs index 2fd0057121..6025c3b551 100644 --- a/Content.Client/Access/UI/AccessOverriderWindow.xaml.cs +++ b/Content.Client/Access/UI/AccessOverriderWindow.xaml.cs @@ -16,7 +16,6 @@ namespace Content.Client.Access.UI [Dependency] private readonly ILogManager _logManager = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - private readonly ISawmill _logMill = default!; private readonly AccessOverriderBoundUserInterface _owner; private readonly Dictionary _accessButtons = new(); @@ -25,7 +24,7 @@ namespace Content.Client.Access.UI { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); - _logMill = _logManager.GetSawmill(SharedAccessOverriderSystem.Sawmill); + var logMill = _logManager.GetSawmill(SharedAccessOverriderSystem.Sawmill); _owner = owner; @@ -33,13 +32,13 @@ namespace Content.Client.Access.UI { if (!prototypeManager.TryIndex(access, out var accessLevel)) { - _logMill.Error($"Unable to find accesslevel for {access}"); + logMill.Error($"Unable to find accesslevel for {access}"); continue; } var newButton = new Button { - Text = GetAccessLevelName(accessLevel), + Text = accessLevel.GetAccessLevelName(), ToggleMode = true, }; @@ -49,14 +48,6 @@ namespace Content.Client.Access.UI } } - private static string GetAccessLevelName(AccessLevelPrototype prototype) - { - if (prototype.Name is { } name) - return Loc.GetString(name); - - return prototype.ID; - } - public void UpdateState(AccessOverriderBoundUserInterfaceState state) { PrivilegedIdLabel.Text = state.PrivilegedIdName; @@ -105,7 +96,7 @@ namespace Content.Client.Access.UI _owner.SubmitData( // Iterate over the buttons dictionary, filter by `Pressed`, only get key from the key/value pair - _accessButtons.Where(x => x.Value.Pressed).Select(x => x.Key).ToList()); + _accessButtons.Where(x => x.Value.Pressed).Select(x => new ProtoId(x.Key)).ToList()); } } } diff --git a/Content.Client/Access/UI/IdCardConsoleBoundUserInterface.cs b/Content.Client/Access/UI/IdCardConsoleBoundUserInterface.cs index 898792aa03..5b7011c195 100644 --- a/Content.Client/Access/UI/IdCardConsoleBoundUserInterface.cs +++ b/Content.Client/Access/UI/IdCardConsoleBoundUserInterface.cs @@ -1,5 +1,6 @@ using Content.Shared.Access; using Content.Shared.Access.Components; +using Content.Shared.Access; using Content.Shared.Access.Systems; using Content.Shared.Containers.ItemSlots; using Content.Shared.CrewManifest; @@ -28,7 +29,6 @@ namespace Content.Client.Access.UI if (EntMan.TryGetComponent(Owner, out var idCard)) { accessLevels = idCard.AccessLevels; - accessLevels.Sort(); } else { @@ -65,7 +65,7 @@ namespace Content.Client.Access.UI _window?.UpdateState(castState); } - public void SubmitData(string newFullName, string newJobTitle, List newAccessList, string newJobPrototype) + public void SubmitData(string newFullName, string newJobTitle, List> newAccessList, string newJobPrototype) { if (newFullName.Length > MaxFullNameLength) newFullName = newFullName[..MaxFullNameLength]; diff --git a/Content.Client/Access/UI/IdCardConsoleWindow.xaml b/Content.Client/Access/UI/IdCardConsoleWindow.xaml index c29adc8ebd..a2f5f3382b 100644 --- a/Content.Client/Access/UI/IdCardConsoleWindow.xaml +++ b/Content.Client/Access/UI/IdCardConsoleWindow.xaml @@ -30,10 +30,6 @@ [GenerateTypedNameReferences] -public sealed partial class MaterialStorageControl : BoxContainer +public sealed partial class MaterialStorageControl : ScrollContainer { [Dependency] private readonly IEntityManager _entityManager = default!; @@ -63,7 +63,7 @@ public sealed partial class MaterialStorageControl : BoxContainer } var children = new List(); - children.AddRange(Children.OfType()); + children.AddRange(MaterialList.Children.OfType()); foreach (var display in children) { @@ -71,7 +71,7 @@ public sealed partial class MaterialStorageControl : BoxContainer if (extra.Contains(mat)) { - RemoveChild(display); + MaterialList.RemoveChild(display); continue; } @@ -83,7 +83,7 @@ public sealed partial class MaterialStorageControl : BoxContainer foreach (var mat in missing) { var volume = mats[mat]; - AddChild(new MaterialDisplay(_owner.Value, mat, volume, canEject)); + MaterialList.AddChild(new MaterialDisplay(_owner.Value, mat, volume, canEject)); } _currentMaterials = mats; diff --git a/Content.Client/Nutrition/EntitySystems/OpenableSystem.cs b/Content.Client/Nutrition/EntitySystems/OpenableSystem.cs deleted file mode 100644 index f8c3f7c447..0000000000 --- a/Content.Client/Nutrition/EntitySystems/OpenableSystem.cs +++ /dev/null @@ -1,7 +0,0 @@ -using Content.Shared.Nutrition.EntitySystems; - -namespace Content.Client.Nutrition.EntitySystems; - -public sealed class OpenableSystem : SharedOpenableSystem -{ -} diff --git a/Content.Client/Options/UI/Tabs/MiscTab.xaml b/Content.Client/Options/UI/Tabs/MiscTab.xaml index 2ee59910f7..5564d7b226 100644 --- a/Content.Client/Options/UI/Tabs/MiscTab.xaml +++ b/Content.Client/Options/UI/Tabs/MiscTab.xaml @@ -25,6 +25,14 @@ + + - - - diff --git a/Content.Client/Options/UI/Tabs/MiscTab.xaml.cs b/Content.Client/Options/UI/Tabs/MiscTab.xaml.cs index 3b9c41efdf..476e7289ea 100644 --- a/Content.Client/Options/UI/Tabs/MiscTab.xaml.cs +++ b/Content.Client/Options/UI/Tabs/MiscTab.xaml.cs @@ -66,6 +66,7 @@ namespace Content.Client.Options.UI.Tabs EnableColorNameCheckBox.OnToggled += OnCheckBoxToggled; ColorblindFriendlyCheckBox.OnToggled += OnCheckBoxToggled; ReducedMotionCheckBox.OnToggled += OnCheckBoxToggled; + ChatWindowOpacitySlider.OnValueChanged += OnChatWindowOpacitySliderChanged; ScreenShakeIntensitySlider.OnValueChanged += OnScreenShakeIntensitySliderChanged; // ToggleWalk.OnToggled += OnCheckBoxToggled; StaticStorageUI.OnToggled += OnCheckBoxToggled; @@ -81,6 +82,7 @@ namespace Content.Client.Options.UI.Tabs EnableColorNameCheckBox.Pressed = _cfg.GetCVar(CCVars.ChatEnableColorName); ColorblindFriendlyCheckBox.Pressed = _cfg.GetCVar(CCVars.AccessibilityColorblindFriendly); ReducedMotionCheckBox.Pressed = _cfg.GetCVar(CCVars.ReducedMotion); + ChatWindowOpacitySlider.Value = _cfg.GetCVar(CCVars.ChatWindowOpacity); ScreenShakeIntensitySlider.Value = _cfg.GetCVar(CCVars.ScreenShakeIntensity) * 100f; // ToggleWalk.Pressed = _cfg.GetCVar(CCVars.ToggleWalk); StaticStorageUI.Pressed = _cfg.GetCVar(CCVars.StaticStorageUI); @@ -101,6 +103,13 @@ namespace Content.Client.Options.UI.Tabs UpdateApplyButton(); } + private void OnChatWindowOpacitySliderChanged(Range range) + { + ChatWindowOpacityLabel.Text = Loc.GetString("ui-options-chat-window-opacity-percent", + ("opacity", range.Value)); + UpdateApplyButton(); + } + private void OnScreenShakeIntensitySliderChanged(Range obj) { ScreenShakeIntensityLabel.Text = Loc.GetString("ui-options-screen-shake-percent", ("intensity", ScreenShakeIntensitySlider.Value / 100f)); @@ -127,6 +136,7 @@ namespace Content.Client.Options.UI.Tabs _cfg.SetCVar(CCVars.ChatEnableColorName, EnableColorNameCheckBox.Pressed); _cfg.SetCVar(CCVars.AccessibilityColorblindFriendly, ColorblindFriendlyCheckBox.Pressed); _cfg.SetCVar(CCVars.ReducedMotion, ReducedMotionCheckBox.Pressed); + _cfg.SetCVar(CCVars.ChatWindowOpacity, ChatWindowOpacitySlider.Value); _cfg.SetCVar(CCVars.ScreenShakeIntensity, ScreenShakeIntensitySlider.Value / 100f); // _cfg.SetCVar(CCVars.ToggleWalk, ToggleWalk.Pressed); _cfg.SetCVar(CCVars.StaticStorageUI, StaticStorageUI.Pressed); @@ -154,6 +164,7 @@ namespace Content.Client.Options.UI.Tabs var isEnableColorNameSame = EnableColorNameCheckBox.Pressed == _cfg.GetCVar(CCVars.ChatEnableColorName); var isColorblindFriendly = ColorblindFriendlyCheckBox.Pressed == _cfg.GetCVar(CCVars.AccessibilityColorblindFriendly); var isReducedMotionSame = ReducedMotionCheckBox.Pressed == _cfg.GetCVar(CCVars.ReducedMotion); + var isChatWindowOpacitySame = Math.Abs(ChatWindowOpacitySlider.Value - _cfg.GetCVar(CCVars.ChatWindowOpacity)) < 0.01f; var isScreenShakeIntensitySame = Math.Abs(ScreenShakeIntensitySlider.Value / 100f - _cfg.GetCVar(CCVars.ScreenShakeIntensity)) < 0.01f; // var isToggleWalkSame = ToggleWalk.Pressed == _cfg.GetCVar(CCVars.ToggleWalk); var isStaticStorageUISame = StaticStorageUI.Pressed == _cfg.GetCVar(CCVars.StaticStorageUI); @@ -170,6 +181,7 @@ namespace Content.Client.Options.UI.Tabs isEnableColorNameSame && isColorblindFriendly && isReducedMotionSame && + isChatWindowOpacitySame && isScreenShakeIntensitySame && // isToggleWalkSame && isStaticStorageUISame; diff --git a/Content.Client/Paint/PaintVisualizerSystem.cs b/Content.Client/Paint/PaintVisualizerSystem.cs deleted file mode 100644 index 8d037811fa..0000000000 --- a/Content.Client/Paint/PaintVisualizerSystem.cs +++ /dev/null @@ -1,116 +0,0 @@ -using System.Linq; -using Robust.Client.GameObjects; -using static Robust.Client.GameObjects.SpriteComponent; -using Content.Shared.Clothing; -using Content.Shared.Hands; -using Content.Shared.Paint; -using Robust.Client.Graphics; -using Robust.Shared.Prototypes; - -namespace Content.Client.Paint; - -public sealed class PaintedVisualizerSystem : VisualizerSystem -{ - /// - /// Visualizer for Paint which applies a shader and colors the entity. - /// - - [Dependency] private readonly SharedAppearanceSystem _appearance = default!; - [Dependency] private readonly IPrototypeManager _protoMan = default!; - - public override void Initialize() - { - base.Initialize(); - - SubscribeLocalEvent(OnHeldVisualsUpdated); - SubscribeLocalEvent(OnShutdown); - SubscribeLocalEvent(OnEquipmentVisualsUpdated); - } - - protected override void OnAppearanceChange(EntityUid uid, PaintedComponent component, ref AppearanceChangeEvent args) - { - var shader = _protoMan.Index(component.ShaderName).Instance(); - - if (args.Sprite == null) - return; - - // What is this even doing? It's not even checking what the value is. - if (!_appearance.TryGetData(uid, PaintVisuals.Painted, out bool isPainted)) - return; - - var sprite = args.Sprite; - - foreach (var spriteLayer in sprite.AllLayers) - { - if (spriteLayer is not Layer layer) - continue; - - if (layer.Shader == null) // If shader isn't null we dont want to replace the original shader. - { - layer.Shader = shader; - layer.Color = component.Color; - } - } - } - - private void OnHeldVisualsUpdated(EntityUid uid, PaintedComponent component, HeldVisualsUpdatedEvent args) - { - if (args.RevealedLayers.Count == 0) - return; - - if (!TryComp(args.User, out SpriteComponent? sprite)) - return; - - foreach (var revealed in args.RevealedLayers) - { - if (!sprite.LayerMapTryGet(revealed, out var layer)) - continue; - - sprite.LayerSetShader(layer, component.ShaderName); - sprite.LayerSetColor(layer, component.Color); - } - } - - private void OnEquipmentVisualsUpdated(EntityUid uid, PaintedComponent component, EquipmentVisualsUpdatedEvent args) - { - if (args.RevealedLayers.Count == 0) - return; - - if (!TryComp(args.Equipee, out SpriteComponent? sprite)) - return; - - foreach (var revealed in args.RevealedLayers) - { - if (!sprite.LayerMapTryGet(revealed, out var layer)) - continue; - - sprite.LayerSetShader(layer, component.ShaderName); - sprite.LayerSetColor(layer, component.Color); - } - } - - private void OnShutdown(EntityUid uid, PaintedComponent component, ref ComponentShutdown args) - { - if (!TryComp(uid, out SpriteComponent? sprite)) - return; - - component.BeforeColor = sprite.Color; - var shader = _protoMan.Index(component.ShaderName).Instance(); - - if (!Terminating(uid)) - { - foreach (var spriteLayer in sprite.AllLayers) - { - if (spriteLayer is not Layer layer) - continue; - - if (layer.Shader == shader) // If shader isn't same as one in component we need to ignore it. - { - layer.Shader = null; - if (layer.Color == component.Color) // If color isn't the same as one in component we don't want to change it. - layer.Color = component.BeforeColor; - } - } - } - } -} diff --git a/Content.Client/Pinpointer/UI/NavMapControl.cs b/Content.Client/Pinpointer/UI/NavMapControl.cs index a8ec7b37a0..677092e191 100644 --- a/Content.Client/Pinpointer/UI/NavMapControl.cs +++ b/Content.Client/Pinpointer/UI/NavMapControl.cs @@ -114,9 +114,16 @@ public partial class NavMapControl : MapGridControl VerticalExpand = false, Children = { - _zoom, - _beacons, - _recenter, + new BoxContainer() + { + Orientation = BoxContainer.LayoutOrientation.Horizontal, + Children = + { + _zoom, + _beacons, + _recenter + } + } } }; diff --git a/Content.Client/Popups/PopupSystem.cs b/Content.Client/Popups/PopupSystem.cs index 479fb02906..fcc8bfc420 100644 --- a/Content.Client/Popups/PopupSystem.cs +++ b/Content.Client/Popups/PopupSystem.cs @@ -163,10 +163,13 @@ namespace Content.Client.Popups PopupEntity(message, uid, type); } - public override void PopupClient(string? message, EntityUid uid, EntityUid recipient, PopupType type = PopupType.Small) + public override void PopupClient(string? message, EntityUid uid, EntityUid? recipient, PopupType type = PopupType.Small) { + if (recipient == null) + return; + if (_timing.IsFirstTimePredicted) - PopupEntity(message, uid, recipient, type); + PopupEntity(message, uid, recipient.Value, type); } public override void PopupEntity(string? message, EntityUid uid, PopupType type = PopupType.Small) diff --git a/Content.Client/RCD/AlignRCDConstruction.cs b/Content.Client/RCD/AlignRCDConstruction.cs new file mode 100644 index 0000000000..da7b22c91a --- /dev/null +++ b/Content.Client/RCD/AlignRCDConstruction.cs @@ -0,0 +1,122 @@ +using System.Numerics; +using Content.Client.Gameplay; +using Content.Shared.Hands.Components; +using Content.Shared.Interaction; +using Content.Shared.RCD.Components; +using Content.Shared.RCD.Systems; +using Robust.Client.Placement; +using Robust.Client.Player; +using Robust.Client.State; +using Robust.Shared.Map; +using Robust.Shared.Map.Components; + +namespace Content.Client.RCD; + +public sealed class AlignRCDConstruction : PlacementMode +{ + [Dependency] private readonly IEntityManager _entityManager = default!; + [Dependency] private readonly IMapManager _mapManager = default!; + [Dependency] private readonly SharedMapSystem _mapSystem = default!; + [Dependency] private readonly RCDSystem _rcdSystem = default!; + [Dependency] private readonly SharedTransformSystem _transformSystem = default!; + [Dependency] private readonly IPlayerManager _playerManager = default!; + [Dependency] private readonly IStateManager _stateManager = default!; + + private const float SearchBoxSize = 2f; + private const float PlaceColorBaseAlpha = 0.5f; + + private EntityCoordinates _unalignedMouseCoords = default; + + /// + /// This placement mode is not on the engine because it is content specific (i.e., for the RCD) + /// + public AlignRCDConstruction(PlacementManager pMan) : base(pMan) + { + var dependencies = IoCManager.Instance!; + _entityManager = dependencies.Resolve(); + _mapManager = dependencies.Resolve(); + _playerManager = dependencies.Resolve(); + _stateManager = dependencies.Resolve(); + + _mapSystem = _entityManager.System(); + _rcdSystem = _entityManager.System(); + _transformSystem = _entityManager.System(); + + ValidPlaceColor = ValidPlaceColor.WithAlpha(PlaceColorBaseAlpha); + } + + public override void AlignPlacementMode(ScreenCoordinates mouseScreen) + { + _unalignedMouseCoords = ScreenToCursorGrid(mouseScreen); + MouseCoords = _unalignedMouseCoords.AlignWithClosestGridTile(SearchBoxSize, _entityManager, _mapManager); + + var gridId = MouseCoords.GetGridUid(_entityManager); + + if (!_entityManager.TryGetComponent(gridId, out var mapGrid)) + return; + + CurrentTile = _mapSystem.GetTileRef(gridId.Value, mapGrid, MouseCoords); + + float tileSize = mapGrid.TileSize; + GridDistancing = tileSize; + + if (pManager.CurrentPermission!.IsTile) + { + MouseCoords = new EntityCoordinates(MouseCoords.EntityId, new Vector2(CurrentTile.X + tileSize / 2, + CurrentTile.Y + tileSize / 2)); + } + else + { + MouseCoords = new EntityCoordinates(MouseCoords.EntityId, new Vector2(CurrentTile.X + tileSize / 2 + pManager.PlacementOffset.X, + CurrentTile.Y + tileSize / 2 + pManager.PlacementOffset.Y)); + } + } + + public override bool IsValidPosition(EntityCoordinates position) + { + var player = _playerManager.LocalSession?.AttachedEntity; + + // If the destination is out of interaction range, set the placer alpha to zero + if (!_entityManager.TryGetComponent(player, out var xform)) + return false; + + if (!xform.Coordinates.InRange(_entityManager, _transformSystem, position, SharedInteractionSystem.InteractionRange)) + { + InvalidPlaceColor = InvalidPlaceColor.WithAlpha(0); + return false; + } + + // Otherwise restore the alpha value + else + { + InvalidPlaceColor = InvalidPlaceColor.WithAlpha(PlaceColorBaseAlpha); + } + + // Determine if player is carrying an RCD in their active hand + if (!_entityManager.TryGetComponent(player, out var hands)) + return false; + + var heldEntity = hands.ActiveHand?.HeldEntity; + + if (!_entityManager.TryGetComponent(heldEntity, out var rcd)) + return false; + + // Retrieve the map grid data for the position + if (!_rcdSystem.TryGetMapGridData(position, out var mapGridData)) + return false; + + // Determine if the user is hovering over a target + var currentState = _stateManager.CurrentState; + + if (currentState is not GameplayStateBase screen) + return false; + + var target = screen.GetClickedEntity(_unalignedMouseCoords.ToMap(_entityManager, _transformSystem)); + + // Determine if the RCD operation is valid or not + if (!_rcdSystem.IsRCDOperationStillValid(heldEntity.Value, rcd, mapGridData.Value, target, player.Value, false)) + return false; + + return true; + } +} diff --git a/Content.Client/RCD/RCDConstructionGhostSystem.cs b/Content.Client/RCD/RCDConstructionGhostSystem.cs new file mode 100644 index 0000000000..792916b892 --- /dev/null +++ b/Content.Client/RCD/RCDConstructionGhostSystem.cs @@ -0,0 +1,78 @@ +using Content.Shared.Hands.Components; +using Content.Shared.Interaction; +using Content.Shared.RCD; +using Content.Shared.RCD.Components; +using Content.Shared.RCD.Systems; +using Robust.Client.Placement; +using Robust.Client.Player; +using Robust.Shared.Enums; + +namespace Content.Client.RCD; + +public sealed class RCDConstructionGhostSystem : EntitySystem +{ + [Dependency] private readonly IPlayerManager _playerManager = default!; + [Dependency] private readonly RCDSystem _rcdSystem = default!; + [Dependency] private readonly IPlacementManager _placementManager = default!; + + private string _placementMode = typeof(AlignRCDConstruction).Name; + private Direction _placementDirection = default; + + public override void Update(float frameTime) + { + base.Update(frameTime); + + // Get current placer data + var placerEntity = _placementManager.CurrentPermission?.MobUid; + var placerProto = _placementManager.CurrentPermission?.EntityType; + var placerIsRCD = HasComp(placerEntity); + + // Exit if erasing or the current placer is not an RCD (build mode is active) + if (_placementManager.Eraser || (placerEntity != null && !placerIsRCD)) + return; + + // Determine if player is carrying an RCD in their active hand + var player = _playerManager.LocalSession?.AttachedEntity; + + if (!TryComp(player, out var hands)) + return; + + var heldEntity = hands.ActiveHand?.HeldEntity; + + if (!TryComp(heldEntity, out var rcd)) + { + // If the player was holding an RCD, but is no longer, cancel placement + if (placerIsRCD) + _placementManager.Clear(); + + return; + } + + // Update the direction the RCD prototype based on the placer direction + if (_placementDirection != _placementManager.Direction) + { + _placementDirection = _placementManager.Direction; + RaiseNetworkEvent(new RCDConstructionGhostRotationEvent(GetNetEntity(heldEntity.Value), _placementDirection)); + } + + // If the placer has not changed, exit + _rcdSystem.UpdateCachedPrototype(heldEntity.Value, rcd); + + if (heldEntity == placerEntity && rcd.CachedPrototype.Prototype == placerProto) + return; + + // Create a new placer + var newObjInfo = new PlacementInformation + { + MobUid = heldEntity.Value, + PlacementOption = _placementMode, + EntityType = rcd.CachedPrototype.Prototype, + Range = (int) Math.Ceiling(SharedInteractionSystem.InteractionRange), + IsTile = (rcd.CachedPrototype.Mode == RcdMode.ConstructTile), + UseEditorContext = false, + }; + + _placementManager.Clear(); + _placementManager.BeginPlacing(newObjInfo); + } +} diff --git a/Content.Client/RCD/RCDMenu.xaml b/Content.Client/RCD/RCDMenu.xaml new file mode 100644 index 0000000000..b3d5367a5f --- /dev/null +++ b/Content.Client/RCD/RCDMenu.xaml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Content.Client/RCD/RCDMenu.xaml.cs b/Content.Client/RCD/RCDMenu.xaml.cs new file mode 100644 index 0000000000..8679e789dc --- /dev/null +++ b/Content.Client/RCD/RCDMenu.xaml.cs @@ -0,0 +1,137 @@ +using Content.Client.UserInterface.Controls; +using Content.Shared.RCD; +using Content.Shared.RCD.Components; +using Robust.Client.AutoGenerated; +using Robust.Client.GameObjects; +using Robust.Client.UserInterface; +using Robust.Client.UserInterface.Controls; +using Robust.Client.UserInterface.XAML; +using Robust.Shared.Prototypes; +using System.Numerics; + +namespace Content.Client.RCD; + +[GenerateTypedNameReferences] +public sealed partial class RCDMenu : RadialMenu +{ + [Dependency] private readonly EntityManager _entManager = default!; + [Dependency] private readonly IPrototypeManager _protoManager = default!; + + private readonly SpriteSystem _spriteSystem; + + public event Action>? SendRCDSystemMessageAction; + + public RCDMenu(EntityUid owner, RCDMenuBoundUserInterface bui) + { + IoCManager.InjectDependencies(this); + RobustXamlLoader.Load(this); + + _spriteSystem = _entManager.System(); + + // Find the main radial container + var main = FindControl("Main"); + + if (main == null) + return; + + // Populate secondary radial containers + if (!_entManager.TryGetComponent(owner, out var rcd)) + return; + + foreach (var protoId in rcd.AvailablePrototypes) + { + if (!_protoManager.TryIndex(protoId, out var proto)) + continue; + + if (proto.Mode == RcdMode.Invalid) + continue; + + var parent = FindControl(proto.Category); + + if (parent == null) + continue; + + var name = Loc.GetString(proto.SetName); + name = char.ToUpper(name[0]) + name.Remove(0, 1); + + var button = new RCDMenuButton() + { + StyleClasses = { "RadialMenuButton" }, + SetSize = new Vector2(64f, 64f), + ToolTip = name, + ProtoId = protoId, + }; + + if (proto.Sprite != null) + { + var tex = new TextureRect() + { + VerticalAlignment = VAlignment.Center, + HorizontalAlignment = HAlignment.Center, + Texture = _spriteSystem.Frame0(proto.Sprite), + TextureScale = new Vector2(2f, 2f), + }; + + button.AddChild(tex); + } + + parent.AddChild(button); + + // Ensure that the button that transitions the menu to the associated category layer + // is visible in the main radial container (as these all start with Visible = false) + foreach (var child in main.Children) + { + var castChild = child as RadialMenuTextureButton; + + if (castChild is not RadialMenuTextureButton) + continue; + + if (castChild.TargetLayer == proto.Category) + { + castChild.Visible = true; + break; + } + } + } + + // Set up menu actions + foreach (var child in Children) + AddRCDMenuButtonOnClickActions(child); + + OnChildAdded += AddRCDMenuButtonOnClickActions; + + SendRCDSystemMessageAction += bui.SendRCDSystemMessage; + } + + private void AddRCDMenuButtonOnClickActions(Control control) + { + var radialContainer = control as RadialContainer; + + if (radialContainer == null) + return; + + foreach (var child in radialContainer.Children) + { + var castChild = child as RCDMenuButton; + + if (castChild == null) + continue; + + castChild.OnButtonUp += _ => + { + SendRCDSystemMessageAction?.Invoke(castChild.ProtoId); + Close(); + }; + } + } +} + +public sealed class RCDMenuButton : RadialMenuTextureButton +{ + public ProtoId ProtoId { get; set; } + + public RCDMenuButton() + { + + } +} diff --git a/Content.Client/RCD/RCDMenuBoundUserInterface.cs b/Content.Client/RCD/RCDMenuBoundUserInterface.cs new file mode 100644 index 0000000000..a37dbcecf8 --- /dev/null +++ b/Content.Client/RCD/RCDMenuBoundUserInterface.cs @@ -0,0 +1,49 @@ +using Content.Shared.RCD; +using Content.Shared.RCD.Components; +using JetBrains.Annotations; +using Robust.Client.Graphics; +using Robust.Client.Input; +using Robust.Shared.Prototypes; + +namespace Content.Client.RCD; + +[UsedImplicitly] +public sealed class RCDMenuBoundUserInterface : BoundUserInterface +{ + [Dependency] private readonly IClyde _displayManager = default!; + [Dependency] private readonly IInputManager _inputManager = default!; + + private RCDMenu? _menu; + + public RCDMenuBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) + { + IoCManager.InjectDependencies(this); + } + + protected override void Open() + { + base.Open(); + + _menu = new(Owner, this); + _menu.OnClose += Close; + + // Open the menu, centered on the mouse + var vpSize = _displayManager.ScreenSize; + _menu.OpenCenteredAt(_inputManager.MouseScreenPosition.Position / vpSize); + } + + public void SendRCDSystemMessage(ProtoId protoId) + { + // A predicted message cannot be used here as the RCD UI is closed immediately + // after this message is sent, which will stop the server from receiving it + SendMessage(new RCDSystemMessage(protoId)); + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) return; + + _menu?.Dispose(); + } +} diff --git a/Content.Client/Shuttles/UI/MapScreen.xaml.cs b/Content.Client/Shuttles/UI/MapScreen.xaml.cs index 225d1be14e..10800b8c5f 100644 --- a/Content.Client/Shuttles/UI/MapScreen.xaml.cs +++ b/Content.Client/Shuttles/UI/MapScreen.xaml.cs @@ -263,9 +263,10 @@ public sealed partial class MapScreen : BoxContainer while (mapComps.MoveNext(out var mapComp, out var mapXform, out var mapMetadata)) { - if (!_shuttles.CanFTLTo(_shuttleEntity.Value, mapComp.MapId)) - continue; - + if (_console != null && !_shuttles.CanFTLTo(_shuttleEntity.Value, mapComp.MapId, _console.Value)) + { + continue; + } var mapName = mapMetadata.EntityName; if (string.IsNullOrEmpty(mapName)) @@ -310,7 +311,6 @@ public sealed partial class MapScreen : BoxContainer }; _mapHeadings.Add(mapComp.MapId, gridContents); - foreach (var grid in _mapManager.GetAllMapGrids(mapComp.MapId)) { _entManager.TryGetComponent(grid.Owner, out IFFComponent? iffComp); @@ -327,8 +327,8 @@ public sealed partial class MapScreen : BoxContainer { AddMapObject(mapComp.MapId, gridObj); } - else if (iffComp == null || - (iffComp.Flags & IFFFlags.Hide) == 0x0) + else if (!_shuttles.IsBeaconMap(_mapManager.GetMapEntityId(mapComp.MapId)) && (iffComp == null || + (iffComp.Flags & IFFFlags.Hide) == 0x0)) { _pendingMapObjects.Add((mapComp.MapId, gridObj)); } diff --git a/Content.Client/Store/Ui/StoreBoundUserInterface.cs b/Content.Client/Store/Ui/StoreBoundUserInterface.cs index b549918d7c..f87b92bc61 100644 --- a/Content.Client/Store/Ui/StoreBoundUserInterface.cs +++ b/Content.Client/Store/Ui/StoreBoundUserInterface.cs @@ -1,22 +1,27 @@ using Content.Shared.Store; using JetBrains.Annotations; -using Robust.Client.GameObjects; using System.Linq; -using System.Threading; -using Serilog; -using Timer = Robust.Shared.Timing.Timer; +using Robust.Shared.Prototypes; namespace Content.Client.Store.Ui; [UsedImplicitly] public sealed class StoreBoundUserInterface : BoundUserInterface { + private IPrototypeManager _prototypeManager = default!; + [ViewVariables] private StoreMenu? _menu; [ViewVariables] private string _windowName = Loc.GetString("store-ui-default-title"); + [ViewVariables] + private string _search = ""; + + [ViewVariables] + private HashSet _listings = new(); + public StoreBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { } @@ -49,6 +54,12 @@ public sealed class StoreBoundUserInterface : BoundUserInterface SendMessage(new StoreRequestUpdateInterfaceMessage()); }; + _menu.SearchTextUpdated += (_, search) => + { + _search = search.Trim().ToLowerInvariant(); + UpdateListingsWithSearchFilter(); + }; + _menu.OnRefundAttempt += (_) => { SendMessage(new StoreRequestRefundMessage()); @@ -64,10 +75,10 @@ public sealed class StoreBoundUserInterface : BoundUserInterface switch (state) { case StoreUpdateState msg: - _menu.UpdateBalance(msg.Balance); - _menu.PopulateStoreCategoryButtons(msg.Listings); + _listings = msg.Listings; - _menu.UpdateListing(msg.Listings.ToList()); + _menu.UpdateBalance(msg.Balance); + UpdateListingsWithSearchFilter(); _menu.SetFooterVisibility(msg.ShowFooter); _menu.UpdateRefund(msg.AllowRefund); break; @@ -89,4 +100,19 @@ public sealed class StoreBoundUserInterface : BoundUserInterface _menu?.Close(); _menu?.Dispose(); } + + private void UpdateListingsWithSearchFilter() + { + if (_menu == null) + return; + + var filteredListings = new HashSet(_listings); + if (!string.IsNullOrEmpty(_search)) + { + filteredListings.RemoveWhere(listingData => !ListingLocalisationHelpers.GetLocalisedNameOrEntityName(listingData, _prototypeManager).Trim().ToLowerInvariant().Contains(_search) && + !ListingLocalisationHelpers.GetLocalisedDescriptionOrEntityDescription(listingData, _prototypeManager).Trim().ToLowerInvariant().Contains(_search)); + } + _menu.PopulateStoreCategoryButtons(filteredListings); + _menu.UpdateListing(filteredListings.ToList()); + } } diff --git a/Content.Client/Store/Ui/StoreMenu.xaml b/Content.Client/Store/Ui/StoreMenu.xaml index 4b38352a44..fc4cbe444f 100644 --- a/Content.Client/Store/Ui/StoreMenu.xaml +++ b/Content.Client/Store/Ui/StoreMenu.xaml @@ -28,7 +28,8 @@ HorizontalAlignment="Right" Text="Refund" /> - + + diff --git a/Content.Client/Store/Ui/StoreMenu.xaml.cs b/Content.Client/Store/Ui/StoreMenu.xaml.cs index 5dc1ab246b..67e5d360a3 100644 --- a/Content.Client/Store/Ui/StoreMenu.xaml.cs +++ b/Content.Client/Store/Ui/StoreMenu.xaml.cs @@ -1,5 +1,4 @@ using System.Linq; -using System.Threading; using Content.Client.Actions; using Content.Client.GameTicking.Managers; using Content.Client.Message; @@ -27,6 +26,7 @@ public sealed partial class StoreMenu : DefaultWindow private StoreWithdrawWindow? _withdrawWindow; + public event EventHandler? SearchTextUpdated; public event Action? OnListingButtonPressed; public event Action? OnCategoryButtonPressed; public event Action? OnWithdrawAttempt; @@ -46,6 +46,7 @@ public sealed partial class StoreMenu : DefaultWindow WithdrawButton.OnButtonDown += OnWithdrawButtonDown; RefreshButton.OnButtonDown += OnRefreshButtonDown; RefundButton.OnButtonDown += OnRefundButtonDown; + SearchBar.OnTextChanged += _ => SearchTextUpdated?.Invoke(this, SearchBar.Text); if (Window != null) Window.Title = name; @@ -59,7 +60,7 @@ public sealed partial class StoreMenu : DefaultWindow (type.Key, type.Value), type => _prototypeManager.Index(type.Key)); var balanceStr = string.Empty; - foreach (var ((type, amount),proto) in currency) + foreach (var ((_, amount), proto) in currency) { balanceStr += Loc.GetString("store-ui-balance-display", ("amount", amount), ("currency", Loc.GetString(proto.DisplayName, ("amount", 1)))); @@ -81,7 +82,6 @@ public sealed partial class StoreMenu : DefaultWindow { var sorted = listings.OrderBy(l => l.Priority).ThenBy(l => l.Cost.Values.Sum()); - // should probably chunk these out instead. to-do if this clogs the internet tubes. // maybe read clients prototypes instead? ClearListings(); @@ -129,8 +129,8 @@ public sealed partial class StoreMenu : DefaultWindow if (!listing.Categories.Contains(CurrentCategory)) return; - var listingName = Loc.GetString(listing.Name); - var listingDesc = Loc.GetString(listing.Description); + var listingName = ListingLocalisationHelpers.GetLocalisedNameOrEntityName(listing, _prototypeManager); + var listingDesc = ListingLocalisationHelpers.GetLocalisedDescriptionOrEntityDescription(listing, _prototypeManager); var listingPrice = listing.Cost; var canBuy = CanBuyListing(Balance, listingPrice); @@ -144,12 +144,6 @@ public sealed partial class StoreMenu : DefaultWindow { if (texture == null) texture = spriteSys.GetPrototypeIcon(listing.ProductEntity).Default; - - var proto = _prototypeManager.Index(listing.ProductEntity); - if (listingName == string.Empty) - listingName = proto.Name; - if (listingDesc == string.Empty) - listingDesc = proto.Description; } else if (listing.ProductAction != null) { @@ -243,13 +237,16 @@ public sealed partial class StoreMenu : DefaultWindow allCategories = allCategories.OrderBy(c => c.Priority).ToList(); + // This will reset the Current Category selection if nothing matches the search. + if (allCategories.All(category => category.ID != CurrentCategory)) + CurrentCategory = string.Empty; + if (CurrentCategory == string.Empty && allCategories.Count > 0) CurrentCategory = allCategories.First().ID; - if (allCategories.Count <= 1) - return; - CategoryListContainer.Children.Clear(); + if (allCategories.Count < 1) + return; foreach (var proto in allCategories) { diff --git a/Content.Client/Stylesheets/StyleNano.cs b/Content.Client/Stylesheets/StyleNano.cs index 426af1616e..a589abb83a 100644 --- a/Content.Client/Stylesheets/StyleNano.cs +++ b/Content.Client/Stylesheets/StyleNano.cs @@ -45,6 +45,7 @@ namespace Content.Client.Stylesheets public const string StyleClassBorderedWindowPanel = "BorderedWindowPanel"; public const string StyleClassInventorySlotBackground = "InventorySlotBackground"; public const string StyleClassHandSlotHighlight = "HandSlotHighlight"; + public const string StyleClassChatPanel = "ChatPanel"; public const string StyleClassChatSubPanel = "ChatSubPanel"; public const string StyleClassTransparentBorderedWindowPanel = "TransparentBorderedWindowPanel"; public const string StyleClassHotbarPanel = "HotbarPanel"; @@ -144,6 +145,8 @@ namespace Content.Client.Stylesheets public const string StyleClassButtonColorRed = "ButtonColorRed"; public const string StyleClassButtonColorGreen = "ButtonColorGreen"; + public static readonly Color ChatBackgroundColor = Color.FromHex("#25252ADD"); + public override Stylesheet Stylesheet { get; } public StyleNano(IResourceCache resCache) : base(resCache) @@ -290,7 +293,7 @@ namespace Content.Client.Stylesheets var buttonTex = resCache.GetTexture("/Textures/Interface/Nano/button.svg.96dpi.png"); var topButtonBase = new StyleBoxTexture { - Texture = buttonTex, + Texture = buttonTex, }; topButtonBase.SetPatchMargin(StyleBox.Margin.All, 10); topButtonBase.SetPadding(StyleBox.Margin.All, 0); @@ -298,19 +301,19 @@ namespace Content.Client.Stylesheets var topButtonOpenRight = new StyleBoxTexture(topButtonBase) { - Texture = new AtlasTexture(buttonTex, UIBox2.FromDimensions(new Vector2(0, 0), new Vector2(14, 24))), + Texture = new AtlasTexture(buttonTex, UIBox2.FromDimensions(new Vector2(0, 0), new Vector2(14, 24))), }; topButtonOpenRight.SetPatchMargin(StyleBox.Margin.Right, 0); var topButtonOpenLeft = new StyleBoxTexture(topButtonBase) { - Texture = new AtlasTexture(buttonTex, UIBox2.FromDimensions(new Vector2(10, 0), new Vector2(14, 24))), + Texture = new AtlasTexture(buttonTex, UIBox2.FromDimensions(new Vector2(10, 0), new Vector2(14, 24))), }; topButtonOpenLeft.SetPatchMargin(StyleBox.Margin.Left, 0); var topButtonSquare = new StyleBoxTexture(topButtonBase) { - Texture = new AtlasTexture(buttonTex, UIBox2.FromDimensions(new Vector2(10, 0), new Vector2(3, 24))), + Texture = new AtlasTexture(buttonTex, UIBox2.FromDimensions(new Vector2(10, 0), new Vector2(3, 24))), }; topButtonSquare.SetPatchMargin(StyleBox.Margin.Horizontal, 0); @@ -346,12 +349,16 @@ namespace Content.Client.Stylesheets lineEdit.SetPatchMargin(StyleBox.Margin.All, 3); lineEdit.SetContentMarginOverride(StyleBox.Margin.Horizontal, 5); - var chatSubBGTex = resCache.GetTexture("/Textures/Interface/Nano/chat_sub_background.png"); - var chatSubBG = new StyleBoxTexture + var chatBg = new StyleBoxFlat { - Texture = chatSubBGTex, + BackgroundColor = ChatBackgroundColor }; - chatSubBG.SetPatchMargin(StyleBox.Margin.All, 2); + + var chatSubBg = new StyleBoxFlat + { + BackgroundColor = ChatBackgroundColor, + }; + chatSubBg.SetContentMarginOverride(StyleBox.Margin.All, 2); var actionSearchBoxTex = resCache.GetTexture("/Textures/Interface/Nano/black_panel_dark_thin_border.png"); var actionSearchBox = new StyleBoxTexture @@ -368,9 +375,9 @@ namespace Content.Client.Stylesheets }; tabContainerPanel.SetPatchMargin(StyleBox.Margin.All, 2); - var tabContainerBoxActive = new StyleBoxFlat {BackgroundColor = new Color(64, 64, 64)}; + var tabContainerBoxActive = new StyleBoxFlat { BackgroundColor = new Color(64, 64, 64) }; tabContainerBoxActive.SetContentMarginOverride(StyleBox.Margin.Horizontal, 5); - var tabContainerBoxInactive = new StyleBoxFlat {BackgroundColor = new Color(32, 32, 32)}; + var tabContainerBoxInactive = new StyleBoxFlat { BackgroundColor = new Color(32, 32, 32) }; tabContainerBoxInactive.SetContentMarginOverride(StyleBox.Margin.Horizontal, 5); var progressBarBackground = new StyleBoxFlat @@ -409,21 +416,21 @@ namespace Content.Client.Stylesheets // Placeholder var placeholderTexture = resCache.GetTexture("/Textures/Interface/Nano/placeholder.png"); - var placeholder = new StyleBoxTexture {Texture = placeholderTexture}; + var placeholder = new StyleBoxTexture { Texture = placeholderTexture }; placeholder.SetPatchMargin(StyleBox.Margin.All, 19); placeholder.SetExpandMargin(StyleBox.Margin.All, -5); placeholder.Mode = StyleBoxTexture.StretchMode.Tile; - var itemListBackgroundSelected = new StyleBoxFlat {BackgroundColor = new Color(75, 75, 86)}; + var itemListBackgroundSelected = new StyleBoxFlat { BackgroundColor = new Color(75, 75, 86) }; itemListBackgroundSelected.SetContentMarginOverride(StyleBox.Margin.Vertical, 2); itemListBackgroundSelected.SetContentMarginOverride(StyleBox.Margin.Horizontal, 4); - var itemListItemBackgroundDisabled = new StyleBoxFlat {BackgroundColor = new Color(10, 10, 12)}; + var itemListItemBackgroundDisabled = new StyleBoxFlat { BackgroundColor = new Color(10, 10, 12) }; itemListItemBackgroundDisabled.SetContentMarginOverride(StyleBox.Margin.Vertical, 2); itemListItemBackgroundDisabled.SetContentMarginOverride(StyleBox.Margin.Horizontal, 4); - var itemListItemBackground = new StyleBoxFlat {BackgroundColor = new Color(55, 55, 68)}; + var itemListItemBackground = new StyleBoxFlat { BackgroundColor = new Color(55, 55, 68) }; itemListItemBackground.SetContentMarginOverride(StyleBox.Margin.Vertical, 2); itemListItemBackground.SetContentMarginOverride(StyleBox.Margin.Horizontal, 4); - var itemListItemBackgroundTransparent = new StyleBoxFlat {BackgroundColor = Color.Transparent}; + var itemListItemBackgroundTransparent = new StyleBoxFlat { BackgroundColor = Color.Transparent }; itemListItemBackgroundTransparent.SetContentMarginOverride(StyleBox.Margin.Vertical, 2); itemListItemBackgroundTransparent.SetContentMarginOverride(StyleBox.Margin.Horizontal, 4); @@ -489,9 +496,9 @@ namespace Content.Client.Stylesheets sliderForeBox.SetPatchMargin(StyleBox.Margin.All, 12); sliderGrabBox.SetPatchMargin(StyleBox.Margin.All, 12); - var sliderFillGreen = new StyleBoxTexture(sliderFillBox) {Modulate = Color.LimeGreen}; - var sliderFillRed = new StyleBoxTexture(sliderFillBox) {Modulate = Color.Red}; - var sliderFillBlue = new StyleBoxTexture(sliderFillBox) {Modulate = Color.Blue}; + var sliderFillGreen = new StyleBoxTexture(sliderFillBox) { Modulate = Color.LimeGreen }; + var sliderFillRed = new StyleBoxTexture(sliderFillBox) { Modulate = Color.Red }; + var sliderFillBlue = new StyleBoxTexture(sliderFillBox) { Modulate = Color.Blue }; var sliderFillWhite = new StyleBoxTexture(sliderFillBox) { Modulate = Color.White }; var boxFont13 = resCache.GetFont("/Fonts/Boxfont-round/Boxfont Round.ttf", 13); @@ -850,6 +857,13 @@ namespace Content.Client.Stylesheets Element().Pseudo(TextEdit.StylePseudoClassPlaceholder) .Prop("font-color", Color.Gray), + // chat subpanels (chat lineedit backing, popup backings) + new StyleRule(new SelectorElement(typeof(PanelContainer), new[] {StyleClassChatPanel}, null, null), + new[] + { + new StyleProperty(PanelContainer.StylePropertyPanel, chatBg), + }), + // Chat lineedit - we don't actually draw a stylebox around the lineedit itself, we put it around the // input + other buttons, so we must clear the default stylebox new StyleRule(new SelectorElement(typeof(LineEdit), new[] {StyleClassChatLineEdit}, null, null), @@ -858,13 +872,6 @@ namespace Content.Client.Stylesheets new StyleProperty(LineEdit.StylePropertyStyleBox, new StyleBoxEmpty()), }), - // chat subpanels (chat lineedit backing, popup backings) - new StyleRule(new SelectorElement(typeof(PanelContainer), new[] {StyleClassChatSubPanel}, null, null), - new[] - { - new StyleProperty(PanelContainer.StylePropertyPanel, chatSubBG), - }), - // Action searchbox lineedit new StyleRule(new SelectorElement(typeof(LineEdit), new[] {StyleClassActionSearchBox}, null, null), new[] @@ -1468,6 +1475,25 @@ namespace Content.Client.Stylesheets Element private void TryWriteToTargetAccessReaderId(EntityUid uid, - List newAccessList, + List> newAccessList, EntityUid player, AccessOverriderComponent? component = null) { @@ -211,9 +217,7 @@ public sealed class AccessOverriderSystem : SharedAccessOverriderSystem return; } - TryComp(component.TargetAccessReaderId, out AccessReaderComponent? accessReader); - - if (accessReader == null) + if (!_accessReader.GetMainAccessReader(component.TargetAccessReaderId, out var accessReader)) return; var oldTags = ConvertAccessHashSetsToList(accessReader.AccessLists); @@ -262,10 +266,10 @@ public sealed class AccessOverriderSystem : SharedAccessOverriderSystem if (!Resolve(uid, ref component)) return true; - if (!EntityManager.TryGetComponent(uid, out var reader)) + if (_accessReader.GetMainAccessReader(uid, out var accessReader)) return true; var privilegedId = component.PrivilegedIdSlot.Item; - return privilegedId != null && _accessReader.IsAllowed(privilegedId.Value, uid, reader); + return privilegedId != null && _accessReader.IsAllowed(privilegedId.Value, uid, accessReader); } } diff --git a/Content.Server/Access/Systems/IdCardConsoleSystem.cs b/Content.Server/Access/Systems/IdCardConsoleSystem.cs index 791159f972..db8b9d036e 100644 --- a/Content.Server/Access/Systems/IdCardConsoleSystem.cs +++ b/Content.Server/Access/Systems/IdCardConsoleSystem.cs @@ -12,6 +12,7 @@ using Robust.Shared.Containers; using Robust.Shared.Prototypes; using System.Linq; using static Content.Shared.Access.Components.IdCardConsoleComponent; +using Content.Shared.Access; namespace Content.Server.Access.Systems; @@ -54,11 +55,11 @@ public sealed class IdCardConsoleSystem : SharedIdCardConsoleSystem return; var privilegedIdName = string.Empty; - string[]? possibleAccess = null; + List>? possibleAccess = null; if (component.PrivilegedIdSlot.Item is { Valid: true } item) { privilegedIdName = EntityManager.GetComponent(item).EntityName; - possibleAccess = _accessReader.FindAccessTags(item).ToArray(); + possibleAccess = _accessReader.FindAccessTags(item).ToList(); } IdCardConsoleBoundUserInterfaceState newState; @@ -82,7 +83,7 @@ public sealed class IdCardConsoleSystem : SharedIdCardConsoleSystem var targetIdComponent = EntityManager.GetComponent(targetId); var targetAccessComponent = EntityManager.GetComponent(targetId); - var jobProto = string.Empty; + var jobProto = new ProtoId(string.Empty); if (TryComp(targetId, out var keyStorage) && keyStorage.Key is {} key && _record.TryGetRecord(key, out var record)) @@ -96,7 +97,7 @@ public sealed class IdCardConsoleSystem : SharedIdCardConsoleSystem true, targetIdComponent.FullName, targetIdComponent.JobTitle, - targetAccessComponent.Tags.ToArray(), + targetAccessComponent.Tags.ToList(), possibleAccess, jobProto, privilegedIdName, @@ -113,8 +114,8 @@ public sealed class IdCardConsoleSystem : SharedIdCardConsoleSystem private void TryWriteToTargetId(EntityUid uid, string newFullName, string newJobTitle, - List newAccessList, - string newJobProto, + List> newAccessList, + ProtoId newJobProto, EntityUid player, IdCardConsoleComponent? component = null) { @@ -140,7 +141,7 @@ public sealed class IdCardConsoleSystem : SharedIdCardConsoleSystem return; } - var oldTags = _access.TryGetTags(targetId) ?? new List(); + var oldTags = _access.TryGetTags(targetId) ?? new List>(); oldTags = oldTags.ToList(); var privilegedId = component.PrivilegedIdSlot.Item; @@ -189,7 +190,7 @@ public sealed class IdCardConsoleSystem : SharedIdCardConsoleSystem return privilegedId != null && _accessReader.IsAllowed(privilegedId.Value, uid, reader); } - private void UpdateStationRecord(EntityUid uid, EntityUid targetId, string newFullName, string newJobTitle, JobPrototype? newJobProto) + private void UpdateStationRecord(EntityUid uid, EntityUid targetId, string newFullName, ProtoId newJobTitle, JobPrototype? newJobProto) { if (!TryComp(targetId, out var keyStorage) || keyStorage.Key is not { } key diff --git a/Content.Server/Administration/Commands/AGhost.cs b/Content.Server/Administration/Commands/AGhost.cs index d541b1c884..935114e7a6 100644 --- a/Content.Server/Administration/Commands/AGhost.cs +++ b/Content.Server/Administration/Commands/AGhost.cs @@ -1,72 +1,122 @@ -using Content.Server.GameTicking; +using System.Linq; +using Content.Server.GameTicking; +using Content.Server.Ghost; +using Content.Server.Mind; using Content.Shared.Administration; using Content.Shared.Ghost; using Content.Shared.Mind; +using Robust.Server.GameObjects; +using Robust.Server.Player; using Robust.Shared.Console; -namespace Content.Server.Administration.Commands +namespace Content.Server.Administration.Commands; + +[AdminCommand(AdminFlags.Admin)] +public sealed class AGhost : LocalizedCommands { - [AdminCommand(AdminFlags.Admin)] - public sealed class AGhost : IConsoleCommand + [Dependency] private readonly IEntityManager _entities = default!; + [Dependency] private readonly IPlayerManager _playerManager = default!; + + public override string Command => "aghost"; + public override string Description => LocalizationManager.GetString("aghost-description"); + public override string Help => "aghost"; + + public override CompletionResult GetCompletion(IConsoleShell shell, string[] args) { - [Dependency] private readonly IEntityManager _entities = default!; - - public string Command => "aghost"; - public string Description => "Makes you an admin ghost."; - public string Help => "aghost"; - - public void Execute(IConsoleShell shell, string argStr, string[] args) + if (args.Length == 1) { - var player = shell.Player; - if (player == null) - { - shell.WriteLine("Nah"); - return; - } - - var mindSystem = _entities.System(); - if (!mindSystem.TryGetMind(player, out var mindId, out var mind)) - { - shell.WriteLine("You can't ghost here!"); - return; - } - - var metaDataSystem = _entities.System(); - - if (mind.VisitingEntity != default && _entities.TryGetComponent(mind.VisitingEntity, out var oldGhostComponent)) - { - mindSystem.UnVisit(mindId, mind); - // If already an admin ghost, then return to body. - if (oldGhostComponent.CanGhostInteract) - return; - } - - var canReturn = mind.CurrentEntity != null - && !_entities.HasComponent(mind.CurrentEntity); - var coordinates = player.AttachedEntity != null - ? _entities.GetComponent(player.AttachedEntity.Value).Coordinates - : EntitySystem.Get().GetObserverSpawnPoint(); - var ghost = _entities.SpawnEntity(GameTicker.AdminObserverPrototypeName, coordinates); - _entities.GetComponent(ghost).AttachToGridOrMap(); - - if (canReturn) - { - // TODO: Remove duplication between all this and "GamePreset.OnGhostAttempt()"... - if (!string.IsNullOrWhiteSpace(mind.CharacterName)) - metaDataSystem.SetEntityName(ghost, mind.CharacterName); - else if (!string.IsNullOrWhiteSpace(mind.Session?.Name)) - metaDataSystem.SetEntityName(ghost, mind.Session.Name); - - mindSystem.Visit(mindId, ghost, mind); - } - else - { - metaDataSystem.SetEntityName(ghost, player.Name); - mindSystem.TransferTo(mindId, ghost, mind: mind); - } - - var comp = _entities.GetComponent(ghost); - EntitySystem.Get().SetCanReturnToBody(comp, canReturn); + var names = _playerManager.Sessions.OrderBy(c => c.Name).Select(c => c.Name).ToArray(); + return CompletionResult.FromHintOptions(names, LocalizationManager.GetString("shell-argument-username-optional-hint")); } + + return CompletionResult.Empty; + } + + public override void Execute(IConsoleShell shell, string argStr, string[] args) + { + if (args.Length > 1) + { + shell.WriteError(LocalizationManager.GetString("shell-wrong-arguments-number")); + return; + } + + var player = shell.Player; + var self = player != null; + if (player == null) + { + // If you are not a player, you require a player argument. + if (args.Length == 0) + { + shell.WriteError(LocalizationManager.GetString("shell-need-exactly-one-argument")); + return; + } + + var didFind = _playerManager.TryGetSessionByUsername(args[0], out player); + if (!didFind) + { + shell.WriteError(LocalizationManager.GetString("shell-target-player-does-not-exist")); + return; + } + } + + // If you are a player and a username is provided, a lookup is done to find the target player. + if (args.Length == 1) + { + var didFind = _playerManager.TryGetSessionByUsername(args[0], out player); + if (!didFind) + { + shell.WriteError(LocalizationManager.GetString("shell-target-player-does-not-exist")); + return; + } + } + + var mindSystem = _entities.System(); + var metaDataSystem = _entities.System(); + var ghostSystem = _entities.System(); + var transformSystem = _entities.System(); + var gameTicker = _entities.System(); + + if (!mindSystem.TryGetMind(player, out var mindId, out var mind)) + { + shell.WriteError(self + ? LocalizationManager.GetString("aghost-no-mind-self") + : LocalizationManager.GetString("aghost-no-mind-other")); + return; + } + + if (mind.VisitingEntity != default && _entities.TryGetComponent(mind.VisitingEntity, out var oldGhostComponent)) + { + mindSystem.UnVisit(mindId, mind); + // If already an admin ghost, then return to body. + if (oldGhostComponent.CanGhostInteract) + return; + } + + var canReturn = mind.CurrentEntity != null + && !_entities.HasComponent(mind.CurrentEntity); + var coordinates = player!.AttachedEntity != null + ? _entities.GetComponent(player.AttachedEntity.Value).Coordinates + : gameTicker.GetObserverSpawnPoint(); + var ghost = _entities.SpawnEntity(GameTicker.AdminObserverPrototypeName, coordinates); + transformSystem.AttachToGridOrMap(ghost, _entities.GetComponent(ghost)); + + if (canReturn) + { + // TODO: Remove duplication between all this and "GamePreset.OnGhostAttempt()"... + if (!string.IsNullOrWhiteSpace(mind.CharacterName)) + metaDataSystem.SetEntityName(ghost, mind.CharacterName); + else if (!string.IsNullOrWhiteSpace(mind.Session?.Name)) + metaDataSystem.SetEntityName(ghost, mind.Session.Name); + + mindSystem.Visit(mindId, ghost, mind); + } + else + { + metaDataSystem.SetEntityName(ghost, player.Name); + mindSystem.TransferTo(mindId, ghost, mind: mind); + } + + var comp = _entities.GetComponent(ghost); + ghostSystem.SetCanReturnToBody(comp, canReturn); } } diff --git a/Content.Server/Administration/Systems/AdminVerbSystem.Tools.cs b/Content.Server/Administration/Systems/AdminVerbSystem.Tools.cs index 9d66338c8b..328fa74484 100644 --- a/Content.Server/Administration/Systems/AdminVerbSystem.Tools.cs +++ b/Content.Server/Administration/Systems/AdminVerbSystem.Tools.cs @@ -35,6 +35,7 @@ using Robust.Shared.Map.Components; using Robust.Shared.Physics; using Robust.Shared.Physics.Components; using Robust.Shared.Player; +using Robust.Shared.Prototypes; using Robust.Shared.Utility; namespace Content.Server.Administration.Systems; @@ -844,14 +845,14 @@ public sealed partial class AdminVerbSystem { var allAccess = _prototypeManager .EnumeratePrototypes() - .Select(p => p.ID).ToArray(); + .Select(p => new ProtoId(p.ID)).ToArray(); _accessSystem.TrySetTags(entity, allAccess); } private void RevokeAllAccess(EntityUid entity) { - _accessSystem.TrySetTags(entity, Array.Empty()); + _accessSystem.TrySetTags(entity, new List>()); } public enum TricksVerbPriorities diff --git a/Content.Server/Advertise/Components/AdvertiseComponent.cs b/Content.Server/Advertise/Components/AdvertiseComponent.cs index 140bc6b902..531b31031d 100644 --- a/Content.Server/Advertise/Components/AdvertiseComponent.cs +++ b/Content.Server/Advertise/Components/AdvertiseComponent.cs @@ -1,7 +1,6 @@ using Content.Server.Advertise.EntitySystems; using Content.Shared.Advertise; using Robust.Shared.Prototypes; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; namespace Content.Server.Advertise.Components; @@ -37,9 +36,4 @@ public sealed partial class AdvertiseComponent : Component [DataField] public TimeSpan NextAdvertisementTime { get; set; } = TimeSpan.Zero; - /// - /// Whether the entity will say advertisements or not. - /// - [DataField] - public bool Enabled { get; set; } = true; } diff --git a/Content.Server/Advertise/EntitySystems/AdvertiseSystem.cs b/Content.Server/Advertise/EntitySystems/AdvertiseSystem.cs index bb254d11ef..12eac72cfe 100644 --- a/Content.Server/Advertise/EntitySystems/AdvertiseSystem.cs +++ b/Content.Server/Advertise/EntitySystems/AdvertiseSystem.cs @@ -23,115 +23,83 @@ public sealed class AdvertiseSystem : EntitySystem /// /// The next time the game will check if advertisements should be displayed /// - private TimeSpan _nextCheckTime = TimeSpan.MaxValue; + private TimeSpan _nextCheckTime = TimeSpan.MinValue; public override void Initialize() { SubscribeLocalEvent(OnMapInit); - SubscribeLocalEvent(OnPowerChanged); - SubscribeLocalEvent(OnPowerReceiverEnableChangeAttempt); - SubscribeLocalEvent(OnVendingEnableChangeAttempt); + SubscribeLocalEvent(OnPowerReceiverAttemptAdvertiseEvent); + SubscribeLocalEvent(OnVendingAttemptAdvertiseEvent); - // The component inits will lower this. - _nextCheckTime = TimeSpan.MaxValue; + _nextCheckTime = TimeSpan.MinValue; } - private void OnMapInit(EntityUid uid, AdvertiseComponent advertise, MapInitEvent args) + private void OnMapInit(EntityUid uid, AdvertiseComponent advert, MapInitEvent args) { - RefreshTimer(uid, advertise); + RandomizeNextAdvertTime(advert); + _nextCheckTime = MathHelper.Min(advert.NextAdvertisementTime, _nextCheckTime); } - private void OnPowerChanged(EntityUid uid, AdvertiseComponent advertise, ref PowerChangedEvent args) + private void RandomizeNextAdvertTime(AdvertiseComponent advert) { - SetEnabled(uid, args.Powered, advertise); - } - - public void RefreshTimer(EntityUid uid, AdvertiseComponent? advertise = null) - { - if (!Resolve(uid, ref advertise)) - return; - - if (!advertise.Enabled) - return; - - var minDuration = Math.Max(1, advertise.MinimumWait); - var maxDuration = Math.Max(minDuration, advertise.MaximumWait); + var minDuration = Math.Max(1, advert.MinimumWait); + var maxDuration = Math.Max(minDuration, advert.MaximumWait); var waitDuration = TimeSpan.FromSeconds(_random.Next(minDuration, maxDuration)); - var nextTime = _gameTiming.CurTime + waitDuration; - advertise.NextAdvertisementTime = nextTime; - - _nextCheckTime = MathHelper.Min(nextTime, _nextCheckTime); + advert.NextAdvertisementTime = _gameTiming.CurTime + waitDuration; } - public void SayAdvertisement(EntityUid uid, AdvertiseComponent? advertise = null) + public void SayAdvertisement(EntityUid uid, AdvertiseComponent? advert = null) { - if (!Resolve(uid, ref advertise)) + if (!Resolve(uid, ref advert)) return; - if (_prototypeManager.TryIndex(advertise.Pack, out var advertisements)) - _chat.TrySendInGameICMessage(uid, Loc.GetString(_random.Pick(advertisements.Messages)), InGameICChatType.Speak, hideChat: true); - } - - public void SetEnabled(EntityUid uid, bool enable, AdvertiseComponent? advertise = null) - { - if (!Resolve(uid, ref advertise)) - return; - - if (advertise.Enabled == enable) - return; - - var attemptEvent = new AdvertiseEnableChangeAttemptEvent(enable); - RaiseLocalEvent(uid, attemptEvent); - + var attemptEvent = new AttemptAdvertiseEvent(uid); + RaiseLocalEvent(uid, ref attemptEvent); if (attemptEvent.Cancelled) return; - advertise.Enabled = enable; - RefreshTimer(uid, advertise); - } - - private static void OnPowerReceiverEnableChangeAttempt(EntityUid uid, ApcPowerReceiverComponent component, AdvertiseEnableChangeAttemptEvent args) - { - if (args.Enabling && !component.Powered) - args.Cancel(); - } - - private static void OnVendingEnableChangeAttempt(EntityUid uid, VendingMachineComponent component, AdvertiseEnableChangeAttemptEvent args) - { - if (args.Enabling && component.Broken) - args.Cancel(); + if (_prototypeManager.TryIndex(advert.Pack, out var advertisements)) + _chat.TrySendInGameICMessage(uid, Loc.GetString(_random.Pick(advertisements.Messages)), InGameICChatType.Speak, hideChat: true); } public override void Update(float frameTime) { - var curTime = _gameTiming.CurTime; - if (_nextCheckTime > curTime) + var currentGameTime = _gameTiming.CurTime; + if (_nextCheckTime > currentGameTime) return; - _nextCheckTime = curTime + _maximumNextCheckDuration; + // _nextCheckTime starts at TimeSpan.MinValue, so this has to SET the value, not just increment it. + _nextCheckTime = currentGameTime + _maximumNextCheckDuration; var query = EntityQueryEnumerator(); while (query.MoveNext(out var uid, out var advert)) { - if (!advert.Enabled) - continue; - - // If this isn't advertising yet - if (advert.NextAdvertisementTime > curTime) + if (currentGameTime > advert.NextAdvertisementTime) { - _nextCheckTime = MathHelper.Min(advert.NextAdvertisementTime, _nextCheckTime); - continue; + SayAdvertisement(uid, advert); + // The timer is always refreshed when it expires, to prevent mass advertising (ex: all the vending machines have no power, and get it back at the same time). + RandomizeNextAdvertTime(advert); } - - SayAdvertisement(uid, advert); - RefreshTimer(uid, advert); + _nextCheckTime = MathHelper.Min(advert.NextAdvertisementTime, _nextCheckTime); } } + + + private static void OnPowerReceiverAttemptAdvertiseEvent(EntityUid uid, ApcPowerReceiverComponent powerReceiver, ref AttemptAdvertiseEvent args) + { + args.Cancelled |= !powerReceiver.Powered; + } + + private static void OnVendingAttemptAdvertiseEvent(EntityUid uid, VendingMachineComponent machine, ref AttemptAdvertiseEvent args) + { + args.Cancelled |= machine.Broken; + } } -public sealed class AdvertiseEnableChangeAttemptEvent(bool enabling) : CancellableEntityEventArgs +[ByRefEvent] +public record struct AttemptAdvertiseEvent(EntityUid? Advertiser) { - public bool Enabling { get; } = enabling; + public bool Cancelled = false; } diff --git a/Content.Server/Anomaly/AnomalySystem.Scanner.cs b/Content.Server/Anomaly/AnomalySystem.Scanner.cs index 74af8e67e3..bce508903d 100644 --- a/Content.Server/Anomaly/AnomalySystem.Scanner.cs +++ b/Content.Server/Anomaly/AnomalySystem.Scanner.cs @@ -1,4 +1,4 @@ -using Content.Server.Anomaly.Components; +using Content.Server.Anomaly.Components; using Content.Shared.Anomaly; using Content.Shared.Anomaly.Components; using Content.Shared.DoAfter; @@ -21,6 +21,7 @@ public sealed partial class AnomalySystem SubscribeLocalEvent(OnScannerAnomalySeverityChanged); SubscribeLocalEvent(OnScannerAnomalyHealthChanged); + SubscribeLocalEvent(OnScannerAnomalyBehaviorChanged); } private void OnScannerAnomalyShutdown(ref AnomalyShutdownEvent args) @@ -67,6 +68,17 @@ public sealed partial class AnomalySystem } } + private void OnScannerAnomalyBehaviorChanged(ref AnomalyBehaviorChangedEvent args) + { + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var component)) + { + if (component.ScannedAnomaly != args.Anomaly) + continue; + UpdateScannerUi(uid, component); + } + } + private void OnScannerUiOpened(EntityUid uid, AnomalyScannerComponent component, BoundUIOpenedEvent args) { UpdateScannerUi(uid, component); @@ -132,29 +144,95 @@ public sealed partial class AnomalySystem return msg; } - msg.AddMarkup(Loc.GetString("anomaly-scanner-severity-percentage", ("percent", anomalyComp.Severity.ToString("P")))); - msg.PushNewline(); - string stateLoc; - if (anomalyComp.Stability < anomalyComp.DecayThreshold) - stateLoc = Loc.GetString("anomaly-scanner-stability-low"); - else if (anomalyComp.Stability > anomalyComp.GrowthThreshold) - stateLoc = Loc.GetString("anomaly-scanner-stability-high"); + TryComp(anomaly, out var secret); + + //Severity + if (secret != null && secret.Secret.Contains(AnomalySecretData.Severity)) + msg.AddMarkup(Loc.GetString("anomaly-scanner-severity-percentage-unknown")); else - stateLoc = Loc.GetString("anomaly-scanner-stability-medium"); - msg.AddMarkup(stateLoc); + msg.AddMarkup(Loc.GetString("anomaly-scanner-severity-percentage", ("percent", anomalyComp.Severity.ToString("P")))); msg.PushNewline(); - msg.AddMarkup(Loc.GetString("anomaly-scanner-point-output", ("point", GetAnomalyPointValue(anomaly, anomalyComp)))); + //Stability + if (secret != null && secret.Secret.Contains(AnomalySecretData.Stability)) + msg.AddMarkup(Loc.GetString("anomaly-scanner-stability-unknown")); + else + { + string stateLoc; + if (anomalyComp.Stability < anomalyComp.DecayThreshold) + stateLoc = Loc.GetString("anomaly-scanner-stability-low"); + else if (anomalyComp.Stability > anomalyComp.GrowthThreshold) + stateLoc = Loc.GetString("anomaly-scanner-stability-high"); + else + stateLoc = Loc.GetString("anomaly-scanner-stability-medium"); + msg.AddMarkup(stateLoc); + } + msg.PushNewline(); + + //Point output + if (secret != null && secret.Secret.Contains(AnomalySecretData.OutputPoint)) + msg.AddMarkup(Loc.GetString("anomaly-scanner-point-output-unknown")); + else + msg.AddMarkup(Loc.GetString("anomaly-scanner-point-output", ("point", GetAnomalyPointValue(anomaly, anomalyComp)))); msg.PushNewline(); msg.PushNewline(); + //Particles title msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-readout")); msg.PushNewline(); - msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-danger", ("type", GetParticleLocale(anomalyComp.SeverityParticleType)))); + + //Danger + if (secret != null && secret.Secret.Contains(AnomalySecretData.ParticleDanger)) + msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-danger-unknown")); + else + msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-danger", ("type", GetParticleLocale(anomalyComp.SeverityParticleType)))); msg.PushNewline(); - msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-unstable", ("type", GetParticleLocale(anomalyComp.DestabilizingParticleType)))); + + //Unstable + if (secret != null && secret.Secret.Contains(AnomalySecretData.ParticleUnstable)) + msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-unstable-unknown")); + else + msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-unstable", ("type", GetParticleLocale(anomalyComp.DestabilizingParticleType)))); msg.PushNewline(); - msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-containment", ("type", GetParticleLocale(anomalyComp.WeakeningParticleType)))); + + //Containment + if (secret != null && secret.Secret.Contains(AnomalySecretData.ParticleContainment)) + msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-containment-unknown")); + else + msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-containment", ("type", GetParticleLocale(anomalyComp.WeakeningParticleType)))); + msg.PushNewline(); + + //Transformation + if (secret != null && secret.Secret.Contains(AnomalySecretData.ParticleTransformation)) + msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-transformation-unknown")); + else + msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-transformation", ("type", GetParticleLocale(anomalyComp.TransformationParticleType)))); + + + //Behavior + msg.PushNewline(); + msg.PushNewline(); + msg.AddMarkup(Loc.GetString("anomaly-behavior-title")); + msg.PushNewline(); + + if (secret != null && secret.Secret.Contains(AnomalySecretData.Behavior)) + msg.AddMarkup(Loc.GetString("anomaly-behavior-unknown")); + else + { + if (anomalyComp.CurrentBehavior != null) + { + var behavior = _prototype.Index(anomalyComp.CurrentBehavior.Value); + + msg.AddMarkup("- " + Loc.GetString(behavior.Description)); + msg.PushNewline(); + var mod = Math.Floor((behavior.EarnPointModifier) * 100); + msg.AddMarkup("- " + Loc.GetString("anomaly-behavior-point", ("mod", mod))); + } + else + { + msg.AddMarkup(Loc.GetString("anomaly-behavior-balanced")); + } + } //The timer at the end here is actually added in the ui itself. return msg; diff --git a/Content.Server/Anomaly/AnomalySystem.cs b/Content.Server/Anomaly/AnomalySystem.cs index c3f19aa177..bae101de87 100644 --- a/Content.Server/Anomaly/AnomalySystem.cs +++ b/Content.Server/Anomaly/AnomalySystem.cs @@ -8,13 +8,18 @@ using Content.Server.Radio.EntitySystems; using Content.Server.Station.Systems; using Content.Shared.Anomaly; using Content.Shared.Anomaly.Components; +using Content.Shared.Anomaly.Prototypes; using Content.Shared.DoAfter; +using Content.Shared.Random; +using Content.Shared.Random.Helpers; using Robust.Server.GameObjects; using Robust.Shared.Audio.Systems; using Robust.Shared.Configuration; using Robust.Shared.Physics.Events; using Robust.Shared.Prototypes; using Robust.Shared.Random; +using Robust.Shared.Serialization.Manager; +using System.Linq; namespace Content.Server.Anomaly; @@ -33,13 +38,20 @@ public sealed partial class AnomalySystem : SharedAnomalySystem [Dependency] private readonly SharedPointLightSystem _pointLight = default!; [Dependency] private readonly StationSystem _station = default!; [Dependency] private readonly RadioSystem _radio = default!; + [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly RadiationSystem _radiation = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly UserInterfaceSystem _ui = default!; + [Dependency] private readonly IComponentFactory _componentFactory = default!; + [Dependency] private readonly ISerializationManager _serialization = default!; + [Dependency] private readonly IEntityManager _entity = default!; public const float MinParticleVariation = 0.8f; public const float MaxParticleVariation = 1.2f; + [ValidatePrototypeId] + const string WeightListProto = "AnomalyBehaviorList"; + /// public override void Initialize() { @@ -54,25 +66,34 @@ public sealed partial class AnomalySystem : SharedAnomalySystem InitializeCommands(); } - private void OnMapInit(EntityUid uid, AnomalyComponent component, MapInitEvent args) + private void OnMapInit(Entity anomaly, ref MapInitEvent args) { - component.NextPulseTime = Timing.CurTime + GetPulseLength(component) * 3; // longer the first time - ChangeAnomalyStability(uid, Random.NextFloat(component.InitialStabilityRange.Item1 , component.InitialStabilityRange.Item2), component); - ChangeAnomalySeverity(uid, Random.NextFloat(component.InitialSeverityRange.Item1, component.InitialSeverityRange.Item2), component); + anomaly.Comp.NextPulseTime = Timing.CurTime + GetPulseLength(anomaly.Comp) * 3; // longer the first time + ChangeAnomalyStability(anomaly, Random.NextFloat(anomaly.Comp.InitialStabilityRange.Item1 , anomaly.Comp.InitialStabilityRange.Item2), anomaly.Comp); + ChangeAnomalySeverity(anomaly, Random.NextFloat(anomaly.Comp.InitialSeverityRange.Item1, anomaly.Comp.InitialSeverityRange.Item2), anomaly.Comp); + ShuffleParticlesEffect(anomaly.Comp); + anomaly.Comp.Continuity = _random.NextFloat(anomaly.Comp.MinContituty, anomaly.Comp.MaxContituty); + SetBehavior(anomaly, GetRandomBehavior()); + } + + public void ShuffleParticlesEffect(AnomalyComponent anomaly) + { var particles = new List - { AnomalousParticleType.Delta, AnomalousParticleType.Epsilon, AnomalousParticleType.Zeta }; - component.SeverityParticleType = Random.PickAndTake(particles); - component.DestabilizingParticleType = Random.PickAndTake(particles); - component.WeakeningParticleType = Random.PickAndTake(particles); + { AnomalousParticleType.Delta, AnomalousParticleType.Epsilon, AnomalousParticleType.Zeta, AnomalousParticleType.Sigma }; + + anomaly.SeverityParticleType = Random.PickAndTake(particles); + anomaly.DestabilizingParticleType = Random.PickAndTake(particles); + anomaly.WeakeningParticleType = Random.PickAndTake(particles); + anomaly.TransformationParticleType = Random.PickAndTake(particles); } - private void OnShutdown(EntityUid uid, AnomalyComponent component, ComponentShutdown args) + private void OnShutdown(Entity anomaly, ref ComponentShutdown args) { - EndAnomaly(uid, component); + EndAnomaly(anomaly); } - private void OnStartCollide(EntityUid uid, AnomalyComponent component, ref StartCollideEvent args) + private void OnStartCollide(Entity anomaly, ref StartCollideEvent args) { if (!TryComp(args.OtherEntity, out var particle)) return; @@ -80,21 +101,33 @@ public sealed partial class AnomalySystem : SharedAnomalySystem if (args.OtherFixtureId != particle.FixtureId) return; + var behaviorMod = 1f; + if (anomaly.Comp.CurrentBehavior != null) + { + var b = _prototype.Index(anomaly.Comp.CurrentBehavior.Value); + behaviorMod = b.ParticleSensivity; + } // small function to randomize because it's easier to read like this - float VaryValue(float v) => v * Random.NextFloat(MinParticleVariation, MaxParticleVariation); + float VaryValue(float v) => v * behaviorMod * Random.NextFloat(MinParticleVariation, MaxParticleVariation); - if (particle.ParticleType == component.DestabilizingParticleType || particle.DestabilzingOverride) + if (particle.ParticleType == anomaly.Comp.DestabilizingParticleType || particle.DestabilzingOverride) { - ChangeAnomalyStability(uid, VaryValue(particle.StabilityPerDestabilizingHit), component); + ChangeAnomalyStability(anomaly, VaryValue(particle.StabilityPerDestabilizingHit), anomaly.Comp); } - if (particle.ParticleType == component.SeverityParticleType || particle.SeverityOverride) + if (particle.ParticleType == anomaly.Comp.SeverityParticleType || particle.SeverityOverride) { - ChangeAnomalySeverity(uid, VaryValue(particle.SeverityPerSeverityHit), component); + ChangeAnomalySeverity(anomaly, VaryValue(particle.SeverityPerSeverityHit), anomaly.Comp); } - if (particle.ParticleType == component.WeakeningParticleType || particle.WeakeningOverride) + if (particle.ParticleType == anomaly.Comp.WeakeningParticleType || particle.WeakeningOverride) { - ChangeAnomalyHealth(uid, VaryValue(particle.HealthPerWeakeningeHit), component); - ChangeAnomalyStability(uid, VaryValue(particle.StabilityPerWeakeningeHit), component); + ChangeAnomalyHealth(anomaly, VaryValue(particle.HealthPerWeakeningeHit), anomaly.Comp); + ChangeAnomalyStability(anomaly, VaryValue(particle.StabilityPerWeakeningeHit), anomaly.Comp); + } + if (particle.ParticleType == anomaly.Comp.TransformationParticleType || particle.TransmutationOverride) + { + ChangeAnomalySeverity(anomaly, VaryValue(particle.SeverityPerSeverityHit), anomaly.Comp); + if (_random.Prob(anomaly.Comp.Continuity)) + SetBehavior(anomaly, GetRandomBehavior()); } } @@ -116,6 +149,13 @@ public sealed partial class AnomalySystem : SharedAnomalySystem //penalty of up to 50% based on health multiplier *= MathF.Pow(1.5f, component.Health) - 0.5f; + //Apply behavior modifier + if (component.CurrentBehavior != null) + { + var behavior = _prototype.Index(component.CurrentBehavior.Value); + multiplier *= behavior.EarnPointModifier; + } + var severityValue = 1 / (1 + MathF.Pow(MathF.E, -7 * (component.Severity - 0.5f))); return (int) ((component.MaxPointsPerSecond - component.MinPointsPerSecond) * severityValue * multiplier) + component.MinPointsPerSecond; @@ -133,6 +173,7 @@ public sealed partial class AnomalySystem : SharedAnomalySystem AnomalousParticleType.Delta => Loc.GetString("anomaly-particles-delta"), AnomalousParticleType.Epsilon => Loc.GetString("anomaly-particles-epsilon"), AnomalousParticleType.Zeta => Loc.GetString("anomaly-particles-zeta"), + AnomalousParticleType.Sigma => Loc.GetString("anomaly-particles-sigma"), _ => throw new ArgumentOutOfRangeException() }; } @@ -144,4 +185,40 @@ public sealed partial class AnomalySystem : SharedAnomalySystem UpdateGenerator(); UpdateVessels(); } + + #region Behavior + private string GetRandomBehavior() + { + var weightList = _prototype.Index(WeightListProto); + return weightList.Pick(_random); + } + + private void SetBehavior(Entity anomaly, ProtoId behaviorProto) + { + if (anomaly.Comp.CurrentBehavior == behaviorProto) + return; + + if (anomaly.Comp.CurrentBehavior != null) + RemoveBehavior(anomaly, anomaly.Comp.CurrentBehavior.Value); + + //event broadcast + var ev = new AnomalyBehaviorChangedEvent(anomaly, anomaly.Comp.CurrentBehavior, behaviorProto); + anomaly.Comp.CurrentBehavior = behaviorProto; + RaiseLocalEvent(anomaly, ref ev, true); + + var behavior = _prototype.Index(behaviorProto); + + EntityManager.AddComponents(anomaly, behavior.Components); + } + + private void RemoveBehavior(Entity anomaly, ProtoId behaviorProto) + { + if (anomaly.Comp.CurrentBehavior == null) + return; + + var behavior = _prototype.Index(anomaly.Comp.CurrentBehavior.Value); + + EntityManager.RemoveComponents(anomaly, behavior.Components); + } + #endregion } diff --git a/Content.Server/Anomaly/Components/AnomalousParticleComponent.cs b/Content.Server/Anomaly/Components/AnomalousParticleComponent.cs index 9141ca6529..5b05522bb9 100644 --- a/Content.Server/Anomaly/Components/AnomalousParticleComponent.cs +++ b/Content.Server/Anomaly/Components/AnomalousParticleComponent.cs @@ -13,58 +13,64 @@ public sealed partial class AnomalousParticleComponent : Component /// The type of particle that the projectile /// imbues onto the anomaly on contact. /// - [DataField("particleType", required: true)] + [DataField(required: true)] public AnomalousParticleType ParticleType; /// /// The fixture that's checked on collision. /// - [DataField("fixtureId")] + [DataField] public string FixtureId = "projectile"; /// /// The amount that the increases by when hit /// of an anomalous particle of . /// - [DataField("severityPerSeverityHit")] + [DataField] public float SeverityPerSeverityHit = 0.025f; /// /// The amount that the increases by when hit /// of an anomalous particle of . /// - [DataField("stabilityPerDestabilizingHit")] + [DataField] public float StabilityPerDestabilizingHit = 0.04f; /// /// The amount that the increases by when hit /// of an anomalous particle of . /// - [DataField("healthPerWeakeningeHit")] + [DataField] public float HealthPerWeakeningeHit = -0.05f; /// /// The amount that the increases by when hit /// of an anomalous particle of . /// - [DataField("stabilityPerWeakeningeHit")] + [DataField] public float StabilityPerWeakeningeHit = -0.1f; /// /// If this is true then the particle will always affect the stability of the anomaly. /// - [DataField("destabilzingOverride")] + [DataField] public bool DestabilzingOverride = false; /// /// If this is true then the particle will always affect the weakeness of the anomaly. /// - [DataField("weakeningOverride")] + [DataField] public bool WeakeningOverride = false; /// /// If this is true then the particle will always affect the severity of the anomaly. /// - [DataField("severityOverride")] + [DataField] public bool SeverityOverride = false; + + /// + /// If this is true then the particle will always affect the behaviour. + /// + [DataField] + public bool TransmutationOverride = false; } diff --git a/Content.Server/Anomaly/Components/SecretDataAnomalyComponent.cs b/Content.Server/Anomaly/Components/SecretDataAnomalyComponent.cs new file mode 100644 index 0000000000..80eecaafc7 --- /dev/null +++ b/Content.Server/Anomaly/Components/SecretDataAnomalyComponent.cs @@ -0,0 +1,45 @@ +using Content.Server.Anomaly.Effects; + +namespace Content.Server.Anomaly.Components; + +/// +/// Hides some information about the anomaly when scanning it +/// +[RegisterComponent, Access(typeof(SecretDataAnomalySystem), typeof(AnomalySystem))] +public sealed partial class SecretDataAnomalyComponent : Component +{ + /// + /// Minimum hidden data elements on MapInit + /// + [DataField] + public int RandomStartSecretMin = 0; + + /// + /// Maximum hidden data elements on MapInit + /// + [DataField] + public int RandomStartSecretMax = 0; + + /// + /// Current secret data + /// + [DataField] + public List Secret = new(); +} + +/// +/// Enum with secret data field variants +/// +[Serializable] +public enum AnomalySecretData : byte +{ + Severity, + Stability, + OutputPoint, + ParticleDanger, + ParticleUnstable, + ParticleContainment, + ParticleTransformation, + Behavior, + Default +} diff --git a/Content.Server/Anomaly/Components/ShuffleParticlesAnomalyComponent.cs b/Content.Server/Anomaly/Components/ShuffleParticlesAnomalyComponent.cs new file mode 100644 index 0000000000..00db76d486 --- /dev/null +++ b/Content.Server/Anomaly/Components/ShuffleParticlesAnomalyComponent.cs @@ -0,0 +1,28 @@ +using Content.Server.Anomaly.Effects; + +namespace Content.Server.Anomaly.Components; + +/// +/// Shuffle Particle types in some situations +/// +[RegisterComponent, Access(typeof(ShuffleParticlesAnomalySystem))] +public sealed partial class ShuffleParticlesAnomalyComponent : Component +{ + /// + /// Prob() chance to randomize particle types after Anomaly pulation + /// + [DataField] + public bool ShuffleOnPulse = false; + + /// + /// Prob() chance to randomize particle types after APE or CHIMP projectile + /// + [DataField] + public bool ShuffleOnParticleHit = false; + + /// + /// Chance to random particles + /// + [DataField] + public float Prob = 0.5f; +} diff --git a/Content.Server/Anomaly/Effects/BluespaceAnomalySystem.cs b/Content.Server/Anomaly/Effects/BluespaceAnomalySystem.cs index dd2da82c9d..bd8c2f3c7d 100644 --- a/Content.Server/Anomaly/Effects/BluespaceAnomalySystem.cs +++ b/Content.Server/Anomaly/Effects/BluespaceAnomalySystem.cs @@ -1,4 +1,4 @@ -using System.Linq; +using System.Linq; using System.Numerics; using Content.Server.Anomaly.Components; using Content.Shared.Administration.Logs; @@ -33,7 +33,7 @@ public sealed class BluespaceAnomalySystem : EntitySystem { var xformQuery = GetEntityQuery(); var xform = xformQuery.GetComponent(uid); - var range = component.MaxShuffleRadius * args.Severity; + var range = component.MaxShuffleRadius * args.Severity * args.PowerModifier; var mobs = new HashSet>(); _lookup.GetEntitiesInRange(xform.Coordinates, range, mobs); var allEnts = new ValueList(mobs.Select(m => m.Owner)) { uid }; @@ -56,7 +56,7 @@ public sealed class BluespaceAnomalySystem : EntitySystem { var xform = Transform(uid); var mapPos = _xform.GetWorldPosition(xform); - var radius = component.SupercriticalTeleportRadius; + var radius = component.SupercriticalTeleportRadius * args.PowerModifier; var gridBounds = new Box2(mapPos - new Vector2(radius, radius), mapPos + new Vector2(radius, radius)); var mobs = new HashSet>(); _lookup.GetEntitiesInRange(xform.Coordinates, component.MaxShuffleRadius, mobs); diff --git a/Content.Server/Anomaly/Effects/ElectricityAnomalySystem.cs b/Content.Server/Anomaly/Effects/ElectricityAnomalySystem.cs index 8b5a72449f..f2a060d629 100644 --- a/Content.Server/Anomaly/Effects/ElectricityAnomalySystem.cs +++ b/Content.Server/Anomaly/Effects/ElectricityAnomalySystem.cs @@ -28,7 +28,7 @@ public sealed class ElectricityAnomalySystem : EntitySystem private void OnPulse(Entity anomaly, ref AnomalyPulseEvent args) { - var range = anomaly.Comp.MaxElectrocuteRange * args.Stability; + var range = anomaly.Comp.MaxElectrocuteRange * args.Stability * args.PowerModifier; int boltCount = (int)MathF.Floor(MathHelper.Lerp((float)anomaly.Comp.MinBoltCount, (float)anomaly.Comp.MaxBoltCount, args.Severity)); @@ -37,7 +37,7 @@ public sealed class ElectricityAnomalySystem : EntitySystem private void OnSupercritical(Entity anomaly, ref AnomalySupercriticalEvent args) { - var range = anomaly.Comp.MaxElectrocuteRange * 3; + var range = anomaly.Comp.MaxElectrocuteRange * 3 * args.PowerModifier; _emp.EmpPulse(_transform.GetMapCoordinates(anomaly), range, anomaly.Comp.EmpEnergyConsumption, anomaly.Comp.EmpDisabledDuration); _lightning.ShootRandomLightnings(anomaly, range, anomaly.Comp.MaxBoltCount * 3, arcDepth: 3); diff --git a/Content.Server/Anomaly/Effects/EntityAnomalySystem.cs b/Content.Server/Anomaly/Effects/EntityAnomalySystem.cs index 90a655fbba..86d6937af5 100644 --- a/Content.Server/Anomaly/Effects/EntityAnomalySystem.cs +++ b/Content.Server/Anomaly/Effects/EntityAnomalySystem.cs @@ -35,7 +35,7 @@ public sealed class EntityAnomalySystem : SharedEntityAnomalySystem if (!entry.Settings.SpawnOnPulse) continue; - SpawnEntities(component, entry, args.Stability, args.Severity); + SpawnEntities(component, entry, args.Stability, args.Severity, args.PowerModifier); } } @@ -46,7 +46,7 @@ public sealed class EntityAnomalySystem : SharedEntityAnomalySystem if (!entry.Settings.SpawnOnSuperCritical) continue; - SpawnEntities(component, entry, 1, 1); + SpawnEntities(component, entry, 1, 1, args.PowerModifier); } } @@ -57,7 +57,7 @@ public sealed class EntityAnomalySystem : SharedEntityAnomalySystem if (!entry.Settings.SpawnOnShutdown || args.Supercritical) continue; - SpawnEntities(component, entry, 1, 1); + SpawnEntities(component, entry, 1, 1, 1); } } @@ -68,7 +68,7 @@ public sealed class EntityAnomalySystem : SharedEntityAnomalySystem if (!entry.Settings.SpawnOnStabilityChanged) continue; - SpawnEntities(component, entry, args.Stability, args.Severity); + SpawnEntities(component, entry, args.Stability, args.Severity, 1); } } @@ -79,17 +79,17 @@ public sealed class EntityAnomalySystem : SharedEntityAnomalySystem if (!entry.Settings.SpawnOnSeverityChanged) continue; - SpawnEntities(component, entry, args.Stability, args.Severity); + SpawnEntities(component, entry, args.Stability, args.Severity, 1); } } - private void SpawnEntities(Entity anomaly, EntitySpawnSettingsEntry entry, float stability, float severity) + private void SpawnEntities(Entity anomaly, EntitySpawnSettingsEntry entry, float stability, float severity, float powerMod) { var xform = Transform(anomaly); if (!TryComp(xform.GridUid, out MapGridComponent? grid)) return; - var tiles = _anomaly.GetSpawningPoints(anomaly, stability, severity, entry.Settings); + var tiles = _anomaly.GetSpawningPoints(anomaly, stability, severity, entry.Settings, powerMod); if (tiles == null) return; diff --git a/Content.Server/Anomaly/Effects/InjectionAnomalySystem.cs b/Content.Server/Anomaly/Effects/InjectionAnomalySystem.cs index 2bef32e322..731d853280 100644 --- a/Content.Server/Anomaly/Effects/InjectionAnomalySystem.cs +++ b/Content.Server/Anomaly/Effects/InjectionAnomalySystem.cs @@ -29,12 +29,12 @@ public sealed class InjectionAnomalySystem : EntitySystem private void OnPulse(Entity entity, ref AnomalyPulseEvent args) { - PulseScalableEffect(entity, entity.Comp.InjectRadius, entity.Comp.MaxSolutionInjection * args.Severity); + PulseScalableEffect(entity, entity.Comp.InjectRadius * args.PowerModifier, entity.Comp.MaxSolutionInjection * args.Severity * args.PowerModifier); } private void OnSupercritical(Entity entity, ref AnomalySupercriticalEvent args) { - PulseScalableEffect(entity, entity.Comp.SuperCriticalInjectRadius, entity.Comp.SuperCriticalSolutionInjection); + PulseScalableEffect(entity, entity.Comp.SuperCriticalInjectRadius * args.PowerModifier, entity.Comp.SuperCriticalSolutionInjection * args.PowerModifier); } private void PulseScalableEffect(Entity entity, float injectRadius, float maxInject) diff --git a/Content.Server/Anomaly/Effects/ProjectileAnomalySystem.cs b/Content.Server/Anomaly/Effects/ProjectileAnomalySystem.cs index 8483c86dbb..23e0e472f0 100644 --- a/Content.Server/Anomaly/Effects/ProjectileAnomalySystem.cs +++ b/Content.Server/Anomaly/Effects/ProjectileAnomalySystem.cs @@ -31,12 +31,12 @@ public sealed class ProjectileAnomalySystem : EntitySystem private void OnPulse(EntityUid uid, ProjectileAnomalyComponent component, ref AnomalyPulseEvent args) { - ShootProjectilesAtEntities(uid, component, args.Severity); + ShootProjectilesAtEntities(uid, component, args.Severity * args.PowerModifier); } private void OnSupercritical(EntityUid uid, ProjectileAnomalyComponent component, ref AnomalySupercriticalEvent args) { - ShootProjectilesAtEntities(uid, component, 1.0f); + ShootProjectilesAtEntities(uid, component, args.PowerModifier); } private void ShootProjectilesAtEntities(EntityUid uid, ProjectileAnomalyComponent component, float severity) diff --git a/Content.Server/Anomaly/Effects/PuddleCreateAnomalySystem.cs b/Content.Server/Anomaly/Effects/PuddleCreateAnomalySystem.cs index 90177bae8e..d460e6f4b0 100644 --- a/Content.Server/Anomaly/Effects/PuddleCreateAnomalySystem.cs +++ b/Content.Server/Anomaly/Effects/PuddleCreateAnomalySystem.cs @@ -25,9 +25,10 @@ public sealed class PuddleCreateAnomalySystem : EntitySystem return; var xform = Transform(entity.Owner); - var puddleSol = _solutionContainer.SplitSolution(sol.Value, entity.Comp.MaxPuddleSize * args.Severity); + var puddleSol = _solutionContainer.SplitSolution(sol.Value, entity.Comp.MaxPuddleSize * args.Severity * args.PowerModifier); _puddle.TrySplashSpillAt(entity.Owner, xform.Coordinates, puddleSol, out _); } + private void OnSupercritical(Entity entity, ref AnomalySupercriticalEvent args) { if (!_solutionContainer.TryGetSolution(entity.Owner, entity.Comp.Solution, out _, out var sol)) diff --git a/Content.Server/Anomaly/Effects/PyroclasticAnomalySystem.cs b/Content.Server/Anomaly/Effects/PyroclasticAnomalySystem.cs index 6bd8be002e..d38bda562b 100644 --- a/Content.Server/Anomaly/Effects/PyroclasticAnomalySystem.cs +++ b/Content.Server/Anomaly/Effects/PyroclasticAnomalySystem.cs @@ -1,4 +1,4 @@ -using Content.Server.Atmos.Components; +using Content.Server.Atmos.Components; using Content.Server.Atmos.EntitySystems; using Content.Shared.Anomaly.Components; using Content.Shared.Anomaly.Effects.Components; @@ -24,14 +24,14 @@ public sealed class PyroclasticAnomalySystem : EntitySystem private void OnPulse(EntityUid uid, PyroclasticAnomalyComponent component, ref AnomalyPulseEvent args) { var xform = Transform(uid); - var ignitionRadius = component.MaximumIgnitionRadius * args.Stability; + var ignitionRadius = component.MaximumIgnitionRadius * args.Stability * args.PowerModifier; IgniteNearby(uid, xform.Coordinates, args.Severity, ignitionRadius); } private void OnSupercritical(EntityUid uid, PyroclasticAnomalyComponent component, ref AnomalySupercriticalEvent args) { var xform = Transform(uid); - IgniteNearby(uid, xform.Coordinates, 1, component.MaximumIgnitionRadius * 2); + IgniteNearby(uid, xform.Coordinates, 1, component.MaximumIgnitionRadius * 2 * args.PowerModifier); } public void IgniteNearby(EntityUid uid, EntityCoordinates coordinates, float severity, float radius) diff --git a/Content.Server/Anomaly/Effects/SecretDataAnomalySystem.cs b/Content.Server/Anomaly/Effects/SecretDataAnomalySystem.cs new file mode 100644 index 0000000000..cbdc4b04df --- /dev/null +++ b/Content.Server/Anomaly/Effects/SecretDataAnomalySystem.cs @@ -0,0 +1,40 @@ +using Content.Server.Anomaly.Components; +using Robust.Shared.Random; + +namespace Content.Server.Anomaly.Effects; + +public sealed class SecretDataAnomalySystem : EntitySystem +{ + [Dependency] private readonly IRobustRandom _random = default!; + + private readonly List _deita = new(); + + public override void Initialize() + { + SubscribeLocalEvent(OnMapInit); + } + + private void OnMapInit(EntityUid uid, SecretDataAnomalyComponent anomaly, MapInitEvent args) + { + RandomizeSecret(uid,_random.Next(anomaly.RandomStartSecretMin, anomaly.RandomStartSecretMax), anomaly); + } + + public void RandomizeSecret(EntityUid uid, int count, SecretDataAnomalyComponent? component = null) + { + if (!Resolve(uid, ref component)) + return; + + component.Secret.Clear(); + + // I also considered just adding all the enum values and pruning but that seems more wasteful. + _deita.Clear(); + _deita.AddRange(Enum.GetValues()); + var actualCount = Math.Min(count, _deita.Count); + + for (int i = 0; i < actualCount; i++) + { + component.Secret.Add(_random.PickAndTake(_deita)); + } + } +} + diff --git a/Content.Server/Anomaly/Effects/ShuffleParticlesAnomalySystem.cs b/Content.Server/Anomaly/Effects/ShuffleParticlesAnomalySystem.cs new file mode 100644 index 0000000000..7d4d9a2ee5 --- /dev/null +++ b/Content.Server/Anomaly/Effects/ShuffleParticlesAnomalySystem.cs @@ -0,0 +1,41 @@ +using Content.Server.Anomaly.Components; +using Content.Shared.Anomaly.Components; +using Robust.Shared.Physics.Events; +using Robust.Shared.Random; + +namespace Content.Server.Anomaly.Effects; +public sealed class ShuffleParticlesAnomalySystem : EntitySystem +{ + [Dependency] private readonly AnomalySystem _anomaly = default!; + [Dependency] private readonly IRobustRandom _random = default!; + + public override void Initialize() + { + SubscribeLocalEvent(OnPulse); + SubscribeLocalEvent(OnStartCollide); + } + + private void OnStartCollide(EntityUid uid, ShuffleParticlesAnomalyComponent shuffle, StartCollideEvent args) + { + if (!TryComp(uid, out var anomaly)) + return; + + if (shuffle.ShuffleOnParticleHit && _random.Prob(shuffle.Prob)) + _anomaly.ShuffleParticlesEffect(anomaly); + + if (!TryComp(args.OtherEntity, out var particle)) + return; + } + + private void OnPulse(EntityUid uid, ShuffleParticlesAnomalyComponent shuffle, AnomalyPulseEvent args) + { + if (!TryComp(uid, out var anomaly)) + return; + + if (shuffle.ShuffleOnPulse && _random.Prob(shuffle.Prob)) + { + _anomaly.ShuffleParticlesEffect(anomaly); + } + } +} + diff --git a/Content.Server/Anomaly/Effects/TileAnomalySystem.cs b/Content.Server/Anomaly/Effects/TileAnomalySystem.cs index c1487cfc8c..92f5415252 100644 --- a/Content.Server/Anomaly/Effects/TileAnomalySystem.cs +++ b/Content.Server/Anomaly/Effects/TileAnomalySystem.cs @@ -34,7 +34,7 @@ public sealed class TileAnomalySystem : SharedTileAnomalySystem if (!entry.Settings.SpawnOnPulse) continue; - SpawnTiles(component, entry, args.Stability, args.Severity); + SpawnTiles(component, entry, args.Stability, args.Severity, args.PowerModifier); } } @@ -45,7 +45,7 @@ public sealed class TileAnomalySystem : SharedTileAnomalySystem if (!entry.Settings.SpawnOnSuperCritical) continue; - SpawnTiles(component, entry, 1, 1); + SpawnTiles(component, entry, 1, 1, args.PowerModifier); } } @@ -56,7 +56,7 @@ public sealed class TileAnomalySystem : SharedTileAnomalySystem if (!entry.Settings.SpawnOnShutdown || args.Supercritical) continue; - SpawnTiles(component, entry, 1, 1); + SpawnTiles(component, entry, 1, 1, 1); } } @@ -67,7 +67,7 @@ public sealed class TileAnomalySystem : SharedTileAnomalySystem if (!entry.Settings.SpawnOnStabilityChanged) continue; - SpawnTiles(component, entry, args.Stability, args.Severity); + SpawnTiles(component, entry, args.Stability, args.Severity, 1); } } @@ -78,17 +78,17 @@ public sealed class TileAnomalySystem : SharedTileAnomalySystem if (!entry.Settings.SpawnOnSeverityChanged) continue; - SpawnTiles(component, entry, args.Stability, args.Severity); + SpawnTiles(component, entry, args.Stability, args.Severity, 1); } } - private void SpawnTiles(Entity anomaly, TileSpawnSettingsEntry entry, float stability, float severity) + private void SpawnTiles(Entity anomaly, TileSpawnSettingsEntry entry, float stability, float severity, float powerMod) { var xform = Transform(anomaly); if (!TryComp(xform.GridUid, out var grid)) return; - var tiles = _anomaly.GetSpawningPoints(anomaly, stability, severity, entry.Settings); + var tiles = _anomaly.GetSpawningPoints(anomaly, stability, severity, entry.Settings, powerMod); if (tiles == null) return; diff --git a/Content.Server/Atmos/EntitySystems/GasTileOverlaySystem.cs b/Content.Server/Atmos/EntitySystems/GasTileOverlaySystem.cs index c42cfd08da..89b9c52078 100644 --- a/Content.Server/Atmos/EntitySystems/GasTileOverlaySystem.cs +++ b/Content.Server/Atmos/EntitySystems/GasTileOverlaySystem.cs @@ -432,14 +432,16 @@ namespace Content.Server.Atmos.EntitySystems if (!overlay.Chunks.TryGetValue(gIndex, out var value)) continue; - if (previousChunks != null && - previousChunks.Contains(gIndex) && - value.LastUpdate > LastSessionUpdate) + // If the chunk was updated since we last sent it, send it again + if (value.LastUpdate > LastSessionUpdate) { + dataToSend.Add(value); continue; } - dataToSend.Add(value); + // Always send it if we didn't previously send it + if (previousChunks == null || !previousChunks.Contains(gIndex)) + dataToSend.Add(value); } previouslySent[netGrid] = gridChunks; diff --git a/Content.Server/Atmos/Piping/Trinary/EntitySystems/GasFilterSystem.cs b/Content.Server/Atmos/Piping/Trinary/EntitySystems/GasFilterSystem.cs index f856946a92..fbd4260469 100644 --- a/Content.Server/Atmos/Piping/Trinary/EntitySystems/GasFilterSystem.cs +++ b/Content.Server/Atmos/Piping/Trinary/EntitySystems/GasFilterSystem.cs @@ -53,7 +53,7 @@ namespace Content.Server.Atmos.Piping.Trinary.EntitySystems private void OnFilterUpdated(EntityUid uid, GasFilterComponent filter, ref AtmosDeviceUpdateEvent args) { if (!filter.Enabled - || !_nodeContainer.TryGetNodes(uid, filter.InletName, filter.OutletName, filter.FilterName, out PipeNode? inletNode, out PipeNode? filterNode, out PipeNode? outletNode) + || !_nodeContainer.TryGetNodes(uid, filter.InletName, filter.FilterName, filter.OutletName, out PipeNode? inletNode, out PipeNode? filterNode, out PipeNode? outletNode) || outletNode.Air.Pressure >= Atmospherics.MaxOutputPressure) // No need to transfer if target is full. { _ambientSoundSystem.SetAmbience(uid, false); diff --git a/Content.Server/Chemistry/Components/BaseSolutionInjectOnEventComponent.cs b/Content.Server/Chemistry/Components/BaseSolutionInjectOnEventComponent.cs new file mode 100644 index 0000000000..708c1ef005 --- /dev/null +++ b/Content.Server/Chemistry/Components/BaseSolutionInjectOnEventComponent.cs @@ -0,0 +1,60 @@ +using Content.Shared.FixedPoint; +using Content.Shared.Inventory; + +namespace Content.Server.Chemistry.Components; + +/// +/// Base class for components that inject a solution into a target's bloodstream in response to an event. +/// +public abstract partial class BaseSolutionInjectOnEventComponent : Component +{ + /// + /// How much solution to remove from this entity per target when transferring. + /// + /// + /// Note that this amount is per target, so the total amount removed will be + /// multiplied by the number of targets hit. + /// + [DataField] + public FixedPoint2 TransferAmount = FixedPoint2.New(1); + + [ViewVariables(VVAccess.ReadWrite)] + public float TransferEfficiency { get => _transferEfficiency; set => _transferEfficiency = Math.Clamp(value, 0, 1); } + + /// + /// Proportion of the that will actually be injected + /// into the target's bloodstream. The rest is lost. + /// 0 means none of the transferred solution will enter the bloodstream. + /// 1 means the entire amount will enter the bloodstream. + /// + [DataField("transferEfficiency")] + private float _transferEfficiency = 1f; + + /// + /// Solution to inject from. + /// + [DataField] + public string Solution = "default"; + + /// + /// Whether this will inject through hardsuits or not. + /// + [DataField] + public bool PierceArmor = true; + + /// + /// Contents of popup message to display to the attacker when injection + /// fails due to the target wearing a hardsuit. + /// + /// + /// Passed values: $weapon and $target + /// + [DataField] + public LocId BlockedByHardsuitPopupMessage = "melee-inject-failed-hardsuit"; + + /// + /// If anything covers any of these slots then the injection fails. + /// + [DataField] + public SlotFlags BlockSlots = SlotFlags.NONE; +} diff --git a/Content.Server/Chemistry/Components/MeleeChemicalInjectorComponent.cs b/Content.Server/Chemistry/Components/MeleeChemicalInjectorComponent.cs index 6b6ce830a9..6b64b82f78 100644 --- a/Content.Server/Chemistry/Components/MeleeChemicalInjectorComponent.cs +++ b/Content.Server/Chemistry/Components/MeleeChemicalInjectorComponent.cs @@ -1,31 +1,8 @@ -using Content.Shared.FixedPoint; +namespace Content.Server.Chemistry.Components; -namespace Content.Server.Chemistry.Components -{ - [RegisterComponent] - public sealed partial class MeleeChemicalInjectorComponent : Component - { - [ViewVariables(VVAccess.ReadWrite)] - [DataField("transferAmount")] - public FixedPoint2 TransferAmount { get; set; } = FixedPoint2.New(1); - - [ViewVariables(VVAccess.ReadWrite)] - public float TransferEfficiency { get => _transferEfficiency; set => _transferEfficiency = Math.Clamp(value, 0, 1); } - - [DataField("transferEfficiency")] - private float _transferEfficiency = 1f; - - /// - /// Whether this will inject through hardsuits or not. - /// - [DataField("pierceArmor"), ViewVariables(VVAccess.ReadWrite)] - public bool PierceArmor = true; - - /// - /// Solution to inject from. - /// - [ViewVariables(VVAccess.ReadWrite)] - [DataField("solution")] - public string Solution { get; set; } = "default"; - } -} +/// +/// Used for melee weapon entities that should try to inject a +/// contained solution into a target when used to hit it. +/// +[RegisterComponent] +public sealed partial class MeleeChemicalInjectorComponent : BaseSolutionInjectOnEventComponent { } diff --git a/Content.Server/Chemistry/Components/SolutionInjectOnCollideComponent.cs b/Content.Server/Chemistry/Components/SolutionInjectOnCollideComponent.cs deleted file mode 100644 index 76bb5294bc..0000000000 --- a/Content.Server/Chemistry/Components/SolutionInjectOnCollideComponent.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Content.Shared.FixedPoint; -using Content.Shared.Inventory; -using Content.Shared.Projectiles; - -namespace Content.Server.Chemistry.Components; - -/// -/// On colliding with an entity that has a bloodstream will dump its solution onto them. -/// -[RegisterComponent] -public sealed partial class SolutionInjectOnCollideComponent : Component -{ - [ViewVariables(VVAccess.ReadWrite)] - [DataField("transferAmount")] - public FixedPoint2 TransferAmount = FixedPoint2.New(1); - - [ViewVariables(VVAccess.ReadWrite)] - public float TransferEfficiency { get => _transferEfficiency; set => _transferEfficiency = Math.Clamp(value, 0, 1); } - - [DataField("transferEfficiency")] - private float _transferEfficiency = 1f; - - /// - /// If anything covers any of these slots then the injection fails. - /// - [DataField("blockSlots"), ViewVariables(VVAccess.ReadWrite)] - public SlotFlags BlockSlots = SlotFlags.MASK; -} diff --git a/Content.Server/Chemistry/Components/SolutionInjectOnEmbedComponent.cs b/Content.Server/Chemistry/Components/SolutionInjectOnEmbedComponent.cs new file mode 100644 index 0000000000..241da38045 --- /dev/null +++ b/Content.Server/Chemistry/Components/SolutionInjectOnEmbedComponent.cs @@ -0,0 +1,8 @@ +namespace Content.Server.Chemistry.Components; + +/// +/// Used for embeddable entities that should try to inject a +/// contained solution into a target when they become embedded in it. +/// +[RegisterComponent] +public sealed partial class SolutionInjectOnEmbedComponent : BaseSolutionInjectOnEventComponent { } diff --git a/Content.Server/Chemistry/Components/SolutionInjectOnProjectileHitComponent.cs b/Content.Server/Chemistry/Components/SolutionInjectOnProjectileHitComponent.cs new file mode 100644 index 0000000000..395a075298 --- /dev/null +++ b/Content.Server/Chemistry/Components/SolutionInjectOnProjectileHitComponent.cs @@ -0,0 +1,8 @@ +namespace Content.Server.Chemistry.Components; + +/// +/// Used for projectile entities that should try to inject a +/// contained solution into a target when they hit it. +/// +[RegisterComponent] +public sealed partial class SolutionInjectOnProjectileHitComponent : BaseSolutionInjectOnEventComponent { } diff --git a/Content.Server/Chemistry/EntitySystems/ReagentDispenserSystem.cs b/Content.Server/Chemistry/EntitySystems/ReagentDispenserSystem.cs index a8583e6bcb..d6433da56a 100644 --- a/Content.Server/Chemistry/EntitySystems/ReagentDispenserSystem.cs +++ b/Content.Server/Chemistry/EntitySystems/ReagentDispenserSystem.cs @@ -1,11 +1,12 @@ using Content.Server.Chemistry.Components; using Content.Server.Chemistry.Containers.EntitySystems; -using Content.Server.Nutrition.EntitySystems; +using Content.Server.Nutrition.Components; using Content.Shared.Chemistry; using Content.Shared.Chemistry.Dispenser; using Content.Shared.Chemistry.EntitySystems; using Content.Shared.Containers.ItemSlots; using Content.Shared.FixedPoint; +using Content.Shared.Nutrition.EntitySystems; using JetBrains.Annotations; using Robust.Server.Audio; using Robust.Server.GameObjects; diff --git a/Content.Server/Chemistry/EntitySystems/SolutionInjectOnCollideSystem.cs b/Content.Server/Chemistry/EntitySystems/SolutionInjectOnCollideSystem.cs deleted file mode 100644 index fb84aca3e4..0000000000 --- a/Content.Server/Chemistry/EntitySystems/SolutionInjectOnCollideSystem.cs +++ /dev/null @@ -1,49 +0,0 @@ -using Content.Server.Body.Components; -using Content.Server.Body.Systems; -using Content.Server.Chemistry.Components; -using Content.Server.Chemistry.Containers.EntitySystems; -using Content.Shared.Inventory; -using Content.Shared.Projectiles; - -namespace Content.Server.Chemistry.EntitySystems; - -public sealed class SolutionInjectOnCollideSystem : EntitySystem -{ - [Dependency] private readonly SolutionContainerSystem _solutionContainersSystem = default!; - [Dependency] private readonly BloodstreamSystem _bloodstreamSystem = default!; - [Dependency] private readonly InventorySystem _inventorySystem = default!; - - public override void Initialize() - { - base.Initialize(); - SubscribeLocalEvent(HandleInjection); - } - - private void HandleInjection(Entity ent, ref ProjectileHitEvent args) - { - var component = ent.Comp; - var target = args.Target; - - if (!TryComp(target, out var bloodstream) || - !_solutionContainersSystem.TryGetInjectableSolution(ent.Owner, out var solution, out _)) - { - return; - } - - if (component.BlockSlots != 0x0) - { - var containerEnumerator = _inventorySystem.GetSlotEnumerator(target, component.BlockSlots); - - // TODO add a helper method for this? - if (containerEnumerator.MoveNext(out _)) - return; - } - - var solRemoved = _solutionContainersSystem.SplitSolution(solution.Value, component.TransferAmount); - var solRemovedVol = solRemoved.Volume; - - var solToInject = solRemoved.SplitSolution(solRemovedVol * component.TransferEfficiency); - - _bloodstreamSystem.TryAddToChemicals(target, solToInject, bloodstream); - } -} diff --git a/Content.Server/Chemistry/EntitySystems/SolutionInjectOnEventSystem.cs b/Content.Server/Chemistry/EntitySystems/SolutionInjectOnEventSystem.cs new file mode 100644 index 0000000000..3c57cc31af --- /dev/null +++ b/Content.Server/Chemistry/EntitySystems/SolutionInjectOnEventSystem.cs @@ -0,0 +1,148 @@ +using Content.Server.Body.Components; +using Content.Server.Body.Systems; +using Content.Server.Chemistry.Components; +using Content.Server.Chemistry.Containers.EntitySystems; +using Content.Shared.Inventory; +using Content.Shared.Popups; +using Content.Shared.Projectiles; +using Content.Shared.Tag; +using Content.Shared.Weapons.Melee.Events; +using Robust.Shared.Collections; + +namespace Content.Server.Chemistry.EntitySystems; + +/// +/// System for handling the different inheritors of . +/// Subscribes to relevent events and performs solution injections when they are raised. +/// +public sealed class SolutionInjectOnCollideSystem : EntitySystem +{ + [Dependency] private readonly BloodstreamSystem _bloodstream = default!; + [Dependency] private readonly InventorySystem _inventory = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; + [Dependency] private readonly SolutionContainerSystem _solutionContainer = default!; + [Dependency] private readonly TagSystem _tag = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(HandleProjectileHit); + SubscribeLocalEvent(HandleEmbed); + SubscribeLocalEvent(HandleMeleeHit); + } + + private void HandleProjectileHit(Entity entity, ref ProjectileHitEvent args) + { + DoInjection((entity.Owner, entity.Comp), args.Target, args.Shooter); + } + + private void HandleEmbed(Entity entity, ref EmbedEvent args) + { + DoInjection((entity.Owner, entity.Comp), args.Embedded, args.Shooter); + } + + private void HandleMeleeHit(Entity entity, ref MeleeHitEvent args) + { + // MeleeHitEvent is weird, so we have to filter to make sure we actually + // hit something and aren't just examining the weapon. + if (args.IsHit) + TryInjectTargets((entity.Owner, entity.Comp), args.HitEntities, args.User); + } + + private void DoInjection(Entity injectorEntity, EntityUid target, EntityUid? source = null) + { + TryInjectTargets(injectorEntity, [target], source); + } + + /// + /// Filters for valid targets and tries to inject a portion of into + /// each valid target's bloodstream. + /// + /// + /// Targets are invalid if any of the following are true: + /// + /// The target does not have a bloodstream. + /// is false and the target is wearing a hardsuit. + /// is not NONE and the target has an item equipped in any of the specified slots. + /// + /// + /// true if at least one target was successfully injected, otherwise false + private bool TryInjectTargets(Entity injector, IReadOnlyList targets, EntityUid? source = null) + { + // Make sure we have at least one target + if (targets.Count == 0) + return false; + + // Get the solution to inject + if (!_solutionContainer.TryGetSolution(injector.Owner, injector.Comp.Solution, out var injectorSolution)) + return false; + + // Build a list of bloodstreams to inject into + var targetBloodstreams = new ValueList>(); + foreach (var target in targets) + { + if (Deleted(target)) + continue; + + // Yuck, this is way to hardcodey for my tastes + // TODO blocking injection with a hardsuit should probably done with a cancellable event or something + if (!injector.Comp.PierceArmor && _inventory.TryGetSlotEntity(target, "outerClothing", out var suit) && _tag.HasTag(suit.Value, "Hardsuit")) + { + // Only show popup to attacker + if (source != null) + _popup.PopupEntity(Loc.GetString(injector.Comp.BlockedByHardsuitPopupMessage, ("weapon", injector.Owner), ("target", target)), target, source.Value, PopupType.SmallCaution); + + continue; + } + + // Check if the target has anything equipped in a slot that would block injection + if (injector.Comp.BlockSlots != SlotFlags.NONE) + { + var blocked = false; + var containerEnumerator = _inventory.GetSlotEnumerator(target, injector.Comp.BlockSlots); + while (containerEnumerator.MoveNext(out var container)) + { + if (container.ContainedEntity != null) + { + blocked = true; + break; + } + } + if (blocked) + continue; + } + + // Make sure the target has a bloodstream + if (!TryComp(target, out var bloodstream)) + continue; + + + // Checks passed; add this target's bloodstream to the list + targetBloodstreams.Add((target, bloodstream)); + } + + // Make sure we got at least one bloodstream + if (targetBloodstreams.Count == 0) + return false; + + // Extract total needed solution from the injector + var removedSolution = _solutionContainer.SplitSolution(injectorSolution.Value, injector.Comp.TransferAmount * targetBloodstreams.Count); + // Adjust solution amount based on transfer efficiency + var solutionToInject = removedSolution.SplitSolution(removedSolution.Volume * injector.Comp.TransferEfficiency); + // Calculate how much of the adjusted solution each target will get + var volumePerBloodstream = solutionToInject.Volume * (1f / targetBloodstreams.Count); + + var anySuccess = false; + foreach (var targetBloodstream in targetBloodstreams) + { + // Take our portion of the adjusted solution for this target + var individualInjection = solutionToInject.SplitSolution(volumePerBloodstream); + // Inject our portion into the target's bloodstream + if (_bloodstream.TryAddToChemicals(targetBloodstream.Owner, individualInjection, targetBloodstream.Comp)) + anySuccess = true; + } + + // Huzzah! + return anySuccess; + } +} diff --git a/Content.Server/Chemistry/EntitySystems/SolutionTransferSystem.cs b/Content.Server/Chemistry/EntitySystems/SolutionTransferSystem.cs deleted file mode 100644 index 1ed5cec8dd..0000000000 --- a/Content.Server/Chemistry/EntitySystems/SolutionTransferSystem.cs +++ /dev/null @@ -1,234 +0,0 @@ -using Content.Server.Administration.Logs; -using Content.Server.Chemistry.Containers.EntitySystems; -using Content.Shared.Chemistry; -using Content.Shared.Chemistry.Components; -using Content.Shared.Database; -using Content.Shared.FixedPoint; -using Content.Shared.Interaction; -using Content.Shared.Popups; -using Content.Shared.Verbs; -using JetBrains.Annotations; -using Robust.Server.GameObjects; -using Robust.Shared.Player; - -namespace Content.Server.Chemistry.EntitySystems -{ - [UsedImplicitly] - public sealed class SolutionTransferSystem : EntitySystem - { - [Dependency] private readonly SharedPopupSystem _popupSystem = default!; - [Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!; - [Dependency] private readonly UserInterfaceSystem _userInterfaceSystem = default!; - [Dependency] private readonly IAdminLogManager _adminLogger = default!; - - /// - /// Default transfer amounts for the set-transfer verb. - /// - public static readonly List DefaultTransferAmounts = new() { 1, 5, 10, 25, 50, 100, 250, 500, 1000 }; - - public override void Initialize() - { - base.Initialize(); - - SubscribeLocalEvent>(AddSetTransferVerbs); - SubscribeLocalEvent(OnAfterInteract); - SubscribeLocalEvent(OnTransferAmountSetValueMessage); - } - - private void OnTransferAmountSetValueMessage(Entity entity, ref TransferAmountSetValueMessage message) - { - var newTransferAmount = FixedPoint2.Clamp(message.Value, entity.Comp.MinimumTransferAmount, entity.Comp.MaximumTransferAmount); - entity.Comp.TransferAmount = newTransferAmount; - - if (message.Session.AttachedEntity is { Valid: true } user) - _popupSystem.PopupEntity(Loc.GetString("comp-solution-transfer-set-amount", ("amount", newTransferAmount)), entity.Owner, user); - } - - private void AddSetTransferVerbs(Entity entity, ref GetVerbsEvent args) - { - var (uid, component) = entity; - - if (!args.CanAccess || !args.CanInteract || !component.CanChangeTransferAmount || args.Hands == null) - return; - - if (!EntityManager.TryGetComponent(args.User, out ActorComponent? actor)) - return; - - // Custom transfer verb - AlternativeVerb custom = new(); - custom.Text = Loc.GetString("comp-solution-transfer-verb-custom-amount"); - custom.Category = VerbCategory.SetTransferAmount; - custom.Act = () => _userInterfaceSystem.TryOpen(uid, TransferAmountUiKey.Key, actor.PlayerSession); - custom.Priority = 1; - args.Verbs.Add(custom); - - // Add specific transfer verbs according to the container's size - var priority = 0; - var user = args.User; - foreach (var amount in DefaultTransferAmounts) - { - if (amount < component.MinimumTransferAmount.Int() || amount > component.MaximumTransferAmount.Int()) - continue; - - AlternativeVerb verb = new(); - verb.Text = Loc.GetString("comp-solution-transfer-verb-amount", ("amount", amount)); - verb.Category = VerbCategory.SetTransferAmount; - verb.Act = () => - { - component.TransferAmount = FixedPoint2.New(amount); - _popupSystem.PopupEntity(Loc.GetString("comp-solution-transfer-set-amount", ("amount", amount)), uid, user); - }; - - // we want to sort by size, not alphabetically by the verb text. - verb.Priority = priority; - priority--; - - args.Verbs.Add(verb); - } - } - - private void OnAfterInteract(Entity entity, ref AfterInteractEvent args) - { - if (!args.CanReach || args.Target == null) - return; - - var target = args.Target!.Value; - var (uid, component) = entity; - - //Special case for reagent tanks, because normally clicking another container will give solution, not take it. - if (component.CanReceive && !EntityManager.HasComponent(target) // target must not be refillable (e.g. Reagent Tanks) - && _solutionContainerSystem.TryGetDrainableSolution(target, out var targetSoln, out _) // target must be drainable - && EntityManager.TryGetComponent(uid, out RefillableSolutionComponent? refillComp) - && _solutionContainerSystem.TryGetRefillableSolution((uid, refillComp, null), out var ownerSoln, out var ownerRefill)) - - { - - var transferAmount = component.TransferAmount; // This is the player-configurable transfer amount of "uid," not the target reagent tank. - - if (EntityManager.TryGetComponent(uid, out RefillableSolutionComponent? refill) && refill.MaxRefill != null) // uid is the entity receiving solution from target. - { - transferAmount = FixedPoint2.Min(transferAmount, (FixedPoint2) refill.MaxRefill); // if the receiver has a smaller transfer limit, use that instead - } - - var transferred = Transfer(args.User, target, targetSoln.Value, uid, ownerSoln.Value, transferAmount); - if (transferred > 0) - { - var toTheBrim = ownerRefill.AvailableVolume == 0; - var msg = toTheBrim - ? "comp-solution-transfer-fill-fully" - : "comp-solution-transfer-fill-normal"; - - _popupSystem.PopupEntity(Loc.GetString(msg, ("owner", args.Target), ("amount", transferred), ("target", uid)), uid, args.User); - - args.Handled = true; - return; - } - } - - // if target is refillable, and owner is drainable - if (component.CanSend && _solutionContainerSystem.TryGetRefillableSolution(target, out targetSoln, out var targetRefill) - && _solutionContainerSystem.TryGetDrainableSolution(uid, out ownerSoln, out var ownerDrain)) - { - var transferAmount = component.TransferAmount; - - if (EntityManager.TryGetComponent(target, out RefillableSolutionComponent? refill) && refill.MaxRefill != null) - { - transferAmount = FixedPoint2.Min(transferAmount, (FixedPoint2) refill.MaxRefill); - } - - var transferred = Transfer(args.User, uid, ownerSoln.Value, target, targetSoln.Value, transferAmount); - - if (transferred > 0) - { - var message = Loc.GetString("comp-solution-transfer-transfer-solution", ("amount", transferred), ("target", target)); - _popupSystem.PopupEntity(message, uid, args.User); - - args.Handled = true; - } - } - } - - /// - /// Transfer from a solution to another. - /// - /// The actual amount transferred. - public FixedPoint2 Transfer(EntityUid user, - EntityUid sourceEntity, - Entity source, - EntityUid targetEntity, - Entity target, - FixedPoint2 amount) - { - var transferAttempt = new SolutionTransferAttemptEvent(sourceEntity, targetEntity); - - // Check if the source is cancelling the transfer - RaiseLocalEvent(sourceEntity, transferAttempt, broadcast: true); - if (transferAttempt.Cancelled) - { - _popupSystem.PopupEntity(transferAttempt.CancelReason!, sourceEntity, user); - return FixedPoint2.Zero; - } - - var sourceSolution = source.Comp.Solution; - if (sourceSolution.Volume == 0) - { - _popupSystem.PopupEntity(Loc.GetString("comp-solution-transfer-is-empty", ("target", sourceEntity)), sourceEntity, user); - return FixedPoint2.Zero; - } - - // Check if the target is cancelling the transfer - RaiseLocalEvent(targetEntity, transferAttempt, broadcast: true); - if (transferAttempt.Cancelled) - { - _popupSystem.PopupEntity(transferAttempt.CancelReason!, sourceEntity, user); - return FixedPoint2.Zero; - } - - var targetSolution = target.Comp.Solution; - if (targetSolution.AvailableVolume == 0) - { - _popupSystem.PopupEntity(Loc.GetString("comp-solution-transfer-is-full", ("target", targetEntity)), targetEntity, user); - return FixedPoint2.Zero; - } - - var actualAmount = FixedPoint2.Min(amount, FixedPoint2.Min(sourceSolution.Volume, targetSolution.AvailableVolume)); - - var solution = _solutionContainerSystem.Drain(sourceEntity, source, actualAmount); - _solutionContainerSystem.Refill(targetEntity, target, solution); - - _adminLogger.Add(LogType.Action, LogImpact.Medium, - $"{EntityManager.ToPrettyString(user):player} transferred {string.Join(", ", solution.Contents)} to {EntityManager.ToPrettyString(targetEntity):entity}, which now contains {SolutionContainerSystem.ToPrettyString(targetSolution)}"); - - return actualAmount; - } - } - - /// - /// Raised when attempting to transfer from one solution to another. - /// - public sealed class SolutionTransferAttemptEvent : CancellableEntityEventArgs - { - public SolutionTransferAttemptEvent(EntityUid from, EntityUid to) - { - From = from; - To = to; - } - - public EntityUid From { get; } - public EntityUid To { get; } - - /// - /// Why the transfer has been cancelled. - /// - public string? CancelReason { get; private set; } - - /// - /// Cancels the transfer. - /// - public void Cancel(string reason) - { - base.Cancel(); - CancelReason = reason; - } - } -} diff --git a/Content.Server/Construction/Conditions/ToiletLidClosed.cs b/Content.Server/Construction/Conditions/ToiletLidClosed.cs deleted file mode 100644 index 40a3be006b..0000000000 --- a/Content.Server/Construction/Conditions/ToiletLidClosed.cs +++ /dev/null @@ -1,39 +0,0 @@ -using Content.Shared.Construction; -using Content.Shared.Examine; -using Content.Shared.Toilet; -using JetBrains.Annotations; - -namespace Content.Server.Construction.Conditions -{ - [UsedImplicitly] - [DataDefinition] - public sealed partial class ToiletLidClosed : IGraphCondition - { - public bool Condition(EntityUid uid, IEntityManager entityManager) - { - if (!entityManager.TryGetComponent(uid, out ToiletComponent? toilet)) - return false; - - return !toilet.LidOpen; - } - - public bool DoExamine(ExaminedEvent args) - { - var entity = args.Examined; - - if (!IoCManager.Resolve().TryGetComponent(entity, out ToiletComponent? toilet)) return false; - if (!toilet.LidOpen) return false; - - args.PushMarkup(Loc.GetString("construction-examine-condition-toilet-lid-closed") + "\n"); - return true; - } - - public IEnumerable GenerateGuideEntry() - { - yield return new ConstructionGuideEntry() - { - Localization = "construction-step-condition-toilet-lid-closed" - }; - } - } -} diff --git a/Content.Server/Destructible/Thresholds/Behaviors/OpenBehavior.cs b/Content.Server/Destructible/Thresholds/Behaviors/OpenBehavior.cs index f01e4f7048..7ab1fe11b0 100644 --- a/Content.Server/Destructible/Thresholds/Behaviors/OpenBehavior.cs +++ b/Content.Server/Destructible/Thresholds/Behaviors/OpenBehavior.cs @@ -1,4 +1,4 @@ -using Content.Server.Nutrition.EntitySystems; +using Content.Shared.Nutrition.EntitySystems; namespace Content.Server.Destructible.Thresholds.Behaviors; diff --git a/Content.Server/DeviceLinking/Components/SignalTimerComponent.cs b/Content.Server/DeviceLinking/Components/SignalTimerComponent.cs index 2e9b369b99..b3535cde1f 100644 --- a/Content.Server/DeviceLinking/Components/SignalTimerComponent.cs +++ b/Content.Server/DeviceLinking/Components/SignalTimerComponent.cs @@ -23,6 +23,12 @@ public sealed partial class SignalTimerComponent : Component [DataField, ViewVariables(VVAccess.ReadWrite)] public string Label = string.Empty; + /// + /// Default max width of a label (how many letters can this render?) + /// + [DataField, ViewVariables(VVAccess.ReadWrite)] + public int MaxLength = 5; + /// /// The port that gets signaled when the timer triggers. /// diff --git a/Content.Server/DeviceLinking/Systems/SignalTimerSystem.cs b/Content.Server/DeviceLinking/Systems/SignalTimerSystem.cs index f9c2d3430e..0e214ee865 100644 --- a/Content.Server/DeviceLinking/Systems/SignalTimerSystem.cs +++ b/Content.Server/DeviceLinking/Systems/SignalTimerSystem.cs @@ -39,6 +39,7 @@ public sealed class SignalTimerSystem : EntitySystem private void OnInit(EntityUid uid, SignalTimerComponent component, ComponentInit args) { + _appearanceSystem.SetData(uid, TextScreenVisuals.DefaultText, component.Label); _appearanceSystem.SetData(uid, TextScreenVisuals.ScreenText, component.Label); _signalSystem.EnsureSinkPorts(uid, component.Trigger); } @@ -66,11 +67,6 @@ public sealed class SignalTimerSystem : EntitySystem { RemComp(uid); - if (TryComp(uid, out var appearance)) - { - _appearanceSystem.SetData(uid, TextScreenVisuals.ScreenText, signalTimer.Label, appearance); - } - _audio.PlayPvs(signalTimer.DoneSound, uid); _signalSystem.InvokePort(uid, signalTimer.TriggerPort); @@ -139,10 +135,15 @@ public sealed class SignalTimerSystem : EntitySystem if (!IsMessageValid(uid, args)) return; - component.Label = args.Text[..Math.Min(5, args.Text.Length)]; + component.Label = args.Text[..Math.Min(component.MaxLength, args.Text.Length)]; if (!HasComp(uid)) + { + // could maybe move the defaulttext update out of this block, + // if you delved deep into appearance update batching + _appearanceSystem.SetData(uid, TextScreenVisuals.DefaultText, component.Label); _appearanceSystem.SetData(uid, TextScreenVisuals.ScreenText, component.Label); + } } /// @@ -166,7 +167,15 @@ public sealed class SignalTimerSystem : EntitySystem { if (!IsMessageValid(uid, args)) return; - OnStartTimer(uid, component); + + // feedback received: pressing the timer button while a timer is running should cancel the timer. + if (HasComp(uid)) + { + _appearanceSystem.SetData(uid, TextScreenVisuals.TargetTime, _gameTiming.CurTime); + Trigger(uid, component); + } + else + OnStartTimer(uid, component); } private void OnSignalReceived(EntityUid uid, SignalTimerComponent component, ref SignalReceivedEvent args) diff --git a/Content.Server/Disposal/Unit/EntitySystems/DisposalUnitSystem.cs b/Content.Server/Disposal/Unit/EntitySystems/DisposalUnitSystem.cs index a03ba5d231..8a7ea438be 100644 --- a/Content.Server/Disposal/Unit/EntitySystems/DisposalUnitSystem.cs +++ b/Content.Server/Disposal/Unit/EntitySystems/DisposalUnitSystem.cs @@ -135,8 +135,7 @@ public sealed class DisposalUnitSystem : SharedDisposalUnitSystem { // This is not an interaction, activation, or alternative verb type because unfortunately most users are // unwilling to accept that this is where they belong and don't want to accidentally climb inside. - if (!component.MobsCanEnter || - !args.CanAccess || + if (!args.CanAccess || !args.CanInteract || component.Container.ContainedEntities.Contains(args.User) || !_actionBlockerSystem.CanMove(args.User)) @@ -630,10 +629,10 @@ public sealed class DisposalUnitSystem : SharedDisposalUnitSystem switch (state) { case DisposalsPressureState.Flushed: - _appearance.SetData(uid, SharedDisposalUnitComponent.Visuals.VisualState, SharedDisposalUnitComponent.VisualState.Flushing, appearance); + _appearance.SetData(uid, SharedDisposalUnitComponent.Visuals.VisualState, SharedDisposalUnitComponent.VisualState.OverlayFlushing, appearance); break; case DisposalsPressureState.Pressurizing: - _appearance.SetData(uid, SharedDisposalUnitComponent.Visuals.VisualState, SharedDisposalUnitComponent.VisualState.Charging, appearance); + _appearance.SetData(uid, SharedDisposalUnitComponent.Visuals.VisualState, SharedDisposalUnitComponent.VisualState.OverlayCharging, appearance); break; case DisposalsPressureState.Ready: _appearance.SetData(uid, SharedDisposalUnitComponent.Visuals.VisualState, SharedDisposalUnitComponent.VisualState.Anchored, appearance); diff --git a/Content.Server/Doors/Electronics/Systems/DoorElectronicsSystem.cs b/Content.Server/Doors/Electronics/Systems/DoorElectronicsSystem.cs new file mode 100644 index 0000000000..56e8bd50b3 --- /dev/null +++ b/Content.Server/Doors/Electronics/Systems/DoorElectronicsSystem.cs @@ -0,0 +1,69 @@ +using System.Linq; +using Content.Server.Doors.Electronics; +using Content.Shared.Access; +using Content.Shared.Access.Components; +using Content.Shared.Access.Systems; +using Content.Shared.DeviceNetwork.Components; +using Content.Shared.Doors.Electronics; +using Content.Shared.Doors; +using Content.Shared.Interaction; +using Robust.Server.GameObjects; +using Robust.Shared.Prototypes; + +namespace Content.Server.Doors.Electronics; + +public sealed class DoorElectronicsSystem : EntitySystem +{ + [Dependency] private readonly UserInterfaceSystem _uiSystem = default!; + [Dependency] private readonly AccessReaderSystem _accessReader = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnChangeConfiguration); + SubscribeLocalEvent(OnAccessReaderChanged); + SubscribeLocalEvent(OnBoundUIOpened); + } + + public void UpdateUserInterface(EntityUid uid, DoorElectronicsComponent component) + { + var accesses = new List>(); + + if (TryComp(uid, out var accessReader)) + { + foreach (var accessList in accessReader.AccessLists) + { + var access = accessList.FirstOrDefault(); + accesses.Add(access); + } + } + + var state = new DoorElectronicsConfigurationState(accesses); + _uiSystem.TrySetUiState(uid, DoorElectronicsConfigurationUiKey.Key, state); + } + + private void OnChangeConfiguration( + EntityUid uid, + DoorElectronicsComponent component, + DoorElectronicsUpdateConfigurationMessage args) + { + var accessReader = EnsureComp(uid); + _accessReader.SetAccesses(uid, accessReader, args.AccessList); + } + + private void OnAccessReaderChanged( + EntityUid uid, + DoorElectronicsComponent component, + AccessReaderConfigurationChangedEvent args) + { + UpdateUserInterface(uid, component); + } + + private void OnBoundUIOpened( + EntityUid uid, + DoorElectronicsComponent component, + BoundUIOpenedEvent args) + { + UpdateUserInterface(uid, component); + } +} diff --git a/Content.Server/Extinguisher/FireExtinguisherSystem.cs b/Content.Server/Extinguisher/FireExtinguisherSystem.cs index dfecd72398..b33a1af157 100644 --- a/Content.Server/Extinguisher/FireExtinguisherSystem.cs +++ b/Content.Server/Extinguisher/FireExtinguisherSystem.cs @@ -73,6 +73,7 @@ public sealed class FireExtinguisherSystem : EntitySystem args.Handled = true; + // TODO: why is this copy paste shit here just have fire extinguisher cancel transfer when safety is on var transfer = containerSolution.AvailableVolume; if (TryComp(entity.Owner, out var solTrans)) { diff --git a/Content.Server/Fluids/EntitySystems/PuddleSystem.Spillable.cs b/Content.Server/Fluids/EntitySystems/PuddleSystem.Spillable.cs index ce5b5b3637..bd7c55e85e 100644 --- a/Content.Server/Fluids/EntitySystems/PuddleSystem.Spillable.cs +++ b/Content.Server/Fluids/EntitySystems/PuddleSystem.Spillable.cs @@ -1,5 +1,5 @@ using Content.Server.Chemistry.Containers.EntitySystems; -using Content.Server.Nutrition.EntitySystems; +using Content.Server.Fluids.Components; using Content.Shared.Chemistry.Components; using Content.Shared.Chemistry.EntitySystems; using Content.Shared.Chemistry.Reaction; @@ -11,6 +11,7 @@ using Content.Shared.FixedPoint; using Content.Shared.Fluids.Components; using Content.Shared.IdentityManagement; using Content.Shared.Inventory.Events; +using Content.Shared.Nutrition.EntitySystems; using Content.Shared.Popups; using Content.Shared.Spillable; using Content.Shared.Throwing; @@ -29,6 +30,7 @@ public sealed partial class PuddleSystem // Openable handles the event if it's closed SubscribeLocalEvent(SplashOnMeleeHit, after: [typeof(OpenableSystem)]); SubscribeLocalEvent(OnGotEquipped); + SubscribeLocalEvent(OnGotUnequipped); SubscribeLocalEvent(OnOverflow); SubscribeLocalEvent(OnDoAfter); SubscribeLocalEvent(OnAttemptPacifiedThrow); @@ -114,6 +116,9 @@ public sealed partial class PuddleSystem if (!_solutionContainerSystem.TryGetSolution(entity.Owner, entity.Comp.SolutionName, out var soln, out var solution)) return; + // block access to the solution while worn + AddComp(entity); + if (solution.Volume == 0) return; @@ -122,6 +127,14 @@ public sealed partial class PuddleSystem TrySplashSpillAt(entity.Owner, Transform(args.Equipee).Coordinates, drainedSolution, out _); } + private void OnGotUnequipped(Entity entity, ref GotUnequippedEvent args) + { + if (!entity.Comp.SpillWorn) + return; + + RemCompDeferred(entity); + } + private void SpillOnLand(Entity entity, ref LandEvent args) { if (!_solutionContainerSystem.TryGetSolution(entity.Owner, entity.Comp.SolutionName, out var soln, out var solution)) diff --git a/Content.Server/GameTicking/GameTicker.RoundFlow.cs b/Content.Server/GameTicking/GameTicker.RoundFlow.cs index 004508ab91..202daf256d 100644 --- a/Content.Server/GameTicking/GameTicker.RoundFlow.cs +++ b/Content.Server/GameTicking/GameTicker.RoundFlow.cs @@ -4,6 +4,7 @@ using Content.Server.Discord; using Content.Server.GameTicking.Events; using Content.Server.Ghost; using Content.Server.Maps; +using Content.Shared.CCVar; using Content.Shared.Database; using Content.Shared.GameTicking; using Content.Shared.Mind; @@ -194,26 +195,18 @@ namespace Content.Server.GameTicking SendServerMessage(Loc.GetString("game-ticker-start-round")); - // Just in case it hasn't been loaded previously we'll try loading it. - LoadMaps(); - - // map has been selected so update the lobby info text - // applies to players who didn't ready up - UpdateInfoText(); - - StartGamePresetRules(); - - RoundLengthMetric.Set(0); - - var startingEvent = new RoundStartingEvent(RoundId); - RaiseLocalEvent(startingEvent); var readyPlayers = new List(); var readyPlayerProfiles = new Dictionary(); - + var autoDeAdmin = _cfg.GetCVar(CCVars.AdminDeadminOnJoin); foreach (var (userId, status) in _playerGameStatuses) { if (LobbyEnabled && status != PlayerGameStatus.ReadyToPlay) continue; if (!_playerManager.TryGetSessionById(userId, out var session)) continue; + + if (autoDeAdmin && _adminManager.IsAdmin(session)) + { + _adminManager.DeAdmin(session); + } #if DEBUG DebugTools.Assert(_userDb.IsLoadComplete(session), $"Player was readied up but didn't have user DB data loaded yet??"); #endif @@ -235,6 +228,20 @@ namespace Content.Server.GameTicking readyPlayerProfiles.Add(userId, profile); } + // Just in case it hasn't been loaded previously we'll try loading it. + LoadMaps(); + + // map has been selected so update the lobby info text + // applies to players who didn't ready up + UpdateInfoText(); + + StartGamePresetRules(); + + RoundLengthMetric.Set(0); + + var startingEvent = new RoundStartingEvent(RoundId); + RaiseLocalEvent(startingEvent); + var origReadyPlayers = readyPlayers.ToArray(); if (!StartPreset(origReadyPlayers, force)) diff --git a/Content.Server/GameTicking/GameTicker.Spawning.cs b/Content.Server/GameTicking/GameTicker.Spawning.cs index 52bab07ce8..5f4610744a 100644 --- a/Content.Server/GameTicking/GameTicker.Spawning.cs +++ b/Content.Server/GameTicking/GameTicker.Spawning.cs @@ -154,10 +154,6 @@ namespace Content.Server.GameTicking return; } - // Automatically de-admin players who are joining. - if (_cfg.GetCVar(CCVars.AdminDeadminOnJoin) && _adminManager.IsAdmin(player)) - _adminManager.DeAdmin(player); - // We raise this event to allow other systems to handle spawning this player themselves. (e.g. late-join wizard, etc) var bev = new PlayerBeforeSpawnEvent(player, character, jobId, lateJoin, station); RaiseLocalEvent(bev); diff --git a/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs b/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs index ea5ab9c2ab..886af60987 100644 --- a/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs @@ -763,10 +763,6 @@ public sealed class NukeopsRuleSystem : GameRuleSystem _mind.SetUserId(newMind, nukieSession.Session.UserId); _roles.MindAddRole(newMind, new NukeopsRoleComponent { PrototypeId = nukieSession.Type.AntagRoleProto }); - // Automatically de-admin players who are being made nukeops - if (_cfg.GetCVar(CCVars.AdminDeadminOnJoin) && _adminManager.IsAdmin(nukieSession.Session)) - _adminManager.DeAdmin(nukieSession.Session); - _mind.TransferTo(newMind, mob); } //Otherwise, spawn as a ghost role diff --git a/Content.Server/Glue/GlueSystem.cs b/Content.Server/Glue/GlueSystem.cs index 44ff4e5459..ff53ef91ca 100644 --- a/Content.Server/Glue/GlueSystem.cs +++ b/Content.Server/Glue/GlueSystem.cs @@ -1,12 +1,12 @@ using Content.Server.Administration.Logs; using Content.Server.Chemistry.Containers.EntitySystems; -using Content.Server.Nutrition.EntitySystems; using Content.Shared.Database; using Content.Shared.Glue; using Content.Shared.Hands; using Content.Shared.Interaction; using Content.Shared.Interaction.Components; using Content.Shared.Item; +using Content.Shared.Nutrition.EntitySystems; using Content.Shared.Popups; using Content.Shared.Verbs; using Robust.Shared.Audio.Systems; diff --git a/Content.Server/Hands/Systems/HandsSystem.cs b/Content.Server/Hands/Systems/HandsSystem.cs index 06946cd052..bfd6393790 100644 --- a/Content.Server/Hands/Systems/HandsSystem.cs +++ b/Content.Server/Hands/Systems/HandsSystem.cs @@ -75,6 +75,9 @@ namespace Content.Server.Hands.Systems private void OnExploded(Entity ent, ref BeforeExplodeEvent args) { + if (ent.Comp.DisableExplosionRecursion) + return; + foreach (var hand in ent.Comp.Hands.Values) { if (hand.HeldEntity is { } uid) diff --git a/Content.Server/Implants/Components/ScramImplantComponent.cs b/Content.Server/Implants/Components/ScramImplantComponent.cs index 88c433abfb..f3bbc9e584 100644 --- a/Content.Server/Implants/Components/ScramImplantComponent.cs +++ b/Content.Server/Implants/Components/ScramImplantComponent.cs @@ -15,12 +15,6 @@ public sealed partial class ScramImplantComponent : Component [DataField, ViewVariables(VVAccess.ReadWrite)] public float TeleportRadius = 100f; - /// - /// How many times to check for a valid tile to teleport to - /// - [DataField, ViewVariables(VVAccess.ReadOnly)] - public int TeleportAttempts = 20; - [DataField, ViewVariables(VVAccess.ReadWrite)] public SoundSpecifier TeleportSound = new SoundPathSpecifier("/Audio/Effects/teleport_arrival.ogg"); } diff --git a/Content.Server/Implants/SubdermalImplantSystem.cs b/Content.Server/Implants/SubdermalImplantSystem.cs index fd95720732..e8af08b2eb 100644 --- a/Content.Server/Implants/SubdermalImplantSystem.cs +++ b/Content.Server/Implants/SubdermalImplantSystem.cs @@ -14,13 +14,14 @@ using Content.Shared.Popups; using Content.Shared.Preferences; using Robust.Shared.Audio.Systems; using Robust.Shared.Map; -using Robust.Shared.Maths; using Robust.Shared.Physics; using Robust.Shared.Physics.Components; using Robust.Shared.Random; using System.Numerics; using Content.Shared.Movement.Pulling.Components; using Content.Shared.Movement.Pulling.Systems; +using Robust.Shared.Collections; +using Robust.Shared.Map.Components; namespace Content.Server.Implants; @@ -28,7 +29,6 @@ public sealed class SubdermalImplantSystem : SharedSubdermalImplantSystem { [Dependency] private readonly CuffableSystem _cuffable = default!; [Dependency] private readonly HumanoidAppearanceSystem _humanoidAppearance = default!; - [Dependency] private readonly IMapManager _mapManager = default!; [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly MetaDataSystem _metaData = default!; [Dependency] private readonly StoreSystem _store = default!; @@ -37,8 +37,11 @@ public sealed class SubdermalImplantSystem : SharedSubdermalImplantSystem [Dependency] private readonly SharedTransformSystem _xform = default!; [Dependency] private readonly ForensicsSystem _forensicsSystem = default!; [Dependency] private readonly PullingSystem _pullingSystem = default!; + [Dependency] private readonly EntityLookupSystem _lookupSystem = default!; + [Dependency] private readonly SharedMapSystem _mapSystem = default!; private EntityQuery _physicsQuery; + private HashSet> _targetGrids = []; public override void Initialize() { @@ -107,41 +110,92 @@ public sealed class SubdermalImplantSystem : SharedSubdermalImplantSystem _pullingSystem.TryStopPull(ent, pull); var xform = Transform(ent); - var entityCoords = xform.Coordinates.ToMap(EntityManager, _xform); + var targetCoords = SelectRandomTileInRange(xform, implant.TeleportRadius); - // try to find a valid position to teleport to, teleport to whatever works if we can't - var targetCoords = new MapCoordinates(); - for (var i = 0; i < implant.TeleportAttempts; i++) + if (targetCoords != null) { - var distance = implant.TeleportRadius * MathF.Sqrt(_random.NextFloat()); // to get an uniform distribution - targetCoords = entityCoords.Offset(_random.NextAngle().ToVec() * distance); - - // prefer teleporting to grids - if (!_mapManager.TryFindGridAt(targetCoords, out var gridUid, out var grid)) - continue; - - // the implant user probably does not want to be in your walls - var valid = true; - foreach (var entity in grid.GetAnchoredEntities(targetCoords)) - { - if (!_physicsQuery.TryGetComponent(entity, out var body)) - continue; - - if (body.BodyType != BodyType.Static || - !body.Hard || - (body.CollisionLayer & (int) CollisionGroup.Impassable) == 0) - continue; - - valid = false; - break; - } - if (valid) - break; + _xform.SetCoordinates(ent, targetCoords.Value); + _audio.PlayPvs(implant.TeleportSound, ent); + args.Handled = true; } - _xform.SetWorldPosition(ent, targetCoords.Position); - _audio.PlayPvs(implant.TeleportSound, ent); + } - args.Handled = true; + private EntityCoordinates? SelectRandomTileInRange(TransformComponent userXform, float radius) + { + var userCoords = userXform.Coordinates.ToMap(EntityManager, _xform); + _targetGrids.Clear(); + _lookupSystem.GetEntitiesInRange(userCoords, radius, _targetGrids); + Entity? targetGrid = null; + + if (_targetGrids.Count == 0) + return null; + + // Give preference to the grid the entity is currently on. + // This does not guarantee that if the probability fails that the owner's grid won't be picked. + // In reality the probability is higher and depends on the number of grids. + if (userXform.GridUid != null && TryComp(userXform.GridUid, out var gridComp)) + { + var userGrid = new Entity(userXform.GridUid.Value, gridComp); + if (_random.Prob(0.5f)) + { + _targetGrids.Remove(userGrid); + targetGrid = userGrid; + } + } + + if (targetGrid == null) + targetGrid = _random.GetRandom().PickAndTake(_targetGrids); + + EntityCoordinates? targetCoords = null; + + do + { + var valid = false; + + var range = (float) Math.Sqrt(radius); + var box = Box2.CenteredAround(userCoords.Position, new Vector2(range, range)); + var tilesInRange = _mapSystem.GetTilesEnumerator(targetGrid.Value.Owner, targetGrid.Value.Comp, box, false); + var tileList = new ValueList(); + + while (tilesInRange.MoveNext(out var tile)) + { + tileList.Add(tile.GridIndices); + } + + while (tileList.Count != 0) + { + var tile = tileList.RemoveSwap(_random.Next(tileList.Count)); + valid = true; + foreach (var entity in _mapSystem.GetAnchoredEntities(targetGrid.Value.Owner, targetGrid.Value.Comp, + tile)) + { + if (!_physicsQuery.TryGetComponent(entity, out var body)) + continue; + + if (body.BodyType != BodyType.Static || + !body.Hard || + (body.CollisionLayer & (int) CollisionGroup.MobMask) == 0) + continue; + + valid = false; + break; + } + + if (valid) + { + targetCoords = new EntityCoordinates(targetGrid.Value.Owner, + _mapSystem.TileCenterToVector(targetGrid.Value, tile)); + break; + } + } + + if (valid || _targetGrids.Count == 0) // if we don't do the check here then PickAndTake will blow up on an empty set. + break; + + targetGrid = _random.GetRandom().PickAndTake(_targetGrids); + } while (true); + + return targetCoords; } private void OnDnaScramblerImplant(EntityUid uid, SubdermalImplantComponent component, UseDnaScramblerImplantEvent args) diff --git a/Content.Server/Lube/LubeSystem.cs b/Content.Server/Lube/LubeSystem.cs index 5285cb389c..06d6456a57 100644 --- a/Content.Server/Lube/LubeSystem.cs +++ b/Content.Server/Lube/LubeSystem.cs @@ -1,12 +1,12 @@ using Content.Server.Administration.Logs; using Content.Server.Chemistry.Containers.EntitySystems; -using Content.Server.Nutrition.EntitySystems; using Content.Shared.Database; using Content.Shared.Glue; using Content.Shared.IdentityManagement; using Content.Shared.Interaction; using Content.Shared.Item; using Content.Shared.Lube; +using Content.Shared.Nutrition.EntitySystems; using Content.Shared.Popups; using Content.Shared.Verbs; using Robust.Shared.Audio; diff --git a/Content.Server/Materials/MaterialReclaimerSystem.cs b/Content.Server/Materials/MaterialReclaimerSystem.cs index ae4444e059..0d6d27777a 100644 --- a/Content.Server/Materials/MaterialReclaimerSystem.cs +++ b/Content.Server/Materials/MaterialReclaimerSystem.cs @@ -1,8 +1,6 @@ using Content.Server.Chemistry.Containers.EntitySystems; -using Content.Server.Chemistry.EntitySystems; using Content.Server.Fluids.EntitySystems; using Content.Server.GameTicking; -using Content.Server.Nutrition.EntitySystems; using Content.Server.Popups; using Content.Server.Power.Components; using Content.Server.Stack; @@ -10,11 +8,13 @@ using Content.Server.Wires; using Content.Shared.Body.Systems; using Content.Shared.Chemistry.Components; using Content.Shared.Chemistry.Components.SolutionManager; +using Content.Shared.Chemistry.EntitySystems; using Content.Shared.IdentityManagement; using Content.Shared.Interaction; using Content.Shared.Interaction.Events; using Content.Shared.Materials; using Content.Shared.Mind; +using Content.Shared.Nutrition.EntitySystems; using Robust.Server.GameObjects; using Robust.Shared.Player; using Robust.Shared.Utility; diff --git a/Content.Server/NPC/Systems/NPCUtilitySystem.cs b/Content.Server/NPC/Systems/NPCUtilitySystem.cs index 6793161105..e8fb54022e 100644 --- a/Content.Server/NPC/Systems/NPCUtilitySystem.cs +++ b/Content.Server/NPC/Systems/NPCUtilitySystem.cs @@ -14,6 +14,7 @@ using Content.Shared.Inventory; using Content.Shared.Mobs.Systems; using Content.Shared.NPC.Systems; using Content.Shared.Nutrition.Components; +using Content.Shared.Nutrition.EntitySystems; using Content.Shared.Tools.Systems; using Content.Shared.Weapons.Melee; using Content.Shared.Weapons.Ranged.Components; diff --git a/Content.Server/NodeContainer/EntitySystems/NodeContainerSystem.cs b/Content.Server/NodeContainer/EntitySystems/NodeContainerSystem.cs index 19b811a287..c0603949be 100644 --- a/Content.Server/NodeContainer/EntitySystems/NodeContainerSystem.cs +++ b/Content.Server/NodeContainer/EntitySystems/NodeContainerSystem.cs @@ -106,7 +106,7 @@ namespace Content.Server.NodeContainer.EntitySystems && ent.Comp.Nodes.TryGetValue(id2, out var n2) && n2 is T2 t2 && ent.Comp.Nodes.TryGetValue(id3, out var n3) - && n2 is T3 t3) + && n3 is T3 t3) { node1 = t1; node2 = t2; diff --git a/Content.Server/Nutrition/EntitySystems/DrinkSystem.cs b/Content.Server/Nutrition/EntitySystems/DrinkSystem.cs index 5fb090087a..74637d4813 100644 --- a/Content.Server/Nutrition/EntitySystems/DrinkSystem.cs +++ b/Content.Server/Nutrition/EntitySystems/DrinkSystem.cs @@ -24,6 +24,7 @@ using Content.Shared.Interaction.Events; using Content.Shared.Mobs.Systems; using Content.Shared.Nutrition; using Content.Shared.Nutrition.Components; +using Content.Shared.Nutrition.EntitySystems; using Content.Shared.Throwing; using Content.Shared.Verbs; using Robust.Shared.Audio; @@ -410,6 +411,10 @@ public sealed class DrinkSystem : EntitySystem !_body.TryGetBodyOrganComponents(ev.User, out var stomachs, body)) return; + // Make sure the solution exists + if (!_solutionContainer.TryGetSolution(entity.Owner, entity.Comp.Solution, out var solution)) + return; + // no drinking from living drinks, have to kill them first. if (_mobState.IsAlive(entity)) return; diff --git a/Content.Server/Nutrition/EntitySystems/FoodSystem.cs b/Content.Server/Nutrition/EntitySystems/FoodSystem.cs index d87b0bd0b0..49d7374041 100644 --- a/Content.Server/Nutrition/EntitySystems/FoodSystem.cs +++ b/Content.Server/Nutrition/EntitySystems/FoodSystem.cs @@ -23,6 +23,7 @@ using Content.Shared.Interaction.Events; using Content.Shared.Inventory; using Content.Shared.Mobs.Systems; using Content.Shared.Nutrition; +using Content.Shared.Nutrition.EntitySystems; using Content.Shared.Stacks; using Content.Shared.Storage; using Content.Shared.Verbs; diff --git a/Content.Server/Nutrition/EntitySystems/OpenableSystem.cs b/Content.Server/Nutrition/EntitySystems/OpenableSystem.cs deleted file mode 100644 index 8037b61572..0000000000 --- a/Content.Server/Nutrition/EntitySystems/OpenableSystem.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Content.Server.Chemistry.EntitySystems; -using Content.Shared.Nutrition.EntitySystems; -using Content.Shared.Nutrition.Components; - -namespace Content.Server.Nutrition.EntitySystems; - -/// -/// Provides API for openable food and drinks, handles opening on use and preventing transfer when closed. -/// -public sealed class OpenableSystem : SharedOpenableSystem -{ - public override void Initialize() - { - base.Initialize(); - - SubscribeLocalEvent(OnTransferAttempt); - } - - private void OnTransferAttempt(EntityUid uid, OpenableComponent comp, SolutionTransferAttemptEvent args) - { - if (!comp.Opened) - { - // message says its just for drinks, shouldn't matter since you typically dont have a food that is openable and can be poured out - args.Cancel(Loc.GetString("drink-component-try-use-drink-not-open", ("owner", uid))); - } - } -} diff --git a/Content.Server/Paint/PaintSystem.cs b/Content.Server/Paint/PaintSystem.cs deleted file mode 100644 index 892f961d63..0000000000 --- a/Content.Server/Paint/PaintSystem.cs +++ /dev/null @@ -1,178 +0,0 @@ -using Content.Shared.Popups; -using Content.Shared.Paint; -using Content.Shared.Sprite; -using Content.Shared.DoAfter; -using Content.Shared.Interaction; -using Content.Server.Chemistry.Containers.EntitySystems; -using Robust.Shared.Audio.Systems; -using Content.Shared.Humanoid; -using Robust.Shared.Utility; -using Content.Shared.Verbs; -using Content.Shared.SubFloor; -using Content.Server.Nutrition.Components; -using Content.Shared.Inventory; -using Content.Server.Nutrition.EntitySystems; - -namespace Content.Server.Paint; - -/// -/// Colors target and consumes reagent on each color success. -/// -public sealed class PaintSystem : SharedPaintSystem -{ - [Dependency] private readonly SharedAudioSystem _audio = default!; - [Dependency] private readonly SharedPopupSystem _popup = default!; - [Dependency] private readonly SolutionContainerSystem _solutionContainer = default!; - [Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!; - [Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!; - [Dependency] private readonly InventorySystem _inventory = default!; - [Dependency] private readonly OpenableSystem _openable = default!; - - public override void Initialize() - { - base.Initialize(); - - SubscribeLocalEvent(OnInteract); - SubscribeLocalEvent(OnPaint); - SubscribeLocalEvent>(OnPaintVerb); - } - - private void OnInteract(EntityUid uid, PaintComponent component, AfterInteractEvent args) - { - if (!args.CanReach) - return; - - if (args.Target is not { Valid: true } target) - return; - - PrepPaint(uid, component, target, args.User); - } - - private void OnPaintVerb(EntityUid uid, PaintComponent component, GetVerbsEvent args) - { - if (!args.CanInteract || !args.CanAccess) - return; - - var paintText = Loc.GetString("paint-verb"); - - var verb = new UtilityVerb() - { - Act = () => - { - PrepPaint(uid, component, args.Target, args.User); - }, - - Text = paintText, - Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/paint.svg.192dpi.png")) - }; - args.Verbs.Add(verb); - } - private void PrepPaint(EntityUid uid, PaintComponent component, EntityUid target, EntityUid user) - { - - var doAfterEventArgs = new DoAfterArgs(EntityManager, user, component.Delay, new PaintDoAfterEvent(), uid, target: target, used: uid) - { - BreakOnMove = true, - NeedHand = true, - BreakOnHandChange = true - }; - - _doAfterSystem.TryStartDoAfter(doAfterEventArgs); - } - - private void OnPaint(Entity entity, ref PaintDoAfterEvent args) - { - if (args.Target == null || args.Used == null) - return; - - if (args.Handled || args.Cancelled) - return; - - if (args.Target is not { Valid: true } target) - return; - - if (!_openable.IsOpen(entity)) - { - _popup.PopupEntity(Loc.GetString("paint-closed", ("used", args.Used)), args.User, args.User, PopupType.Medium); - return; - } - - if (HasComp(target) || HasComp(target)) - { - _popup.PopupEntity(Loc.GetString("paint-failure-painted", ("target", args.Target)), args.User, args.User, PopupType.Medium); - return; - } - - if (!entity.Comp.Blacklist?.IsValid(target, EntityManager) != true || HasComp(target) || HasComp(target)) - { - _popup.PopupEntity(Loc.GetString("paint-failure", ("target", args.Target)), args.User, args.User, PopupType.Medium); - return; - } - - if (TryPaint(entity, target)) - { - EnsureComp(target, out PaintedComponent? paint); - EnsureComp(target); - - paint.Color = entity.Comp.Color; // set the target color to the color specified in the spray paint yml. - _audio.PlayPvs(entity.Comp.Spray, entity); - paint.Enabled = true; - - if (HasComp(target)) // Paint any clothing the target is wearing. - { - if (_inventory.TryGetSlots(target, out var slotDefinitions)) - { - foreach (var slot in slotDefinitions) - { - if (!_inventory.TryGetSlotEntity(target, slot.Name, out var slotEnt)) - continue; - - if (HasComp(slotEnt.Value) || !entity.Comp.Blacklist?.IsValid(slotEnt.Value, - EntityManager) != true - || HasComp(slotEnt.Value) || - HasComp( - slotEnt.Value)) - { - continue; - } - - EnsureComp(slotEnt.Value, out PaintedComponent? slotpaint); - EnsureComp(slotEnt.Value); - slotpaint.Color = entity.Comp.Color; - _appearanceSystem.SetData(slotEnt.Value, PaintVisuals.Painted, true); - Dirty(slotEnt.Value, slotpaint); - } - } - } - - _popup.PopupEntity(Loc.GetString("paint-success", ("target", args.Target)), args.User, args.User, PopupType.Medium); - _appearanceSystem.SetData(target, PaintVisuals.Painted, true); - Dirty(target, paint); - args.Handled = true; - return; - } - - if (!TryPaint(entity, target)) - { - _popup.PopupEntity(Loc.GetString("paint-empty", ("used", args.Used)), args.User, args.User, PopupType.Medium); - return; - } - } - - private bool TryPaint(Entity reagent, EntityUid target) - { - if (HasComp(target) || HasComp(target)) - return false; - - if (_solutionContainer.TryGetSolution(reagent.Owner, reagent.Comp.Solution, out _, out var solution)) - { - var quantity = solution.RemoveReagent(reagent.Comp.Reagent, reagent.Comp.ConsumptionUnit); - if (quantity > 0)// checks quantity of solution is more than 0. - return true; - - if (quantity < 1) - return false; - } - return false; - } -} diff --git a/Content.Server/Paper/PaperRandomStoryComponent.cs b/Content.Server/Paper/PaperRandomStoryComponent.cs new file mode 100644 index 0000000000..7c5744f087 --- /dev/null +++ b/Content.Server/Paper/PaperRandomStoryComponent.cs @@ -0,0 +1,14 @@ +namespace Content.Server.Paper; + +/// +/// Adds randomly generated stories to Paper component +/// +[RegisterComponent, Access(typeof(PaperRandomStorySystem))] +public sealed partial class PaperRandomStoryComponent : Component +{ + [DataField] + public List? StorySegments; + + [DataField] + public string StorySeparator = " "; +} diff --git a/Content.Server/Paper/PaperRandomStorySystem.cs b/Content.Server/Paper/PaperRandomStorySystem.cs new file mode 100644 index 0000000000..e7712009c2 --- /dev/null +++ b/Content.Server/Paper/PaperRandomStorySystem.cs @@ -0,0 +1,29 @@ +using Content.Server.RandomMetadata; + +namespace Content.Server.Paper; + +public sealed class PaperRandomStorySystem : EntitySystem +{ + + [Dependency] private readonly RandomMetadataSystem _randomMeta = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnMapinit); + } + + private void OnMapinit(Entity paperStory, ref MapInitEvent ev) + { + if (!TryComp(paperStory, out var paper)) + return; + + if (paperStory.Comp.StorySegments == null) + return; + + var story = _randomMeta.GetRandomFromSegments(paperStory.Comp.StorySegments, paperStory.Comp.StorySeparator); + + paper.Content += $"\n{story}"; + } +} diff --git a/Content.Server/Popups/PopupSystem.cs b/Content.Server/Popups/PopupSystem.cs index c5eb3819b5..237ca33a4d 100644 --- a/Content.Server/Popups/PopupSystem.cs +++ b/Content.Server/Popups/PopupSystem.cs @@ -88,7 +88,7 @@ namespace Content.Server.Popups RaiseNetworkEvent(new PopupEntityEvent(message, type, GetNetEntity(uid)), actor.PlayerSession); } - public override void PopupClient(string? message, EntityUid uid, EntityUid recipient, PopupType type = PopupType.Small) + public override void PopupClient(string? message, EntityUid uid, EntityUid? recipient, PopupType type = PopupType.Small) { // do nothing duh its for client only } diff --git a/Content.Server/Radio/EntitySystems/JammerSystem.cs b/Content.Server/Radio/EntitySystems/JammerSystem.cs index 1258cc10fa..5a2a854017 100644 --- a/Content.Server/Radio/EntitySystems/JammerSystem.cs +++ b/Content.Server/Radio/EntitySystems/JammerSystem.cs @@ -54,14 +54,10 @@ public sealed class JammerSystem : EntitySystem if (activated) { EnsureComp(uid); - var stationId = _stationSystem.GetOwningStation(uid); - if (stationId != null && _singletonServerSystem.TryGetActiveServerAddress(stationId.Value, out var netId)) - { - EnsureComp(uid, out var jammingComp); - jammingComp.Range = comp.Range; - jammingComp.JammableNetworks.Add(netId); - Dirty(uid, jammingComp); - } + EnsureComp(uid, out var jammingComp); + jammingComp.Range = comp.Range; + jammingComp.JammableNetworks.Add(DeviceNetworkComponent.DeviceNetIdDefaults.Wireless.ToString()); + Dirty(uid, jammingComp); } else { diff --git a/Content.Server/RandomMetadata/RandomMetadataSystem.cs b/Content.Server/RandomMetadata/RandomMetadataSystem.cs index ebec4d5249..c088d57fd9 100644 --- a/Content.Server/RandomMetadata/RandomMetadataSystem.cs +++ b/Content.Server/RandomMetadata/RandomMetadataSystem.cs @@ -1,4 +1,4 @@ -using Content.Shared.Dataset; +using Content.Shared.Dataset; using JetBrains.Annotations; using Robust.Shared.Prototypes; using Robust.Shared.Random; @@ -48,8 +48,8 @@ public sealed class RandomMetadataSystem : EntitySystem foreach (var segment in segments) { outputSegments.Add(_prototype.TryIndex(segment, out var proto) - ? _random.Pick(proto.Values) - : segment); + ? Loc.GetString(_random.Pick(proto.Values)) + : Loc.GetString(segment)); } return string.Join(separator, outputSegments); } diff --git a/Content.Server/Resist/EscapeInventorySystem.cs b/Content.Server/Resist/EscapeInventorySystem.cs index 6bce38fbac..35c7d0bc65 100644 --- a/Content.Server/Resist/EscapeInventorySystem.cs +++ b/Content.Server/Resist/EscapeInventorySystem.cs @@ -1,5 +1,5 @@ using Content.Server.Popups; -using Content.Server.Storage.Components; +using Content.Shared.Storage.Components; using Content.Shared.ActionBlocker; using Content.Shared.DoAfter; using Content.Shared.Hands.EntitySystems; diff --git a/Content.Server/Salvage/SalvageSystem.ExpeditionConsole.cs b/Content.Server/Salvage/SalvageSystem.ExpeditionConsole.cs index f7f3718208..61636bea7c 100644 --- a/Content.Server/Salvage/SalvageSystem.ExpeditionConsole.cs +++ b/Content.Server/Salvage/SalvageSystem.ExpeditionConsole.cs @@ -1,10 +1,16 @@ +using Content.Shared.Shuttles.Components; using Content.Shared.Procedural; using Content.Shared.Salvage.Expeditions; +using Content.Shared.Dataset; +using Robust.Shared.Prototypes; namespace Content.Server.Salvage; public sealed partial class SalvageSystem { + [ValidatePrototypeId] + public const string CoordinatesDisk = "CoordinatesDisk"; + private void OnSalvageClaimMessage(EntityUid uid, SalvageExpeditionConsoleComponent component, ClaimSalvageMessage args) { var station = _station.GetOwningStation(uid); @@ -15,11 +21,16 @@ public sealed partial class SalvageSystem if (!data.Missions.TryGetValue(args.Index, out var missionparams)) return; - SpawnMission(missionparams, station.Value); + var cdUid = Spawn(CoordinatesDisk, Transform(uid).Coordinates); + SpawnMission(missionparams, station.Value, cdUid); data.ActiveMission = args.Index; var mission = GetMission(_prototypeManager.Index(missionparams.Difficulty), missionparams.Seed); data.NextOffer = _timing.CurTime + mission.Duration + TimeSpan.FromSeconds(1); + + _labelSystem.Label(cdUid, GetFTLName(_prototypeManager.Index("names_borer"), missionparams.Seed)); + _audio.PlayPvs(component.PrintSound, uid); + UpdateConsoles((station.Value, data)); } diff --git a/Content.Server/Salvage/SalvageSystem.Expeditions.cs b/Content.Server/Salvage/SalvageSystem.Expeditions.cs index 7e4a9c9310..839730ec87 100644 --- a/Content.Server/Salvage/SalvageSystem.Expeditions.cs +++ b/Content.Server/Salvage/SalvageSystem.Expeditions.cs @@ -8,6 +8,7 @@ using Content.Shared.Salvage.Expeditions; using Robust.Shared.CPUJob.JobQueues; using Robust.Shared.CPUJob.JobQueues.Queues; using Robust.Shared.GameStates; +using Robust.Shared.Map; namespace Content.Server.Salvage; @@ -148,7 +149,7 @@ public sealed partial class SalvageSystem return new SalvageExpeditionConsoleState(component.NextOffer, component.Claimed, component.Cooldown, component.ActiveMission, missions); } - private void SpawnMission(SalvageMissionParams missionParams, EntityUid station) + private void SpawnMission(SalvageMissionParams missionParams, EntityUid station, EntityUid? coordinatesDisk) { var cancelToken = new CancellationTokenSource(); var job = new SpawnSalvageMissionJob( @@ -162,7 +163,9 @@ public sealed partial class SalvageSystem _biome, _dungeon, _metaData, + _transform, station, + coordinatesDisk, missionParams, cancelToken.Token); diff --git a/Content.Server/Salvage/SalvageSystem.cs b/Content.Server/Salvage/SalvageSystem.cs index a1a3b686b2..9af4736345 100644 --- a/Content.Server/Salvage/SalvageSystem.cs +++ b/Content.Server/Salvage/SalvageSystem.cs @@ -32,6 +32,7 @@ using Robust.Shared.Audio; using Robust.Shared.Audio.Systems; using Robust.Shared.Map.Components; using Robust.Shared.Timing; +using Content.Server.Labels; namespace Content.Server.Salvage { @@ -39,6 +40,7 @@ namespace Content.Server.Salvage { [Dependency] private readonly IChatManager _chat = default!; [Dependency] private readonly IConfigurationManager _configurationManager = default!; + [Dependency] private readonly IEntityManager _entManager = default!; [Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly ILogManager _logManager = default!; [Dependency] private readonly IMapManager _mapManager = default!; @@ -48,6 +50,7 @@ namespace Content.Server.Salvage [Dependency] private readonly BiomeSystem _biome = default!; [Dependency] private readonly DungeonSystem _dungeon = default!; [Dependency] private readonly GravitySystem _gravity = default!; + [Dependency] private readonly LabelSystem _labelSystem = default!; [Dependency] private readonly MapLoaderSystem _map = default!; [Dependency] private readonly MetaDataSystem _metaData = default!; [Dependency] private readonly RadioSystem _radioSystem = default!; diff --git a/Content.Server/Salvage/SpawnSalvageMissionJob.cs b/Content.Server/Salvage/SpawnSalvageMissionJob.cs index e2b17b5872..180c8d145c 100644 --- a/Content.Server/Salvage/SpawnSalvageMissionJob.cs +++ b/Content.Server/Salvage/SpawnSalvageMissionJob.cs @@ -33,6 +33,9 @@ using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Timing; using Robust.Shared.Utility; +using Content.Server.Shuttles.Components; +using Content.Shared.Coordinates; +using Content.Shared.Shuttles.Components; namespace Content.Server.Salvage; @@ -46,8 +49,10 @@ public sealed class SpawnSalvageMissionJob : Job private readonly BiomeSystem _biome; private readonly DungeonSystem _dungeon; private readonly MetaDataSystem _metaData; + private readonly SharedTransformSystem _xforms; public readonly EntityUid Station; + public readonly EntityUid? CoordinatesDisk; private readonly SalvageMissionParams _missionParams; private readonly ISawmill _sawmill; @@ -63,7 +68,9 @@ public sealed class SpawnSalvageMissionJob : Job BiomeSystem biome, DungeonSystem dungeon, MetaDataSystem metaData, + SharedTransformSystem xform, EntityUid station, + EntityUid? coordinatesDisk, SalvageMissionParams missionParams, CancellationToken cancellation = default) : base(maxTime, cancellation) { @@ -75,7 +82,9 @@ public sealed class SpawnSalvageMissionJob : Job _biome = biome; _dungeon = dungeon; _metaData = metaData; + _xforms = xform; Station = station; + CoordinatesDisk = coordinatesDisk; _missionParams = missionParams; _sawmill = logManager.GetSawmill("salvage_job"); #if !DEBUG @@ -94,6 +103,18 @@ public sealed class SpawnSalvageMissionJob : Job var random = new Random(_missionParams.Seed); var destComp = _entManager.AddComponent(mapUid); destComp.BeaconsOnly = true; + destComp.RequireCoordinateDisk = true; + destComp.Enabled = true; + _metaData.SetEntityName(mapUid, SharedSalvageSystem.GetFTLName(_prototypeManager.Index("names_borer"), _missionParams.Seed)); + _entManager.AddComponent(mapUid); + + // Saving the mission mapUid to a CD is made optional, in case one is somehow made in a process without a CD entity + if (CoordinatesDisk.HasValue) + { + var cd = _entManager.EnsureComponent(CoordinatesDisk.Value); + cd.Destination = mapUid; + _entManager.Dirty(CoordinatesDisk.Value, cd); + } // Setup mission configs // As we go through the config the rating will deplete so we'll go for most important to least important. @@ -144,11 +165,6 @@ public sealed class SpawnSalvageMissionJob : Job expedition.EndTime = _timing.CurTime + mission.Duration; expedition.MissionParams = _missionParams; - // Don't want consoles to have the incorrect name until refreshed. - var ftlUid = _entManager.CreateEntityUninitialized("FTLPoint", new EntityCoordinates(mapUid, grid.TileSizeHalfVector)); - _metaData.SetEntityName(ftlUid, SharedSalvageSystem.GetFTLName(_prototypeManager.Index("names_borer"), _missionParams.Seed)); - _entManager.InitializeAndStartEntity(ftlUid); - var landingPadRadius = 24; var minDungeonOffset = landingPadRadius + 4; diff --git a/Content.Server/Sandbox/SandboxSystem.cs b/Content.Server/Sandbox/SandboxSystem.cs index b8bf123090..30fe4e0fe9 100644 --- a/Content.Server/Sandbox/SandboxSystem.cs +++ b/Content.Server/Sandbox/SandboxSystem.cs @@ -14,6 +14,7 @@ using Robust.Server.Placement; using Robust.Server.Player; using Robust.Shared.Enums; using Robust.Shared.Player; +using Robust.Shared.Prototypes; namespace Content.Server.Sandbox { @@ -121,7 +122,7 @@ namespace Content.Server.Sandbox var allAccess = PrototypeManager .EnumeratePrototypes() - .Select(p => p.ID).ToArray(); + .Select(p => new ProtoId(p.ID)).ToList(); if (_inventory.TryGetSlotEntity(attached, "id", out var slotEntity)) { diff --git a/Content.Server/Screens/Systems/ScreenSystem.cs b/Content.Server/Screens/Systems/ScreenSystem.cs index 19790f64d5..782fe38c88 100644 --- a/Content.Server/Screens/Systems/ScreenSystem.cs +++ b/Content.Server/Screens/Systems/ScreenSystem.cs @@ -56,6 +56,7 @@ public sealed class ScreenSystem : EntitySystem ) { _appearanceSystem.SetData(uid, TextScreenVisuals.DefaultText, text); + _appearanceSystem.SetData(uid, TextScreenVisuals.ScreenText, text); } } diff --git a/Content.Server/Shuttles/Components/EscapePodComponent.cs b/Content.Server/Shuttles/Components/EscapePodComponent.cs index 72c8024e12..d717e97441 100644 --- a/Content.Server/Shuttles/Components/EscapePodComponent.cs +++ b/Content.Server/Shuttles/Components/EscapePodComponent.cs @@ -9,7 +9,7 @@ namespace Content.Server.Shuttles.Components; [RegisterComponent, Access(typeof(EmergencyShuttleSystem)), AutoGenerateComponentPause] public sealed partial class EscapePodComponent : Component { - [DataField("launchTime", customTypeSerializer:typeof(TimeOffsetSerializer))] + [DataField(customTypeSerializer:typeof(TimeOffsetSerializer))] [AutoPausedField] public TimeSpan? LaunchTime; } diff --git a/Content.Server/Shuttles/Components/ShuttleConsoleComponent.cs b/Content.Server/Shuttles/Components/ShuttleConsoleComponent.cs index 91cecde044..03e262cef5 100644 --- a/Content.Server/Shuttles/Components/ShuttleConsoleComponent.cs +++ b/Content.Server/Shuttles/Components/ShuttleConsoleComponent.cs @@ -14,5 +14,11 @@ namespace Content.Server.Shuttles.Components /// [DataField("zoom")] public Vector2 Zoom = new(1.5f, 1.5f); + + /// + /// Should this console have access to restricted FTL destinations? + /// + [ViewVariables(VVAccess.ReadWrite), DataField("whitelistSpecific")] + public List FTLWhitelist = new List(); } } diff --git a/Content.Server/Shuttles/Systems/EmergencyShuttleSystem.cs b/Content.Server/Shuttles/Systems/EmergencyShuttleSystem.cs index a7f83f2e15..c043861b37 100644 --- a/Content.Server/Shuttles/Systems/EmergencyShuttleSystem.cs +++ b/Content.Server/Shuttles/Systems/EmergencyShuttleSystem.cs @@ -418,7 +418,7 @@ public sealed partial class EmergencyShuttleSystem : EntitySystem } var mapId = _mapManager.CreateMap(); - var grid = _map.LoadGrid(mapId, component.Map.ToString(), new MapLoadOptions() + var grid = _map.LoadGrid(mapId, component.Map.ToString(), new MapLoadOptions() { LoadMap = false, }); diff --git a/Content.Server/Shuttles/Systems/ShuttleConsoleSystem.FTL.cs b/Content.Server/Shuttles/Systems/ShuttleConsoleSystem.FTL.cs index 7606d190a4..c214bb015c 100644 --- a/Content.Server/Shuttles/Systems/ShuttleConsoleSystem.FTL.cs +++ b/Content.Server/Shuttles/Systems/ShuttleConsoleSystem.FTL.cs @@ -44,6 +44,10 @@ public sealed partial class ShuttleConsoleSystem } var nCoordinates = new NetCoordinates(GetNetEntity(targetXform.ParentUid), targetXform.LocalPosition); + if (targetXform.ParentUid == EntityUid.Invalid) + { + nCoordinates = new NetCoordinates(GetNetEntity(beaconEnt), targetXform.LocalPosition); + } // Check target exists if (!_shuttle.CanFTLBeacon(nCoordinates)) @@ -128,7 +132,7 @@ public sealed partial class ShuttleConsoleSystem } // Check shuttle can FTL to this target. - if (!_shuttle.CanFTLTo(shuttleUid.Value, targetMap)) + if (!_shuttle.CanFTLTo(shuttleUid.Value, targetMap, ent)) { return; } diff --git a/Content.Server/Speech/Components/SouthernAccentComponent.cs b/Content.Server/Speech/Components/SouthernAccentComponent.cs new file mode 100644 index 0000000000..0c44290086 --- /dev/null +++ b/Content.Server/Speech/Components/SouthernAccentComponent.cs @@ -0,0 +1,8 @@ +using Content.Server.Speech.EntitySystems; + +namespace Content.Server.Speech.Components; + +[RegisterComponent] +[Access(typeof(SouthernAccentSystem))] +public sealed partial class SouthernAccentComponent : Component +{ } diff --git a/Content.Server/Speech/EntitySystems/SouthernAccentSystem.cs b/Content.Server/Speech/EntitySystems/SouthernAccentSystem.cs new file mode 100644 index 0000000000..4d401367cc --- /dev/null +++ b/Content.Server/Speech/EntitySystems/SouthernAccentSystem.cs @@ -0,0 +1,28 @@ +using System.Text.RegularExpressions; +using Content.Server.Speech.Components; + +namespace Content.Server.Speech.EntitySystems; + +public sealed class SouthernAccentSystem : EntitySystem +{ + [Dependency] private readonly ReplacementAccentSystem _replacement = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnAccent); + } + + private void OnAccent(EntityUid uid, SouthernAccentComponent component, AccentGetEvent args) + { + var message = args.Message; + + message = _replacement.ApplyReplacements(message, "southern"); + + //They shoulda started runnin' an' hidin' from me! + message = Regex.Replace(message, @"ing\b", "in'"); + message = Regex.Replace(message, @"\band\b", "an'"); + message = Regex.Replace(message, "d've", "da"); + args.Message = message; + } +}; diff --git a/Content.Server/Storage/Components/SecretStashComponent.cs b/Content.Server/Storage/Components/SecretStashComponent.cs deleted file mode 100644 index a63cb074ad..0000000000 --- a/Content.Server/Storage/Components/SecretStashComponent.cs +++ /dev/null @@ -1,39 +0,0 @@ -using Content.Server.Storage.EntitySystems; -using Content.Shared.Containers.ItemSlots; -using Content.Shared.Item; -using Content.Shared.Toilet; -using Robust.Shared.Containers; -using Robust.Shared.Prototypes; - -namespace Content.Server.Storage.Components -{ - /// - /// Logic for a secret slot stash, like plant pot or toilet cistern. - /// Unlike it doesn't have interaction logic or verbs. - /// Other classes like should implement it. - /// - [RegisterComponent] - [Access(typeof(SecretStashSystem))] - public sealed partial class SecretStashComponent : Component - { - /// - /// Max item size that can be fitted into secret stash. - /// - [DataField("maxItemSize")] - public ProtoId MaxItemSize = "Small"; - - /// - /// IC secret stash name. For example "the toilet cistern". - /// If empty string, will replace it with entity name in init. - /// - [DataField("secretPartName", readOnly: true)] - public string SecretPartName { get; set; } = ""; - - /// - /// Container used to keep secret stash item. - /// - [ViewVariables] - public ContainerSlot ItemContainer = default!; - - } -} diff --git a/Content.Server/Storage/EntitySystems/BluespaceLockerSystem.cs b/Content.Server/Storage/EntitySystems/BluespaceLockerSystem.cs index 356768769b..838311c1aa 100644 --- a/Content.Server/Storage/EntitySystems/BluespaceLockerSystem.cs +++ b/Content.Server/Storage/EntitySystems/BluespaceLockerSystem.cs @@ -3,6 +3,7 @@ using Content.Server.Explosion.EntitySystems; using Content.Server.Resist; using Content.Server.Station.Components; using Content.Server.Storage.Components; +using Content.Shared.Access; using Content.Shared.Access.Components; using Content.Shared.Coordinates; using Content.Shared.DoAfter; @@ -14,6 +15,7 @@ using Content.Shared.Tools.Systems; using Robust.Shared.Containers; using Robust.Shared.Random; using Robust.Shared.Timing; +using Robust.Shared.Prototypes; namespace Content.Server.Storage.EntitySystems; @@ -138,7 +140,7 @@ public sealed class BluespaceLockerSystem : EntitySystem } /// True if any HashSet in would grant access to - private bool AccessMatch(IReadOnlyCollection>? a, IReadOnlyCollection>? b) + private bool AccessMatch(IReadOnlyCollection>>? a, IReadOnlyCollection>>? b) { if ((a == null || a.Count == 0) && (b == null || b.Count == 0)) return true; diff --git a/Content.Server/Storage/EntitySystems/SpawnItemsOnUseSystem.cs b/Content.Server/Storage/EntitySystems/SpawnItemsOnUseSystem.cs index 0b4b13d6e4..c49bfdec93 100644 --- a/Content.Server/Storage/EntitySystems/SpawnItemsOnUseSystem.cs +++ b/Content.Server/Storage/EntitySystems/SpawnItemsOnUseSystem.cs @@ -80,6 +80,11 @@ namespace Content.Server.Storage.EntitySystems _adminLogger.Add(LogType.EntitySpawn, LogImpact.Low, $"{ToPrettyString(args.User)} used {ToPrettyString(uid)} which spawned {ToPrettyString(entityToPlaceInHands.Value)}"); } + if (component.Sound != null) + { + _audio.PlayPvs(component.Sound, uid); + } + component.Uses--; // Delete entity only if component was successfully used @@ -92,7 +97,6 @@ namespace Content.Server.Storage.EntitySystems if (entityToPlaceInHands != null) { _hands.PickupOrDrop(args.User, entityToPlaceInHands.Value); - _audio.PlayPvs(component.Sound, entityToPlaceInHands.Value); } } } diff --git a/Content.Server/Store/Components/StoreComponent.cs b/Content.Server/Store/Components/StoreComponent.cs index 063e25fbf9..0b7dbbea09 100644 --- a/Content.Server/Store/Components/StoreComponent.cs +++ b/Content.Server/Store/Components/StoreComponent.cs @@ -78,6 +78,13 @@ public sealed partial class StoreComponent : Component [ViewVariables, DataField] public bool RefundAllowed; + /// + /// Checks if store can be opened by the account owner only. + /// Not meant to be used with uplinks. + /// + [ViewVariables(VVAccess.ReadWrite), DataField] + public bool OwnerOnly; + /// /// The map the store was originally from, used to block refunds if the map is changed /// diff --git a/Content.Server/Store/Systems/StoreSystem.Ui.cs b/Content.Server/Store/Systems/StoreSystem.Ui.cs index 49db980451..e6c4eb0cce 100644 --- a/Content.Server/Store/Systems/StoreSystem.Ui.cs +++ b/Content.Server/Store/Systems/StoreSystem.Ui.cs @@ -15,6 +15,7 @@ using Content.Shared.UserInterface; using Robust.Server.GameObjects; using Robust.Shared.Audio.Systems; using Robust.Shared.Player; +using Robust.Shared.Prototypes; namespace Content.Server.Store.Systems; @@ -29,6 +30,7 @@ public sealed partial class StoreSystem [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly StackSystem _stack = default!; [Dependency] private readonly UserInterfaceSystem _ui = default!; + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; private void InitializeUi() { @@ -259,7 +261,7 @@ public sealed partial class StoreSystem //log dat shit. _admin.Add(LogType.StorePurchase, LogImpact.Low, - $"{ToPrettyString(buyer):player} purchased listing \"{Loc.GetString(listing.Name)}\" from {ToPrettyString(uid)}"); + $"{ToPrettyString(buyer):player} purchased listing \"{ListingLocalisationHelpers.GetLocalisedNameOrEntityName(listing, _prototypeManager)}\" from {ToPrettyString(uid)}"); listing.PurchaseAmount++; //track how many times something has been purchased _audio.PlayEntity(component.BuySuccessSound, msg.Session, uid); //cha-ching! diff --git a/Content.Server/Store/Systems/StoreSystem.cs b/Content.Server/Store/Systems/StoreSystem.cs index 8ce1f9bb83..56426e0404 100644 --- a/Content.Server/Store/Systems/StoreSystem.cs +++ b/Content.Server/Store/Systems/StoreSystem.cs @@ -10,6 +10,7 @@ using JetBrains.Annotations; using Robust.Server.GameObjects; using Robust.Shared.Prototypes; using System.Linq; +using Robust.Shared.Utility; namespace Content.Server.Store.Systems; @@ -26,6 +27,7 @@ public sealed partial class StoreSystem : EntitySystem { base.Initialize(); + SubscribeLocalEvent(OnStoreOpenAttempt); SubscribeLocalEvent(OnAfterInteract); SubscribeLocalEvent(BeforeActivatableUiOpen); @@ -65,6 +67,21 @@ public sealed partial class StoreSystem : EntitySystem RaiseLocalEvent(uid, ref ev, true); } + private void OnStoreOpenAttempt(EntityUid uid, StoreComponent component, ActivatableUIOpenAttemptEvent args) + { + if (!component.OwnerOnly) + return; + + component.AccountOwner ??= args.User; + DebugTools.Assert(component.AccountOwner != null); + + if (component.AccountOwner == args.User) + return; + + _popup.PopupEntity(Loc.GetString("store-not-account-owner", ("store", uid)), uid, args.User); + args.Cancel(); + } + private void OnAfterInteract(EntityUid uid, CurrencyComponent component, AfterInteractEvent args) { if (args.Handled || !args.CanReach) diff --git a/Content.Server/Toilet/ToiletSystem.cs b/Content.Server/Toilet/ToiletSystem.cs index 8bf8457e07..e184ddf0d5 100644 --- a/Content.Server/Toilet/ToiletSystem.cs +++ b/Content.Server/Toilet/ToiletSystem.cs @@ -1,197 +1,8 @@ -using Content.Server.Body.Systems; -using Content.Shared.Buckle; -using Content.Server.Popups; -using Content.Server.Storage.Components; -using Content.Server.Storage.EntitySystems; -using Content.Shared.Audio; -using Content.Shared.Body.Components; -using Content.Shared.Body.Part; -using Content.Shared.Buckle.Components; -using Content.Shared.Examine; -using Content.Shared.IdentityManagement; -using Content.Shared.Interaction; -using Content.Shared.Interaction.Events; -using Content.Shared.Popups; -using Content.Shared.Toilet; -using Content.Shared.Tools; -using Content.Shared.Tools.Components; -using Content.Shared.Verbs; -using Robust.Shared.Audio; -using Robust.Shared.Audio.Systems; -using Robust.Shared.Player; -using Robust.Shared.Random; -using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem; +using Content.Shared.Toilet.Systems; -namespace Content.Server.Toilet +namespace Content.Server.Toilet; + +public sealed class ToiletSystem : SharedToiletSystem { - public sealed class ToiletSystem : EntitySystem - { - [Dependency] private readonly IRobustRandom _random = default!; - [Dependency] private readonly SharedAppearanceSystem _appearance = default!; - [Dependency] private readonly BodySystem _body = default!; - [Dependency] private readonly SharedAudioSystem _audio = default!; - [Dependency] private readonly SecretStashSystem _secretStash = default!; - [Dependency] private readonly PopupSystem _popup = default!; - [Dependency] private readonly SharedToolSystem _tool = default!; - public override void Initialize() - { - base.Initialize(); - SubscribeLocalEvent(OnInit); - SubscribeLocalEvent(OnMapInit); - SubscribeLocalEvent(OnInteractUsing); - SubscribeLocalEvent(OnInteractHand); - SubscribeLocalEvent(OnExamine); - SubscribeLocalEvent(OnSuicide); - SubscribeLocalEvent(OnToiletPried); - SubscribeLocalEvent>(OnToggleSeatVerb); - } - - private void OnSuicide(EntityUid uid, ToiletComponent component, SuicideEvent args) - { - if (args.Handled) - return; - - // Check that victim has a head - // FIXME: since suiciding turns you into a ghost immediately, both messages are seen, not sure how this can be fixed - if (TryComp(args.Victim, out var body) && - _body.BodyHasPartType(args.Victim, BodyPartType.Head, body)) - { - var othersMessage = Loc.GetString("toilet-component-suicide-head-message-others", - ("victim", Identity.Entity(args.Victim, EntityManager)), ("owner", uid)); - _popup.PopupEntity(othersMessage, uid, Filter.PvsExcept(args.Victim), true, PopupType.MediumCaution); - - var selfMessage = Loc.GetString("toilet-component-suicide-head-message", - ("owner", uid)); - _popup.PopupEntity(selfMessage, uid, args.Victim, PopupType.LargeCaution); - - args.SetHandled(SuicideKind.Asphyxiation); - } - else - { - var othersMessage = Loc.GetString("toilet-component-suicide-message-others", - ("victim", Identity.Entity(args.Victim, EntityManager)), ("owner", uid)); - _popup.PopupEntity(othersMessage, uid, Filter.PvsExcept(uid), true, PopupType.MediumCaution); - - var selfMessage = Loc.GetString("toilet-component-suicide-message", - ("owner", uid)); - _popup.PopupEntity(selfMessage, uid, args.Victim, PopupType.LargeCaution); - - args.SetHandled(SuicideKind.Blunt); - } - } - - private void OnInit(EntityUid uid, ToiletComponent component, ComponentInit args) - { - EnsureComp(uid); - } - - private void OnMapInit(EntityUid uid, ToiletComponent component, MapInitEvent args) - { - // roll is toilet seat will be up or down - component.IsSeatUp = _random.Prob(0.5f); - UpdateSprite(uid, component); - } - - private void OnInteractUsing(EntityUid uid, ToiletComponent component, InteractUsingEvent args) - { - if (args.Handled) - return; - - // are player trying place or lift of cistern lid? - if (_tool.UseTool(args.Used, args.User, uid, component.PryLidTime, component.PryingQuality, new ToiletPryDoAfterEvent())) - { - args.Handled = true; - } - // maybe player trying to hide something inside cistern? - else if (component.LidOpen) - { - args.Handled = true; - _secretStash.TryHideItem(uid, args.User, args.Used); - } - } - - private void OnInteractHand(EntityUid uid, ToiletComponent component, InteractHandEvent args) - { - if (args.Handled) - return; - - // trying get something from stash? - if (component.LidOpen) - { - var gotItem = _secretStash.TryGetItem(uid, args.User); - if (gotItem) - { - args.Handled = true; - return; - } - } - - args.Handled = true; - } - - private void OnToggleSeatVerb(EntityUid uid, ToiletComponent component, GetVerbsEvent args) - { - if (!args.CanInteract || !args.CanAccess || !CanToggle(uid)) - return; - - var alterToiletSeatText = component.IsSeatUp ? Loc.GetString("toilet-seat-close") : Loc.GetString("toilet-seat-open"); - - var verb = new AlternativeVerb() - { - Act = () => { - if (CanToggle(uid)) - ToggleToiletSeat(uid, component); - }, - Text = alterToiletSeatText - }; - - args.Verbs.Add(verb); - } - - private void OnExamine(EntityUid uid, ToiletComponent component, ExaminedEvent args) - { - if (args.IsInDetailsRange && component.LidOpen) - { - if (_secretStash.HasItemInside(uid)) - { - var msg = Loc.GetString("toilet-component-on-examine-found-hidden-item"); - args.PushMarkup(msg); - } - } - } - - private void OnToiletPried(EntityUid uid, ToiletComponent toilet, ToiletPryDoAfterEvent args) - { - if (args.Cancelled) - return; - - toilet.LidOpen = !toilet.LidOpen; - UpdateSprite(uid, toilet); - } - - public bool CanToggle(EntityUid uid) - { - return TryComp(uid, out var strap) && strap.BuckledEntities.Count == 0; - } - - public void ToggleToiletSeat(EntityUid uid, ToiletComponent? component = null) - { - if (!Resolve(uid, ref component)) - return; - - component.IsSeatUp = !component.IsSeatUp; - _audio.PlayPvs(component.ToggleSound, uid, AudioParams.Default.WithVariation(SharedContentAudioSystem.DefaultVariation)); - UpdateSprite(uid, component); - } - - private void UpdateSprite(EntityUid uid, ToiletComponent component) - { - if (!TryComp(uid, out var appearance)) - return; - - _appearance.SetData(uid, ToiletVisuals.LidOpen, component.LidOpen, appearance); - _appearance.SetData(uid, ToiletVisuals.SeatUp, component.IsSeatUp, appearance); - } - } } diff --git a/Content.Server/UserInterface/ActivatableUIComponent.cs b/Content.Server/UserInterface/ActivatableUIComponent.cs index 54639dd2b0..cc0e5008e4 100644 --- a/Content.Server/UserInterface/ActivatableUIComponent.cs +++ b/Content.Server/UserInterface/ActivatableUIComponent.cs @@ -1,3 +1,6 @@ +using Content.Shared.Whitelist; +using Robust.Server.GameObjects; +using Robust.Server.Player; using Robust.Shared.Player; using Robust.Shared.Serialization.TypeSerializers.Implementations; @@ -34,12 +37,19 @@ namespace Content.Server.UserInterface [DataField] public bool RequireHands = true; + /// + /// Entities that are required to open this UI. + /// + [DataField("allowedItems")] + [ViewVariables(VVAccess.ReadWrite)] + public EntityWhitelist? AllowedItems = null; + /// /// Whether you can activate this ui with activateinhand or not /// [ViewVariables(VVAccess.ReadWrite)] [DataField] - public bool rightClickOnly = false; + public bool RightClickOnly; /// /// Whether spectators (non-admin ghosts) should be allowed to view this UI. @@ -63,4 +73,3 @@ namespace Content.Server.UserInterface public ICommonSession? CurrentSingleUser; } } - diff --git a/Content.Server/UserInterface/ActivatableUISystem.cs b/Content.Server/UserInterface/ActivatableUISystem.cs index 387221e00c..e3a11af429 100644 --- a/Content.Server/UserInterface/ActivatableUISystem.cs +++ b/Content.Server/UserInterface/ActivatableUISystem.cs @@ -26,6 +26,7 @@ public sealed partial class ActivatableUISystem : EntitySystem SubscribeLocalEvent(OnActivate); SubscribeLocalEvent(OnUseInHand); + SubscribeLocalEvent(OnInteractUsing); SubscribeLocalEvent(OnHandDeselected); SubscribeLocalEvent((uid, aui, _) => CloseAll(uid, aui)); // *THIS IS A BLATANT WORKAROUND!* RATIONALE: Microwaves need it @@ -100,12 +101,20 @@ public sealed partial class ActivatableUISystem : EntitySystem if (args.Handled) return; - if (component.rightClickOnly) + if (component.RightClickOnly) return; args.Handled = InteractUI(args.User, uid, component); } + private void OnInteractUsing(EntityUid uid, ActivatableUIComponent component, InteractUsingEvent args) + { + if (args.Handled) return; + if (component.AllowedItems == null) return; + if (!component.AllowedItems.IsValid(args.Used, EntityManager)) return; + args.Handled = InteractUI(args.User, uid, component); + } + private void OnParentChanged(EntityUid uid, ActivatableUIComponent aui, ref EntParentChangedMessage args) { CloseAll(uid, aui); diff --git a/Content.Server/Weapons/Melee/MeleeWeaponSystem.cs b/Content.Server/Weapons/Melee/MeleeWeaponSystem.cs index a01a324013..2612e99ec9 100644 --- a/Content.Server/Weapons/Melee/MeleeWeaponSystem.cs +++ b/Content.Server/Weapons/Melee/MeleeWeaponSystem.cs @@ -1,8 +1,4 @@ -using Content.Server.Body.Components; -using Content.Server.Body.Systems; using Content.Server.Chat.Systems; -using Content.Server.Chemistry.Components; -using Content.Server.Chemistry.Containers.EntitySystems; using Content.Server.CombatMode.Disarm; using Content.Server.Movement.Systems; using Content.Shared.Actions.Events; @@ -14,15 +10,14 @@ using Content.Shared.Database; using Content.Shared.Effects; using Content.Shared.Hands.Components; using Content.Shared.IdentityManagement; -using Content.Shared.Inventory; using Content.Shared.Mobs.Systems; using Content.Shared.Popups; using Content.Shared.Speech.Components; using Content.Shared.StatusEffect; -using Content.Shared.Tag; using Content.Shared.Weapons.Melee; using Content.Shared.Weapons.Melee.Events; using Robust.Shared.Audio; +using Robust.Shared.Audio.Systems; using Robust.Shared.Map; using Robust.Shared.Player; using Robust.Shared.Random; @@ -33,21 +28,17 @@ namespace Content.Server.Weapons.Melee; public sealed class MeleeWeaponSystem : SharedMeleeWeaponSystem { + [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly IRobustRandom _random = default!; - [Dependency] private readonly BloodstreamSystem _bloodstream = default!; [Dependency] private readonly ChatSystem _chat = default!; [Dependency] private readonly DamageExamineSystem _damageExamine = default!; - [Dependency] private readonly InventorySystem _inventory = default!; [Dependency] private readonly LagCompensationSystem _lag = default!; [Dependency] private readonly MobStateSystem _mobState = default!; [Dependency] private readonly SharedColorFlashEffectSystem _color = default!; - [Dependency] private readonly SolutionContainerSystem _solutions = default!; - [Dependency] private readonly TagSystem _tag = default!; public override void Initialize() { base.Initialize(); - SubscribeLocalEvent(OnChemicalInjectorHit); SubscribeLocalEvent(OnSpeechHit); SubscribeLocalEvent(OnMeleeExamineDamage); } @@ -158,7 +149,8 @@ public sealed class MeleeWeaponSystem : SharedMeleeWeaponSystem return false; } - Audio.PlayPvs(combatMode.DisarmSuccessSound, user, AudioParams.Default.WithVariation(0.025f).WithVolume(5f)); + _audio.PlayPvs(combatMode.DisarmSuccessSound, user, AudioParams.Default.WithVariation(0.025f).WithVolume(5f)); + AdminLogger.Add(LogType.DisarmedAction, $"{ToPrettyString(user):user} used disarm on {ToPrettyString(target):target}"); var targetEnt = Identity.Entity(target, EntityManager); var userEnt = Identity.Entity(user, EntityManager); @@ -175,7 +167,6 @@ public sealed class MeleeWeaponSystem : SharedMeleeWeaponSystem PopupSystem.PopupEntity(msgOther, user, filterOther, true); PopupSystem.PopupEntity(msgUser, target, user); - if (eventArgs.IsStunned) { @@ -261,47 +252,4 @@ public sealed class MeleeWeaponSystem : SharedMeleeWeaponSystem } } - - private void OnChemicalInjectorHit(Entity entity, ref MeleeHitEvent args) - { - if (!args.IsHit || - !args.HitEntities.Any() || - !_solutions.TryGetSolution(entity.Owner, entity.Comp.Solution, out var solutionContainer)) - { - return; - } - - var hitBloodstreams = new List<(EntityUid Entity, BloodstreamComponent Component)>(); - var bloodQuery = GetEntityQuery(); - - foreach (var hit in args.HitEntities) - { - if (Deleted(hit)) - continue; - - // prevent deathnettles injecting through hardsuits - if (!entity.Comp.PierceArmor && _inventory.TryGetSlotEntity(hit, "outerClothing", out var suit) && _tag.HasTag(suit.Value, "Hardsuit")) - { - PopupSystem.PopupEntity(Loc.GetString("melee-inject-failed-hardsuit", ("weapon", entity.Owner)), args.User, args.User, PopupType.SmallCaution); - continue; - } - - if (bloodQuery.TryGetComponent(hit, out var bloodstream)) - hitBloodstreams.Add((hit, bloodstream)); - } - - if (!hitBloodstreams.Any()) - return; - - var removedSolution = _solutions.SplitSolution(solutionContainer.Value, entity.Comp.TransferAmount * hitBloodstreams.Count); - var removedVol = removedSolution.Volume; - var solutionToInject = removedSolution.SplitSolution(removedVol * entity.Comp.TransferEfficiency); - var volPerBloodstream = solutionToInject.Volume * (1 / hitBloodstreams.Count); - - foreach (var (ent, bloodstream) in hitBloodstreams) - { - var individualInjection = solutionToInject.SplitSolution(volPerBloodstream); - _bloodstream.TryAddToChemicals(ent, individualInjection, bloodstream); - } - } } diff --git a/Content.Server/Weapons/Ranged/Systems/GunSystem.cs b/Content.Server/Weapons/Ranged/Systems/GunSystem.cs index e64657743d..f5f4e3f199 100644 --- a/Content.Server/Weapons/Ranged/Systems/GunSystem.cs +++ b/Content.Server/Weapons/Ranged/Systems/GunSystem.cs @@ -38,7 +38,7 @@ public sealed partial class GunSystem : SharedGunSystem [Dependency] private readonly StaminaSystem _stamina = default!; [Dependency] private readonly StunSystem _stun = default!; - public const float DamagePitchVariation = SharedMeleeWeaponSystem.DamagePitchVariation; + private const float DamagePitchVariation = 0.05f; public const float GunClumsyChance = 0.5f; public override void Initialize() diff --git a/Content.Server/Wires/WiresComponent.cs b/Content.Server/Wires/WiresComponent.cs index 526b73a300..89e1873c00 100644 --- a/Content.Server/Wires/WiresComponent.cs +++ b/Content.Server/Wires/WiresComponent.cs @@ -1,4 +1,5 @@ using Robust.Shared.Audio; +using Robust.Shared.Prototypes; namespace Content.Server.Wires; @@ -15,7 +16,7 @@ public sealed partial class WiresComponent : Component /// The layout ID of this entity's wires. /// [DataField(required: true)] - public string LayoutId { get; set; } = default!; + public ProtoId LayoutId { get; set; } = default!; /// /// The serial number of this board. Randomly generated upon start, diff --git a/Content.Shared/Access/AccessGroupPrototype.cs b/Content.Shared/Access/AccessGroupPrototype.cs index 8d3ed8feea..323fdb91ed 100644 --- a/Content.Shared/Access/AccessGroupPrototype.cs +++ b/Content.Shared/Access/AccessGroupPrototype.cs @@ -14,6 +14,6 @@ public sealed partial class AccessGroupPrototype : IPrototype [IdDataField] public string ID { get; private set; } = default!; - [DataField("tags", required: true, customTypeSerializer: typeof(PrototypeIdHashSetSerializer))] - public HashSet Tags = default!; + [DataField("tags", required: true)] + public HashSet> Tags = default!; } diff --git a/Content.Shared/Access/AccessLevelPrototype.cs b/Content.Shared/Access/AccessLevelPrototype.cs index 8cc5927158..e3a3b426b0 100644 --- a/Content.Shared/Access/AccessLevelPrototype.cs +++ b/Content.Shared/Access/AccessLevelPrototype.cs @@ -17,5 +17,13 @@ namespace Content.Shared.Access /// [DataField("name")] public string? Name { get; set; } + + public string GetAccessLevelName() + { + if (Name is { } name) + return Loc.GetString(name); + + return ID; + } } } diff --git a/Content.Shared/Access/Components/AccessComponent.cs b/Content.Shared/Access/Components/AccessComponent.cs index 2eacf2aa67..00ee87b3b6 100644 --- a/Content.Shared/Access/Components/AccessComponent.cs +++ b/Content.Shared/Access/Components/AccessComponent.cs @@ -20,17 +20,17 @@ public sealed partial class AccessComponent : Component [AutoNetworkedField] public bool Enabled = true; - [DataField(customTypeSerializer: typeof(PrototypeIdHashSetSerializer))] + [DataField] [Access(typeof(SharedAccessSystem), Other = AccessPermissions.ReadExecute)] // FIXME Friends [AutoNetworkedField] - public HashSet Tags = new(); + public HashSet> Tags = new(); /// /// Access Groups. These are added to the tags during map init. After map init this will have no effect. /// - [DataField(readOnly: true, customTypeSerializer: typeof(PrototypeIdHashSetSerializer))] + [DataField(readOnly: true)] [AutoNetworkedField] - public HashSet Groups = new(); + public HashSet> Groups = new(); } /// @@ -47,9 +47,9 @@ public struct GetAdditionalAccessEvent } [ByRefEvent] -public record struct GetAccessTagsEvent(HashSet Tags, IPrototypeManager PrototypeManager) +public record struct GetAccessTagsEvent(HashSet> Tags, IPrototypeManager PrototypeManager) { - public void AddGroup(string group) + public void AddGroup(ProtoId group) { if (!PrototypeManager.TryIndex(group, out var groupPrototype)) return; diff --git a/Content.Shared/Access/Components/AccessOverriderComponent.cs b/Content.Shared/Access/Components/AccessOverriderComponent.cs index 92c09f1ab7..6a1bf2c831 100644 --- a/Content.Shared/Access/Components/AccessOverriderComponent.cs +++ b/Content.Shared/Access/Components/AccessOverriderComponent.cs @@ -25,9 +25,9 @@ public sealed partial class AccessOverriderComponent : Component [Serializable, NetSerializable] public sealed class WriteToTargetAccessReaderIdMessage : BoundUserInterfaceMessage { - public readonly List AccessList; + public readonly List> AccessList; - public WriteToTargetAccessReaderIdMessage(List accessList) + public WriteToTargetAccessReaderIdMessage(List> accessList) { AccessList = accessList; } @@ -48,15 +48,15 @@ public sealed partial class AccessOverriderComponent : Component public readonly string PrivilegedIdName; public readonly bool IsPrivilegedIdPresent; public readonly bool IsPrivilegedIdAuthorized; - public readonly string[]? TargetAccessReaderIdAccessList; - public readonly string[]? AllowedModifyAccessList; - public readonly string[]? MissingPrivilegesList; + public readonly ProtoId[]? TargetAccessReaderIdAccessList; + public readonly ProtoId[]? AllowedModifyAccessList; + public readonly ProtoId[]? MissingPrivilegesList; public AccessOverriderBoundUserInterfaceState(bool isPrivilegedIdPresent, bool isPrivilegedIdAuthorized, - string[]? targetAccessReaderIdAccessList, - string[]? allowedModifyAccessList, - string[]? missingPrivilegesList, + ProtoId[]? targetAccessReaderIdAccessList, + ProtoId[]? allowedModifyAccessList, + ProtoId[]? missingPrivilegesList, string privilegedIdName, string targetLabel, Color targetLabelColor) diff --git a/Content.Shared/Access/Components/AccessReaderComponent.cs b/Content.Shared/Access/Components/AccessReaderComponent.cs index b157797922..cbd3f5acd6 100644 --- a/Content.Shared/Access/Components/AccessReaderComponent.cs +++ b/Content.Shared/Access/Components/AccessReaderComponent.cs @@ -1,5 +1,6 @@ using Content.Shared.StationRecords; using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; using Robust.Shared.Serialization; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Set; @@ -23,15 +24,15 @@ public sealed partial class AccessReaderComponent : Component /// The set of tags that will automatically deny an allowed check, if any of them are present. /// [ViewVariables(VVAccess.ReadWrite)] - [DataField(customTypeSerializer: typeof(PrototypeIdHashSetSerializer))] - public HashSet DenyTags = new(); + [DataField] + public HashSet> DenyTags = new(); /// /// 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. /// [DataField("access")] [ViewVariables(VVAccess.ReadWrite)] - public List> AccessLists = new(); + public List>> AccessLists = new(); /// /// A list of s that grant access. Only a single matching key is required to gain @@ -88,9 +89,9 @@ public sealed class AccessReaderComponentState : ComponentState { public bool Enabled; - public HashSet DenyTags; + public HashSet> DenyTags; - public List> AccessLists; + public List>> AccessLists; public List<(NetEntity, uint)> AccessKeys; @@ -98,7 +99,7 @@ public sealed class AccessReaderComponentState : ComponentState public int AccessLogLimit; - public AccessReaderComponentState(bool enabled, HashSet denyTags, List> accessLists, List<(NetEntity, uint)> accessKeys, Queue accessLog, int accessLogLimit) + public AccessReaderComponentState(bool enabled, HashSet> denyTags, List>> accessLists, List<(NetEntity, uint)> accessKeys, Queue accessLog, int accessLogLimit) { Enabled = enabled; DenyTags = denyTags; @@ -108,3 +109,10 @@ public sealed class AccessReaderComponentState : ComponentState AccessLogLimit = accessLogLimit; } } + +public sealed class AccessReaderConfigurationChangedEvent : EntityEventArgs +{ + public AccessReaderConfigurationChangedEvent() + { + } +} diff --git a/Content.Shared/Access/Components/IdCardConsoleComponent.cs b/Content.Shared/Access/Components/IdCardConsoleComponent.cs index 387ca8a013..deeafe2793 100644 --- a/Content.Shared/Access/Components/IdCardConsoleComponent.cs +++ b/Content.Shared/Access/Components/IdCardConsoleComponent.cs @@ -3,6 +3,8 @@ using Content.Shared.Containers.ItemSlots; using Robust.Shared.GameStates; using Robust.Shared.Prototypes; using Robust.Shared.Serialization; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; +using Robust.Shared.Prototypes; namespace Content.Shared.Access.Components; @@ -27,10 +29,10 @@ public sealed partial class IdCardConsoleComponent : Component { public readonly string FullName; public readonly string JobTitle; - public readonly List AccessList; - public readonly string JobPrototype; + public readonly List> AccessList; + public readonly ProtoId JobPrototype; - public WriteToTargetIdMessage(string fullName, string jobTitle, List accessList, string jobPrototype) + public WriteToTargetIdMessage(string fullName, string jobTitle, List> accessList, ProtoId jobPrototype) { FullName = fullName; JobTitle = jobTitle; @@ -86,18 +88,18 @@ public sealed partial class IdCardConsoleComponent : Component public readonly string TargetIdName; public readonly string? TargetIdFullName; public readonly string? TargetIdJobTitle; - public readonly string[]? TargetIdAccessList; - public readonly string[]? AllowedModifyAccessList; - public readonly string TargetIdJobPrototype; + public readonly List>? TargetIdAccessList; + public readonly List>? AllowedModifyAccessList; + public readonly ProtoId TargetIdJobPrototype; public IdCardConsoleBoundUserInterfaceState(bool isPrivilegedIdPresent, bool isPrivilegedIdAuthorized, bool isTargetIdPresent, string? targetIdFullName, string? targetIdJobTitle, - string[]? targetIdAccessList, - string[]? allowedModifyAccessList, - string targetIdJobPrototype, + List>? targetIdAccessList, + List>? allowedModifyAccessList, + ProtoId targetIdJobPrototype, string privilegedIdName, string targetIdName) { diff --git a/Content.Shared/Access/Systems/AccessReaderSystem.cs b/Content.Shared/Access/Systems/AccessReaderSystem.cs index 812a8e0487..4c12622ab5 100644 --- a/Content.Shared/Access/Systems/AccessReaderSystem.cs +++ b/Content.Shared/Access/Systems/AccessReaderSystem.cs @@ -112,11 +112,36 @@ public sealed class AccessReaderSystem : EntitySystem return false; } + public bool GetMainAccessReader(EntityUid uid, [NotNullWhen(true)] out AccessReaderComponent? component) + { + component = null; + if (!TryComp(uid, out AccessReaderComponent? accessReader)) + return false; + + component = accessReader; + + if (component.ContainerAccessProvider == null) + return true; + + if (!_containerSystem.TryGetContainer(uid, component.ContainerAccessProvider, out var container)) + return true; + + foreach (var entity in container.ContainedEntities) + { + if (TryComp(entity, out AccessReaderComponent? containedReader)) + { + component = containedReader; + return true; + } + } + return true; + } + /// /// Check whether the given access permissions satisfy an access reader's requirements. /// public bool IsAllowed( - ICollection access, + ICollection> access, ICollection stationKeys, EntityUid target, AccessReaderComponent reader) @@ -142,7 +167,7 @@ public sealed class AccessReaderSystem : EntitySystem return false; } - private bool IsAllowedInternal(ICollection access, ICollection stationKeys, AccessReaderComponent reader) + private bool IsAllowedInternal(ICollection> access, ICollection stationKeys, AccessReaderComponent reader) { return !reader.Enabled || AreAccessTagsAllowed(access, reader) @@ -154,7 +179,7 @@ public sealed class AccessReaderSystem : EntitySystem /// /// A list of access tags /// An access reader to check against - public bool AreAccessTagsAllowed(ICollection accessTags, AccessReaderComponent reader) + public bool AreAccessTagsAllowed(ICollection> accessTags, AccessReaderComponent reader) { if (reader.DenyTags.Overlaps(accessTags)) { @@ -218,9 +243,9 @@ public sealed class AccessReaderSystem : EntitySystem /// /// The entity that is being searched. /// All of the items to search for access. If none are passed in, will be used. - public ICollection FindAccessTags(EntityUid uid, HashSet? items = null) + public ICollection> FindAccessTags(EntityUid uid, HashSet? items = null) { - HashSet? tags = null; + HashSet>? tags = null; var owned = false; items ??= FindPotentialAccessItems(uid); @@ -230,7 +255,7 @@ public sealed class AccessReaderSystem : EntitySystem FindAccessTagsItem(ent, ref tags, ref owned); } - return (ICollection?) tags ?? Array.Empty(); + return (ICollection>?) tags ?? Array.Empty>(); } /// @@ -260,7 +285,7 @@ public sealed class AccessReaderSystem : EntitySystem /// 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). /// - private void FindAccessTagsItem(EntityUid uid, ref HashSet? tags, ref bool owned) + private void FindAccessTagsItem(EntityUid uid, ref HashSet>? tags, ref bool owned) { if (!FindAccessTagsItem(uid, out var targetTags)) { @@ -286,6 +311,16 @@ public sealed class AccessReaderSystem : EntitySystem } } + public void SetAccesses(EntityUid uid, AccessReaderComponent component, List> accesses) + { + component.AccessLists.Clear(); + foreach (var access in accesses) + { + component.AccessLists.Add(new HashSet>(){access}); + } + RaiseLocalEvent(uid, new AccessReaderConfigurationChangedEvent()); + } + public bool FindAccessItemsInventory(EntityUid uid, out HashSet items) { items = new(); @@ -308,7 +343,7 @@ public sealed class AccessReaderSystem : EntitySystem /// Try to find on this item /// or inside this item (if it's pda) /// - private bool FindAccessTagsItem(EntityUid uid, out HashSet tags) + private bool FindAccessTagsItem(EntityUid uid, out HashSet> tags) { tags = new(); var ev = new GetAccessTagsEvent(tags, _prototype); diff --git a/Content.Shared/Access/Systems/SharedAccessSystem.cs b/Content.Shared/Access/Systems/SharedAccessSystem.cs index 965ccb2412..a4b04c3559 100644 --- a/Content.Shared/Access/Systems/SharedAccessSystem.cs +++ b/Content.Shared/Access/Systems/SharedAccessSystem.cs @@ -51,7 +51,7 @@ namespace Content.Shared.Access.Systems /// Replaces the set of access tags we have with the provided set. /// /// The new access tags - public bool TrySetTags(EntityUid uid, IEnumerable newTags, AccessComponent? access = null) + public bool TrySetTags(EntityUid uid, IEnumerable> newTags, AccessComponent? access = null) { if (!Resolve(uid, ref access)) return false; @@ -67,12 +67,12 @@ namespace Content.Shared.Access.Systems /// Gets the set of access tags. /// /// The new access tags - public IEnumerable? TryGetTags(EntityUid uid, AccessComponent? access = null) + public IEnumerable>? TryGetTags(EntityUid uid, AccessComponent? access = null) { return !Resolve(uid, ref access) ? null : access.Tags; } - public bool TryAddGroups(EntityUid uid, IEnumerable newGroups, AccessComponent? access = null) + public bool TryAddGroups(EntityUid uid, IEnumerable> newGroups, AccessComponent? access = null) { if (!Resolve(uid, ref access)) return false; diff --git a/Content.Shared/Access/Systems/SharedIdCardConsoleSystem.cs b/Content.Shared/Access/Systems/SharedIdCardConsoleSystem.cs index 12e25e1e22..81843b5e2d 100644 --- a/Content.Shared/Access/Systems/SharedIdCardConsoleSystem.cs +++ b/Content.Shared/Access/Systems/SharedIdCardConsoleSystem.cs @@ -1,6 +1,9 @@ using Content.Shared.Access.Components; using Content.Shared.Containers.ItemSlots; using JetBrains.Annotations; +using Robust.Shared.GameStates; +using Robust.Shared.Serialization; +using Robust.Shared.Prototypes; namespace Content.Shared.Access.Systems { @@ -33,5 +36,16 @@ namespace Content.Shared.Access.Systems _itemSlotsSystem.RemoveItemSlot(uid, component.PrivilegedIdSlot); _itemSlotsSystem.RemoveItemSlot(uid, component.TargetIdSlot); } + + [Serializable, NetSerializable] + private sealed class IdCardConsoleComponentState : ComponentState + { + public List AccessLevels; + + public IdCardConsoleComponentState(List accessLevels) + { + AccessLevels = accessLevels; + } + } } } diff --git a/Content.Shared/Anomaly/Components/AnomalyComponent.cs b/Content.Shared/Anomaly/Components/AnomalyComponent.cs index bafdf12360..3878aeb81c 100644 --- a/Content.Shared/Anomaly/Components/AnomalyComponent.cs +++ b/Content.Shared/Anomaly/Components/AnomalyComponent.cs @@ -1,4 +1,5 @@ using System.Numerics; +using Content.Shared.Anomaly.Prototypes; using Content.Shared.Damage; using Robust.Shared.Audio; using Robust.Shared.GameStates; @@ -94,13 +95,13 @@ public sealed partial class AnomalyComponent : Component /// The minimum interval between pulses. /// [DataField] - public TimeSpan MinPulseLength = TimeSpan.FromMinutes(1); + public TimeSpan MinPulseLength = TimeSpan.FromMinutes(2); /// /// The maximum interval between pulses. /// [DataField] - public TimeSpan MaxPulseLength = TimeSpan.FromMinutes(2); + public TimeSpan MaxPulseLength = TimeSpan.FromMinutes(4); /// /// A percentage by which the length of a pulse might vary. @@ -166,6 +167,12 @@ public sealed partial class AnomalyComponent : Component [DataField] public AnomalousParticleType WeakeningParticleType; + /// + /// The particle type that change anomaly behaviour. + /// + [DataField] + public AnomalousParticleType TransformationParticleType; + #region Points and Vessels /// /// The vessel that the anomaly is connceted to. Stored so that multiple @@ -185,7 +192,7 @@ public sealed partial class AnomalyComponent : Component /// This doesn't include the point bonus for being unstable. /// [DataField("maxPointsPerSecond")] - public int MaxPointsPerSecond = 80; + public int MaxPointsPerSecond = 70; /// /// The multiplier applied to the point value for the @@ -221,6 +228,31 @@ public sealed partial class AnomalyComponent : Component [DataField, ViewVariables(VVAccess.ReadWrite)] public EntProtoId? CoreInertPrototype; + #region Behavior Deviations + + [DataField] + public ProtoId? CurrentBehavior; + + /// + /// Presumption of anomaly to change behavior. The higher the number, the higher the chance that the anomaly will change its behavior. + /// + [DataField] + public float Continuity = 0f; + + /// + /// Minimum contituty probability chance, that can be selected by anomaly on MapInit + /// + [DataField] + public float MinContituty = 0.1f; + + /// + /// Maximum contituty probability chance, that can be selected by anomaly on MapInit + /// + [DataField] + public float MaxContituty = 1.0f; + + #endregion + #region Floating Animation /// /// How long it takes to go from the bottom of the animation to the top. @@ -247,13 +279,13 @@ public sealed partial class AnomalyComponent : Component /// /// [ByRefEvent] -public readonly record struct AnomalyPulseEvent(EntityUid Anomaly, float Stability, float Severity); +public readonly record struct AnomalyPulseEvent(EntityUid Anomaly, float Stability, float Severity, float PowerModifier); /// /// Event raised on an anomaly when it reaches a supercritical point. /// [ByRefEvent] -public readonly record struct AnomalySupercriticalEvent(EntityUid Anomaly); +public readonly record struct AnomalySupercriticalEvent(EntityUid Anomaly, float PowerModifier); /// /// Event broadcast after an anomaly goes supercritical @@ -282,3 +314,9 @@ public readonly record struct AnomalyStabilityChangedEvent(EntityUid Anomaly, fl /// The anomaly being changed [ByRefEvent] public readonly record struct AnomalyHealthChangedEvent(EntityUid Anomaly, float Health); + +/// +/// Event broadcast when an anomaly's behavior is changed. +/// +[ByRefEvent] +public readonly record struct AnomalyBehaviorChangedEvent(EntityUid Anomaly, ProtoId? Old, ProtoId? New); diff --git a/Content.Shared/Anomaly/Effects/SharedGravityAnomalySystem.cs b/Content.Shared/Anomaly/Effects/SharedGravityAnomalySystem.cs index f4b7cc8bf4..4c3cdb0146 100644 --- a/Content.Shared/Anomaly/Effects/SharedGravityAnomalySystem.cs +++ b/Content.Shared/Anomaly/Effects/SharedGravityAnomalySystem.cs @@ -1,4 +1,4 @@ -using System.Linq; +using System.Linq; using Content.Shared.Anomaly.Components; using Content.Shared.Anomaly.Effects.Components; using Content.Shared.Ghost; @@ -27,8 +27,8 @@ public abstract class SharedGravityAnomalySystem : EntitySystem private void OnAnomalyPulse(EntityUid uid, GravityAnomalyComponent component, ref AnomalyPulseEvent args) { var xform = Transform(uid); - var range = component.MaxThrowRange * args.Severity; - var strength = component.MaxThrowStrength * args.Severity; + var range = component.MaxThrowRange * args.Severity * args.PowerModifier; + var strength = component.MaxThrowStrength * args.Severity * args.PowerModifier; var lookup = _lookup.GetEntitiesInRange(uid, range, LookupFlags.Dynamic | LookupFlags.Sundries); var xformQuery = GetEntityQuery(); var worldPos = _xform.GetWorldPosition(xform, xformQuery); @@ -61,8 +61,8 @@ public abstract class SharedGravityAnomalySystem : EntitySystem var tiles = tileref.Select(t => (t.GridIndices, Tile.Empty)).ToList(); _mapSystem.SetTiles(xform.GridUid.Value, grid, tiles); - var range = component.MaxThrowRange * 2; - var strength = component.MaxThrowStrength * 2; + var range = component.MaxThrowRange * 2 * args.PowerModifier; + var strength = component.MaxThrowStrength * 2 * args.PowerModifier; var lookup = _lookup.GetEntitiesInRange(uid, range, LookupFlags.Dynamic | LookupFlags.Sundries); var xformQuery = GetEntityQuery(); var physQuery = GetEntityQuery(); diff --git a/Content.Shared/Anomaly/Prototypes/AnomalyBehaviorPrototype.cs b/Content.Shared/Anomaly/Prototypes/AnomalyBehaviorPrototype.cs new file mode 100644 index 0000000000..c498f5c595 --- /dev/null +++ b/Content.Shared/Anomaly/Prototypes/AnomalyBehaviorPrototype.cs @@ -0,0 +1,45 @@ +using Robust.Shared.Prototypes; + +namespace Content.Shared.Anomaly.Prototypes; + +[Prototype] +public sealed partial class AnomalyBehaviorPrototype : IPrototype +{ + [IdDataField] public string ID { get; private set; } = default!; + + /// + /// Description for anomaly scanner + /// + [DataField] + public string Description = string.Empty; + + /// + /// modification of the number of points earned from an anomaly + /// + [DataField] + public float EarnPointModifier = 1f; + + /// + /// deceleration or acceleration of the pulsation frequency of the anomaly + /// + [DataField] + public float PulseFrequencyModifier = 1f; + + /// + /// pulse and supercrit power modifier + /// + [DataField] + public float PulsePowerModifier = 1f; + + /// + /// how much the particles will affect the anomaly + /// + [DataField] + public float ParticleSensivity = 1f; + + /// + /// Components that are added to the anomaly when this behavior is selected, and removed when another behavior is selected. + /// + [DataField(serverOnly: true)] + public ComponentRegistry Components = new(); +} diff --git a/Content.Shared/Anomaly/SharedAnomaly.cs b/Content.Shared/Anomaly/SharedAnomaly.cs index b7585cb5f1..cde61ca336 100644 --- a/Content.Shared/Anomaly/SharedAnomaly.cs +++ b/Content.Shared/Anomaly/SharedAnomaly.cs @@ -33,6 +33,7 @@ public enum AnomalousParticleType : byte Delta, Epsilon, Zeta, + Sigma, Default } diff --git a/Content.Shared/Anomaly/SharedAnomalySystem.cs b/Content.Shared/Anomaly/SharedAnomalySystem.cs index c335cd7b85..da1d31c6ff 100644 --- a/Content.Shared/Anomaly/SharedAnomalySystem.cs +++ b/Content.Shared/Anomaly/SharedAnomalySystem.cs @@ -1,5 +1,6 @@ using Content.Shared.Administration.Logs; using Content.Shared.Anomaly.Components; +using Content.Shared.Anomaly.Prototypes; using Content.Shared.Damage; using Content.Shared.Database; using Content.Shared.Interaction; @@ -14,6 +15,7 @@ using Robust.Shared.Network; using Robust.Shared.Physics; using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Systems; +using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Timing; using Robust.Shared.Utility; @@ -33,6 +35,7 @@ public abstract class SharedAnomalySystem : EntitySystem [Dependency] protected readonly SharedAppearanceSystem Appearance = default!; [Dependency] private readonly SharedPhysicsSystem _physics = default!; [Dependency] protected readonly SharedPopupSystem Popup = default!; + [Dependency] private readonly IPrototypeManager _prototype = default!; [Dependency] private readonly IRobustRandom _random = default!; public override void Initialize() @@ -90,8 +93,7 @@ public abstract class SharedAnomalySystem : EntitySystem return; DebugTools.Assert(component.MinPulseLength > TimeSpan.FromSeconds(3)); // this is just to prevent lagspikes mispredicting pulses - var variation = Random.NextFloat(-component.PulseVariation, component.PulseVariation) + 1; - component.NextPulseTime = Timing.CurTime + GetPulseLength(component) * variation; + RefreshPulseTimer(uid, component); if (_net.IsServer) Log.Info($"Performing anomaly pulse. Entity: {ToPrettyString(uid)}"); @@ -115,10 +117,25 @@ public abstract class SharedAnomalySystem : EntitySystem pulse.EndTime = Timing.CurTime + pulse.PulseDuration; Appearance.SetData(uid, AnomalyVisuals.IsPulsing, true); - var ev = new AnomalyPulseEvent(uid, component.Stability, component.Severity); + var powerMod = 1f; + if (component.CurrentBehavior != null) + { + var beh = _prototype.Index(component.CurrentBehavior); + powerMod = beh.PulsePowerModifier; + } + var ev = new AnomalyPulseEvent(uid, component.Stability, component.Severity, powerMod); RaiseLocalEvent(uid, ref ev, true); } + public void RefreshPulseTimer(EntityUid uid, AnomalyComponent? component = null) + { + if (!Resolve(uid, ref component)) + return; + + var variation = Random.NextFloat(-component.PulseVariation, component.PulseVariation) + 1; + component.NextPulseTime = Timing.CurTime + GetPulseLength(component) * variation; + } + /// /// Begins the animation for going supercritical /// @@ -159,7 +176,14 @@ public abstract class SharedAnomalySystem : EntitySystem if (_net.IsServer) Log.Info($"Raising supercritical event. Entity: {ToPrettyString(uid)}"); - var ev = new AnomalySupercriticalEvent(uid); + var powerMod = 1f; + if (component.CurrentBehavior != null) + { + var beh = _prototype.Index(component.CurrentBehavior); + powerMod = beh.PulsePowerModifier; + } + + var ev = new AnomalySupercriticalEvent(uid, powerMod); RaiseLocalEvent(uid, ref ev, true); EndAnomaly(uid, component, true); @@ -276,8 +300,17 @@ public abstract class SharedAnomalySystem : EntitySystem public TimeSpan GetPulseLength(AnomalyComponent component) { DebugTools.Assert(component.MaxPulseLength > component.MinPulseLength); - var modifier = Math.Clamp((component.Stability - component.GrowthThreshold) / component.GrowthThreshold, 0, 1); - return (component.MaxPulseLength - component.MinPulseLength) * modifier + component.MinPulseLength; + var modifier = Math.Clamp((component.Stability - component.GrowthThreshold) / component.GrowthThreshold, 0, 1); + + var lenght = (component.MaxPulseLength - component.MinPulseLength) * modifier + component.MinPulseLength; + + //Apply behavior modifier + if (component.CurrentBehavior != null) + { + var behavior = _prototype.Index(component.CurrentBehavior.Value); + lenght *= behavior.PulseFrequencyModifier; + } + return lenght; } /// @@ -335,14 +368,14 @@ public abstract class SharedAnomalySystem : EntitySystem /// /// Gets random points around the anomaly based on the given parameters. /// - public List? GetSpawningPoints(EntityUid uid, float stability, float severity, AnomalySpawnSettings settings) + public List? GetSpawningPoints(EntityUid uid, float stability, float severity, AnomalySpawnSettings settings, float powerModifier = 1f) { var xform = Transform(uid); if (!TryComp(xform.GridUid, out var grid)) return null; - var amount = (int) (MathHelper.Lerp(settings.MinAmount, settings.MaxAmount, severity * stability) + 0.5f); + var amount = (int) (MathHelper.Lerp(settings.MinAmount, settings.MaxAmount, severity * stability * powerModifier) + 0.5f); var localpos = xform.Coordinates.Position; var tilerefs = grid.GetLocalTilesIntersecting( diff --git a/Content.Shared/Buckle/Components/StrapComponent.cs b/Content.Shared/Buckle/Components/StrapComponent.cs index f25e1b0374..72c92ebf84 100644 --- a/Content.Shared/Buckle/Components/StrapComponent.cs +++ b/Content.Shared/Buckle/Components/StrapComponent.cs @@ -22,9 +22,14 @@ public sealed partial class StrapComponent : Component /// Entities that this strap accepts and can buckle /// If null it accepts any entity /// - [DataField] - [ViewVariables] - public EntityWhitelist? AllowedEntities; + [DataField, ViewVariables(VVAccess.ReadWrite)] + public EntityWhitelist? Whitelist; + + /// + /// Entities that this strap does not accept and cannot buckle. + /// + [DataField, ViewVariables(VVAccess.ReadWrite)] + public EntityWhitelist? Blacklist; /// /// The change in position to the strapped mob diff --git a/Content.Shared/Buckle/SharedBuckleSystem.Buckle.cs b/Content.Shared/Buckle/SharedBuckleSystem.Buckle.cs index 3d1fbf2b69..0d67473ffe 100644 --- a/Content.Shared/Buckle/SharedBuckleSystem.Buckle.cs +++ b/Content.Shared/Buckle/SharedBuckleSystem.Buckle.cs @@ -221,8 +221,8 @@ public abstract partial class SharedBuckleSystem } // Does it pass the Whitelist - if (strapComp.AllowedEntities != null && - !strapComp.AllowedEntities.IsValid(userUid, EntityManager)) + if (strapComp.Whitelist != null && + !strapComp.Whitelist.IsValid(buckleUid, EntityManager) || strapComp.Blacklist?.IsValid(buckleUid, EntityManager) == true) { if (_netManager.IsServer) _popup.PopupEntity(Loc.GetString("buckle-component-cannot-fit-message"), userUid, buckleUid, PopupType.Medium); diff --git a/Content.Shared/Burial/BurialSystem.cs b/Content.Shared/Burial/BurialSystem.cs index e19ac2e9c6..ccf5f1a298 100644 --- a/Content.Shared/Burial/BurialSystem.cs +++ b/Content.Shared/Burial/BurialSystem.cs @@ -51,8 +51,15 @@ public sealed class BurialSystem : EntitySystem BreakOnHandChange = true }; + if (component.Stream == null) + component.Stream = _audioSystem.PlayPredicted(component.DigSound, uid, args.User)?.Entity; + if (!_doAfterSystem.TryStartDoAfter(doAfterEventArgs)) + { + _audioSystem.Stop(component.Stream); return; + } + StartDigging(uid, args.User, args.Used, component); } @@ -111,8 +118,6 @@ public sealed class BurialSystem : EntitySystem { _popupSystem.PopupClient(Loc.GetString("grave-start-digging-user", ("grave", uid), ("tool", used)), user, user); _popupSystem.PopupEntity(Loc.GetString("grave-start-digging-others", ("user", user), ("grave", uid), ("tool", used)), user, Filter.PvsExcept(user), true); - if (component.Stream == null) - component.Stream = _audioSystem.PlayPredicted(component.DigSound, uid, user)?.Entity; component.ActiveShovelDigging = true; Dirty(uid, component); } @@ -163,8 +168,15 @@ public sealed class BurialSystem : EntitySystem BreakOnDamage = false }; - if (!_doAfterSystem.TryStartDoAfter(doAfterEventArgs, out component.HandDiggingDoAfter)) + + if (component.Stream == null) + component.Stream = _audioSystem.PlayPredicted(component.DigSound, uid, args.Entity)?.Entity; + + if (!_doAfterSystem.TryStartDoAfter(doAfterEventArgs)) + { + _audioSystem.Stop(component.Stream); return; + } StartDigging(uid, args.Entity, null, component); } diff --git a/Content.Shared/CCVar/CCVars.cs b/Content.Shared/CCVar/CCVars.cs index 51f782991e..82d1fdd14a 100644 --- a/Content.Shared/CCVar/CCVars.cs +++ b/Content.Shared/CCVar/CCVars.cs @@ -1580,6 +1580,13 @@ namespace Content.Shared.CCVar * Accessibility */ + /// + /// Chat window opacity slider, controlling the alpha of the chat window background. + /// Goes from to 0 (completely transparent) to 1 (completely opaque) + /// + public static readonly CVarDef ChatWindowOpacity = + CVarDef.Create("accessibility.chat_window_transparency", 0.85f, CVar.CLIENTONLY | CVar.ARCHIVE); + /// /// Toggle for visual effects that may potentially cause motion sickness. /// Where reasonable, effects affected by this CVar should use an alternate effect. diff --git a/Content.Shared/Charges/Systems/SharedChargesSystem.cs b/Content.Shared/Charges/Systems/SharedChargesSystem.cs index 021191ac26..5de1383cde 100644 --- a/Content.Shared/Charges/Systems/SharedChargesSystem.cs +++ b/Content.Shared/Charges/Systems/SharedChargesSystem.cs @@ -61,4 +61,26 @@ public abstract class SharedChargesSystem : EntitySystem if (Resolve(uid, ref comp, false)) AddCharges(uid, -1, comp); } + + /// + /// Gets the limited charges component and returns true if the number of charges remaining is less than the specified value. + /// Will return false if there is no limited charges component. + /// + public bool HasInsufficientCharges(EntityUid uid, int requiredCharges, LimitedChargesComponent? comp = null) + { + // can't be empty if there are no limited charges + if (!Resolve(uid, ref comp, false)) + return false; + + return comp.Charges < requiredCharges; + } + + /// + /// Uses up a specified number of charges. Must check HasInsufficentCharges beforehand to prevent using with insufficient remaining charges. + /// + public virtual void UseCharges(EntityUid uid, int chargesUsed, LimitedChargesComponent? comp = null) + { + if (Resolve(uid, ref comp, false)) + AddCharges(uid, -chargesUsed, comp); + } } diff --git a/Content.Shared/Chat/TypingIndicator/TypingIndicatorPrototype.cs b/Content.Shared/Chat/TypingIndicator/TypingIndicatorPrototype.cs index 8cbfe7bb2e..63008c6e08 100644 --- a/Content.Shared/Chat/TypingIndicator/TypingIndicatorPrototype.cs +++ b/Content.Shared/Chat/TypingIndicator/TypingIndicatorPrototype.cs @@ -23,6 +23,6 @@ public sealed partial class TypingIndicatorPrototype : IPrototype public Vector2 Offset = new(0, 0); [DataField("shader")] - public string Shader = "unshaded"; + public string Shader = "shaded"; } diff --git a/Content.Shared/Chemistry/Components/BlockSolutionAccessComponent.cs b/Content.Shared/Chemistry/Components/BlockSolutionAccessComponent.cs new file mode 100644 index 0000000000..182f92d7d3 --- /dev/null +++ b/Content.Shared/Chemistry/Components/BlockSolutionAccessComponent.cs @@ -0,0 +1,11 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Chemistry.Components; + +/// +/// Blocks all attempts to access solutions contained by this entity. +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class BlockSolutionAccessComponent : Component +{ +} diff --git a/Content.Shared/Chemistry/Components/HyposprayComponent.cs b/Content.Shared/Chemistry/Components/HyposprayComponent.cs index 05d202aaaa..05ef84bbaf 100644 --- a/Content.Shared/Chemistry/Components/HyposprayComponent.cs +++ b/Content.Shared/Chemistry/Components/HyposprayComponent.cs @@ -30,4 +30,11 @@ public sealed partial class HyposprayComponent : Component [AutoNetworkedField] [DataField(required: true)] public bool OnlyAffectsMobs = false; + + /// + /// Whether or not the hypospray is able to draw from containers or if it's a single use + /// device that can only inject. + /// + [DataField] + public bool InjectOnly = false; } diff --git a/Content.Shared/Chemistry/Components/ScoopableSolutionComponent.cs b/Content.Shared/Chemistry/Components/ScoopableSolutionComponent.cs new file mode 100644 index 0000000000..6c3f934b7a --- /dev/null +++ b/Content.Shared/Chemistry/Components/ScoopableSolutionComponent.cs @@ -0,0 +1,31 @@ +using Content.Shared.Chemistry.EntitySystems; +using Robust.Shared.GameStates; + +namespace Content.Shared.Chemistry.Components; + +/// +/// Basically reverse spiking, instead of using the solution-entity on a beaker, you use the beaker on the solution-entity. +/// If there is not enough volume it will stay in the solution-entity rather than spill onto the floor. +/// +[RegisterComponent, NetworkedComponent, Access(typeof(ScoopableSolutionSystem))] +public sealed partial class ScoopableSolutionComponent : Component +{ + /// + /// Solution name that can be scooped from. + /// + [DataField] + public string Solution = "default"; + + /// + /// If true, when the whole solution is scooped up the entity will be deleted. + /// + [DataField] + public bool Delete = true; + + /// + /// Popup to show the user when scooping. + /// Passed entities "scooped" and "beaker". + /// + [DataField] + public LocId Popup = "scoopable-component-popup"; +} diff --git a/Content.Shared/Chemistry/Components/SolutionManager/ExaminableSolutionComponent.cs b/Content.Shared/Chemistry/Components/SolutionManager/ExaminableSolutionComponent.cs index 76e7967db2..1abe81180c 100644 --- a/Content.Shared/Chemistry/Components/SolutionManager/ExaminableSolutionComponent.cs +++ b/Content.Shared/Chemistry/Components/SolutionManager/ExaminableSolutionComponent.cs @@ -5,4 +5,10 @@ public sealed partial class ExaminableSolutionComponent : Component { [DataField, ViewVariables(VVAccess.ReadWrite)] public string Solution = "default"; + + /// + /// If false then the hidden solution is always visible. + /// + [DataField] + public bool HeldOnly; } diff --git a/Content.Shared/Chemistry/EntitySystems/ScoopableSolutionSystem.cs b/Content.Shared/Chemistry/EntitySystems/ScoopableSolutionSystem.cs new file mode 100644 index 0000000000..84f1e45616 --- /dev/null +++ b/Content.Shared/Chemistry/EntitySystems/ScoopableSolutionSystem.cs @@ -0,0 +1,53 @@ +using Content.Shared.Chemistry.Components; +using Content.Shared.Interaction; +using Content.Shared.Popups; +using Robust.Shared.Network; + +namespace Content.Shared.Chemistry.EntitySystems; + +/// +/// Handles solution transfer when a beaker is used on a scoopable entity. +/// +public sealed class ScoopableSolutionSystem : EntitySystem +{ + [Dependency] private readonly INetManager _netManager = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; + [Dependency] private readonly SharedSolutionContainerSystem _solution = default!; + [Dependency] private readonly SolutionTransferSystem _solutionTransfer = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnInteractUsing); + } + + private void OnInteractUsing(Entity ent, ref InteractUsingEvent args) + { + TryScoop(ent, args.Used, args.User); + } + + public bool TryScoop(Entity ent, EntityUid beaker, EntityUid user) + { + if (!_solution.TryGetSolution(ent.Owner, ent.Comp.Solution, out var src, out var srcSolution) || + !_solution.TryGetRefillableSolution(beaker, out var target, out _)) + return false; + + var scooped = _solutionTransfer.Transfer(user, ent, src.Value, beaker, target.Value, srcSolution.Volume); + if (scooped == 0) + return false; + + _popup.PopupClient(Loc.GetString(ent.Comp.Popup, ("scooped", ent.Owner), ("beaker", beaker)), user, user); + + if (srcSolution.Volume == 0 && ent.Comp.Delete) + { + // deletion isnt predicted so do this to prevent spam clicking to see "the ash is empty!" + RemCompDeferred(ent); + + if (!_netManager.IsClient) + QueueDel(ent); + } + + return true; + } +} diff --git a/Content.Shared/Chemistry/EntitySystems/SharedHypospraySystem.cs b/Content.Shared/Chemistry/EntitySystems/SharedHypospraySystem.cs index f91e5621f0..b647d33c98 100644 --- a/Content.Shared/Chemistry/EntitySystems/SharedHypospraySystem.cs +++ b/Content.Shared/Chemistry/EntitySystems/SharedHypospraySystem.cs @@ -27,7 +27,7 @@ public abstract class SharedHypospraySystem : EntitySystem // private void AddToggleModeVerb(Entity entity, ref GetVerbsEvent args) { - if (!args.CanAccess || !args.CanInteract || args.Hands == null) + if (!args.CanAccess || !args.CanInteract || args.Hands == null || entity.Comp.InjectOnly) return; var (_, component) = entity; diff --git a/Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.cs b/Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.cs index 6e762aa598..5bb97e83eb 100644 --- a/Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.cs +++ b/Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.cs @@ -13,6 +13,8 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Runtime.CompilerServices; using System.Text; +using Content.Shared.Hands.Components; +using Content.Shared.Hands.EntitySystems; using Dependency = Robust.Shared.IoC.DependencyAttribute; namespace Content.Shared.Chemistry.EntitySystems; @@ -53,6 +55,7 @@ public abstract partial class SharedSolutionContainerSystem : EntitySystem [Dependency] protected readonly ChemicalReactionSystem ChemicalReactionSystem = default!; [Dependency] protected readonly ExamineSystemShared ExamineSystem = default!; [Dependency] protected readonly SharedAppearanceSystem AppearanceSystem = default!; + [Dependency] protected readonly SharedHandsSystem Hands = default!; [Dependency] protected readonly SharedContainerSystem ContainerSystem = default!; public override void Initialize() @@ -133,6 +136,12 @@ public abstract partial class SharedSolutionContainerSystem : EntitySystem /// public bool TryGetSolution(Entity container, string? name, [NotNullWhen(true)] out Entity? entity) { + if (TryComp(container, out BlockSolutionAccessComponent? blocker)) + { + entity = null; + return false; + } + EntityUid uid; if (name is null) uid = container; @@ -178,6 +187,9 @@ public abstract partial class SharedSolutionContainerSystem : EntitySystem if (!Resolve(container, ref container.Comp, logMissing: false)) yield break; + if (HasComp(container)) + yield break; + foreach (var name in container.Comp.Containers) { if (ContainerSystem.GetContainer(container, $"solution@{name}") is ContainerSlot slot && slot.ContainedEntity is { } solutionId) @@ -720,6 +732,9 @@ public abstract partial class SharedSolutionContainerSystem : EntitySystem return; } + if (!CanSeeHiddenSolution(entity,args.Examiner)) + return; + var primaryReagent = solution.GetPrimaryReagentId(); if (string.IsNullOrEmpty(primaryReagent?.Prototype)) @@ -816,6 +831,9 @@ public abstract partial class SharedSolutionContainerSystem : EntitySystem return; } + if (!CanSeeHiddenSolution(entity,args.User)) + return; + var target = args.Target; var user = args.User; var verb = new ExamineVerb() @@ -865,5 +883,22 @@ public abstract partial class SharedSolutionContainerSystem : EntitySystem return msg; } + /// + /// Check if examinable solution requires you to hold the item in hand. + /// + private bool CanSeeHiddenSolution(Entity entity, EntityUid examiner) + { + // If not held-only then it's always visible. + if (!entity.Comp.HeldOnly) + return true; + + if (TryComp(examiner, out HandsComponent? handsComp)) + { + return Hands.IsHolding(examiner, entity, out _, handsComp); + } + + return true; + } + #endregion Event Handlers } diff --git a/Content.Shared/Chemistry/EntitySystems/SolutionTransferSystem.cs b/Content.Shared/Chemistry/EntitySystems/SolutionTransferSystem.cs new file mode 100644 index 0000000000..34a64d0edb --- /dev/null +++ b/Content.Shared/Chemistry/EntitySystems/SolutionTransferSystem.cs @@ -0,0 +1,223 @@ +using Content.Shared.Administration.Logs; +using Content.Shared.Chemistry; +using Content.Shared.Chemistry.Components; +using Content.Shared.Database; +using Content.Shared.FixedPoint; +using Content.Shared.Interaction; +using Content.Shared.Popups; +using Content.Shared.Verbs; +using Robust.Shared.Network; +using Robust.Shared.Player; + +namespace Content.Shared.Chemistry.EntitySystems; + +/// +/// Allows an entity to transfer solutions with a customizable amount per click. +/// Also provides API for other systems. +/// +public sealed class SolutionTransferSystem : EntitySystem +{ + [Dependency] private readonly INetManager _net = default!; + [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; + [Dependency] private readonly SharedSolutionContainerSystem _solution = default!; + [Dependency] private readonly SharedUserInterfaceSystem _ui = default!; + + /// + /// Default transfer amounts for the set-transfer verb. + /// + public static readonly FixedPoint2[] DefaultTransferAmounts = new FixedPoint2[] { 1, 5, 10, 25, 50, 100, 250, 500, 1000 }; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent>(AddSetTransferVerbs); + SubscribeLocalEvent(OnAfterInteract); + SubscribeLocalEvent(OnTransferAmountSetValueMessage); + } + + private void OnTransferAmountSetValueMessage(Entity ent, ref TransferAmountSetValueMessage message) + { + var newTransferAmount = FixedPoint2.Clamp(message.Value, ent.Comp.MinimumTransferAmount, ent.Comp.MaximumTransferAmount); + ent.Comp.TransferAmount = newTransferAmount; + + if (message.Session.AttachedEntity is { Valid: true } user) + _popup.PopupClient(Loc.GetString("comp-solution-transfer-set-amount", ("amount", newTransferAmount)), ent, user); + } + + private void AddSetTransferVerbs(Entity ent, ref GetVerbsEvent args) + { + var (uid, comp) = ent; + + if (!args.CanAccess || !args.CanInteract || !comp.CanChangeTransferAmount || args.Hands == null) + return; + + if (!TryComp(args.User, out var actor)) + return; + + // Custom transfer verb + args.Verbs.Add(new AlternativeVerb() + { + Text = Loc.GetString("comp-solution-transfer-verb-custom-amount"), + Category = VerbCategory.SetTransferAmount, + // TODO: remove server check when bui prediction is a thing + Act = () => + { + if (_net.IsServer) + _ui.TryOpen(uid, TransferAmountUiKey.Key, actor.PlayerSession); + }, + Priority = 1 + }); + + // Add specific transfer verbs according to the container's size + var priority = 0; + var user = args.User; + foreach (var amount in DefaultTransferAmounts) + { + AlternativeVerb verb = new(); + verb.Text = Loc.GetString("comp-solution-transfer-verb-amount", ("amount", amount)); + verb.Category = VerbCategory.SetTransferAmount; + verb.Act = () => + { + comp.TransferAmount = amount; + _popup.PopupClient(Loc.GetString("comp-solution-transfer-set-amount", ("amount", amount)), uid, user); + }; + + // we want to sort by size, not alphabetically by the verb text. + verb.Priority = priority; + priority--; + + args.Verbs.Add(verb); + } + } + + private void OnAfterInteract(Entity ent, ref AfterInteractEvent args) + { + if (!args.CanReach || args.Target is not {} target) + return; + + var (uid, comp) = ent; + + //Special case for reagent tanks, because normally clicking another container will give solution, not take it. + if (comp.CanReceive + && !HasComp(target) // target must not be refillable (e.g. Reagent Tanks) + && _solution.TryGetDrainableSolution(target, out var targetSoln, out _) // target must be drainable + && TryComp(uid, out var refill) + && _solution.TryGetRefillableSolution((uid, refill, null), out var ownerSoln, out var ownerRefill)) + { + var transferAmount = comp.TransferAmount; // This is the player-configurable transfer amount of "uid," not the target reagent tank. + + // if the receiver has a smaller transfer limit, use that instead + if (refill?.MaxRefill is {} maxRefill) + transferAmount = FixedPoint2.Min(transferAmount, maxRefill); + + var transferred = Transfer(args.User, target, targetSoln.Value, uid, ownerSoln.Value, transferAmount); + if (transferred > 0) + { + var toTheBrim = ownerRefill.AvailableVolume == 0; + var msg = toTheBrim + ? "comp-solution-transfer-fill-fully" + : "comp-solution-transfer-fill-normal"; + + _popup.PopupClient(Loc.GetString(msg, ("owner", args.Target), ("amount", transferred), ("target", uid)), uid, args.User); + + args.Handled = true; + return; + } + } + + // if target is refillable, and owner is drainable + if (comp.CanSend + && TryComp(target, out var targetRefill) + && _solution.TryGetRefillableSolution((target, targetRefill, null), out targetSoln, out _) + && _solution.TryGetDrainableSolution(uid, out ownerSoln, out _)) + { + var transferAmount = comp.TransferAmount; + + if (targetRefill?.MaxRefill is {} maxRefill) + transferAmount = FixedPoint2.Min(transferAmount, maxRefill); + + var transferred = Transfer(args.User, uid, ownerSoln.Value, target, targetSoln.Value, transferAmount); + + if (transferred > 0) + { + var message = Loc.GetString("comp-solution-transfer-transfer-solution", ("amount", transferred), ("target", target)); + _popup.PopupClient(message, uid, args.User); + + args.Handled = true; + } + } + } + + /// + /// Transfer from a solution to another, allowing either entity to cancel it and show a popup. + /// + /// The actual amount transferred. + public FixedPoint2 Transfer(EntityUid user, + EntityUid sourceEntity, + Entity source, + EntityUid targetEntity, + Entity target, + FixedPoint2 amount) + { + var transferAttempt = new SolutionTransferAttemptEvent(sourceEntity, targetEntity); + + // Check if the source is cancelling the transfer + RaiseLocalEvent(sourceEntity, ref transferAttempt); + if (transferAttempt.CancelReason is {} reason) + { + _popup.PopupClient(reason, sourceEntity, user); + return FixedPoint2.Zero; + } + + var sourceSolution = source.Comp.Solution; + if (sourceSolution.Volume == 0) + { + _popup.PopupClient(Loc.GetString("comp-solution-transfer-is-empty", ("target", sourceEntity)), sourceEntity, user); + return FixedPoint2.Zero; + } + + // Check if the target is cancelling the transfer + RaiseLocalEvent(targetEntity, ref transferAttempt); + if (transferAttempt.CancelReason is {} targetReason) + { + _popup.PopupClient(targetReason, targetEntity, user); + return FixedPoint2.Zero; + } + + var targetSolution = target.Comp.Solution; + if (targetSolution.AvailableVolume == 0) + { + _popup.PopupClient(Loc.GetString("comp-solution-transfer-is-full", ("target", targetEntity)), targetEntity, user); + return FixedPoint2.Zero; + } + + var actualAmount = FixedPoint2.Min(amount, FixedPoint2.Min(sourceSolution.Volume, targetSolution.AvailableVolume)); + + var solution = _solution.SplitSolution(source, actualAmount); + _solution.Refill(targetEntity, target, solution); + + _adminLogger.Add(LogType.Action, LogImpact.Medium, + $"{ToPrettyString(user):player} transferred {SharedSolutionContainerSystem.ToPrettyString(solution)} to {ToPrettyString(targetEntity):target}, which now contains {SharedSolutionContainerSystem.ToPrettyString(targetSolution)}"); + + return actualAmount; + } +} + +/// +/// Raised when attempting to transfer from one solution to another. +/// Raised on both the source and target entities so either can cancel the transfer. +/// To not mispredict this should always be cancelled in shared code and not server or client. +/// +[ByRefEvent] +public record struct SolutionTransferAttemptEvent(EntityUid From, EntityUid To, string? CancelReason = null) +{ + /// + /// Cancels the transfer. + /// + public void Cancel(string reason) + { + CancelReason = reason; + } +} diff --git a/Content.Shared/Construction/Components/ComputerBoardComponent.cs b/Content.Shared/Construction/Components/ComputerBoardComponent.cs index f80a668778..539e09245d 100644 --- a/Content.Shared/Construction/Components/ComputerBoardComponent.cs +++ b/Content.Shared/Construction/Components/ComputerBoardComponent.cs @@ -1,4 +1,4 @@ -using Robust.Shared.Prototypes; +using Robust.Shared.Prototypes; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; namespace Content.Shared.Construction.Components @@ -9,7 +9,7 @@ namespace Content.Shared.Construction.Components [RegisterComponent] public sealed partial class ComputerBoardComponent : Component { - [DataField("prototype", customTypeSerializer:typeof(PrototypeIdSerializer))] + [DataField("prototype", customTypeSerializer: typeof(PrototypeIdSerializer))] public string? Prototype { get; private set; } } } diff --git a/Content.Shared/Disposal/Components/SharedDisposalUnitComponent.cs b/Content.Shared/Disposal/Components/SharedDisposalUnitComponent.cs index 72586be1ec..4948cb6640 100644 --- a/Content.Shared/Disposal/Components/SharedDisposalUnitComponent.cs +++ b/Content.Shared/Disposal/Components/SharedDisposalUnitComponent.cs @@ -1,4 +1,5 @@ using Robust.Shared.Audio; +using Content.Shared.Whitelist; using Robust.Shared.Containers; using Robust.Shared.GameStates; using Robust.Shared.Serialization; @@ -17,6 +18,18 @@ public abstract partial class SharedDisposalUnitComponent : Component [ViewVariables(VVAccess.ReadWrite), DataField("soundFlush")] public SoundSpecifier? FlushSound = new SoundPathSpecifier("/Audio/Machines/disposalflush.ogg"); + /// + /// Blacklists (prevents) entities listed from being placed inside. + /// + [DataField] + public EntityWhitelist? Blacklist; + + /// + /// Whitelists (allows) entities listed from being placed inside. + /// + [DataField] + public EntityWhitelist? Whitelist; + /// /// Sound played when an object is inserted into the disposal unit. /// @@ -33,20 +46,20 @@ public abstract partial class SharedDisposalUnitComponent : Component /// /// State for this disposals unit. /// - [DataField("state")] + [DataField] public DisposalsPressureState State; // TODO: Just make this use vaulting. /// /// We'll track whatever just left disposals so we know what collision we need to ignore until they stop intersecting our BB. /// - [ViewVariables, DataField("recentlyEjected")] + [ViewVariables, DataField] public List RecentlyEjected = new(); /// /// Next time the disposal unit will be pressurized. /// - [DataField("nextPressurized", customTypeSerializer:typeof(TimeOffsetSerializer))] + [DataField(customTypeSerializer:typeof(TimeOffsetSerializer))] public TimeSpan NextPressurized = TimeSpan.Zero; /// @@ -58,63 +71,60 @@ public abstract partial class SharedDisposalUnitComponent : Component /// /// How long it takes from the start of a flush animation to return the sprite to normal. /// - [DataField("flushDelay")] + [DataField] public TimeSpan FlushDelay = TimeSpan.FromSeconds(3); - [DataField("mobsCanEnter")] - public bool MobsCanEnter = true; - /// /// Removes the pressure requirement for flushing. /// - [DataField("disablePressure"), ViewVariables(VVAccess.ReadWrite)] + [DataField, ViewVariables(VVAccess.ReadWrite)] public bool DisablePressure; /// - /// Last time that an entity tried to exit this disposal unit. + /// Last time that an entity tried to exit this disposal unit. /// [ViewVariables] public TimeSpan LastExitAttempt; - [DataField("autoEngageEnabled")] + [DataField] public bool AutomaticEngage = true; [ViewVariables(VVAccess.ReadWrite)] - [DataField("autoEngageTime")] + [DataField] public TimeSpan AutomaticEngageTime = TimeSpan.FromSeconds(30); /// - /// Delay from trying to enter disposals ourselves. + /// Delay from trying to enter disposals ourselves. /// [ViewVariables(VVAccess.ReadWrite)] - [DataField("entryDelay")] + [DataField] public float EntryDelay = 0.5f; /// - /// Delay from trying to shove someone else into disposals. + /// Delay from trying to shove someone else into disposals. /// [ViewVariables(VVAccess.ReadWrite)] public float DraggedEntryDelay = 2.0f; /// - /// Container of entities inside this disposal unit. + /// Container of entities inside this disposal unit. /// [ViewVariables] public Container Container = default!; // TODO: Network power shit instead fam. - [ViewVariables, DataField("powered")] + [ViewVariables, DataField] public bool Powered; /// /// Was the disposals unit engaged for a manual flush. /// - [ViewVariables(VVAccess.ReadWrite), DataField("engaged")] + [ViewVariables(VVAccess.ReadWrite), DataField] public bool Engaged; /// /// Next time this unit will flush. Is the lesser of and /// - [ViewVariables, DataField("nextFlush", customTypeSerializer:typeof(TimeOffsetSerializer))] + [ViewVariables, DataField(customTypeSerializer:typeof(TimeOffsetSerializer))] public TimeSpan? NextFlush; [Serializable, NetSerializable] @@ -130,8 +140,8 @@ public abstract partial class SharedDisposalUnitComponent : Component { UnAnchored, Anchored, - Flushing, - Charging + OverlayFlushing, + OverlayCharging } [Serializable, NetSerializable] diff --git a/Content.Shared/Disposal/SharedDisposalUnitSystem.cs b/Content.Shared/Disposal/SharedDisposalUnitSystem.cs index 9afd683cbd..c39139f9a5 100644 --- a/Content.Shared/Disposal/SharedDisposalUnitSystem.cs +++ b/Content.Shared/Disposal/SharedDisposalUnitSystem.cs @@ -1,12 +1,10 @@ -using System.Diagnostics.CodeAnalysis; +using System.Diagnostics.CodeAnalysis; using Content.Shared.Body.Components; using Content.Shared.Disposal.Components; using Content.Shared.DoAfter; using Content.Shared.DragDrop; using Content.Shared.Emag.Systems; using Content.Shared.Item; -using Content.Shared.Mobs.Components; -using Content.Shared.Mobs.Systems; using Content.Shared.Throwing; using Robust.Shared.Audio; using Robust.Shared.Physics.Components; @@ -26,7 +24,6 @@ public abstract class SharedDisposalUnitSystem : EntitySystem { [Dependency] protected readonly IGameTiming GameTiming = default!; [Dependency] protected readonly MetaDataSystem Metadata = default!; - [Dependency] private readonly MobStateSystem _mobState = default!; [Dependency] protected readonly SharedJointSystem Joints = default!; protected static TimeSpan ExitAttemptDelay = TimeSpan.FromSeconds(0.5); @@ -112,19 +109,21 @@ public abstract class SharedDisposalUnitSystem : EntitySystem if (!Transform(uid).Anchored) return false; - // TODO: Probably just need a disposable tag. var storable = HasComp(entity); if (!storable && !HasComp(entity)) return false; - //Check if the entity is a mob and if mobs can be inserted - if (TryComp(entity, out var damageState) && !component.MobsCanEnter) + if (component.Blacklist?.IsValid(entity, EntityManager) == true) return false; - if (TryComp(entity, out var physics) && (physics.CanCollide || storable)) - return true; + if (component.Whitelist != null && component.Whitelist?.IsValid(entity, EntityManager) != true) + return false; + + if (TryComp(entity, out var physics) && (physics.CanCollide) || storable) + return true; + else + return false; - return damageState != null && (!component.MobsCanEnter || _mobState.IsDead(entity, damageState)); } public abstract void DoInsertDisposalUnit(EntityUid uid, EntityUid toInsert, EntityUid user, SharedDisposalUnitComponent? disposal = null); diff --git a/Content.Shared/Doors/Electronics/DoorElectronicsComponent.cs b/Content.Shared/Doors/Electronics/DoorElectronicsComponent.cs new file mode 100644 index 0000000000..3e9f279ee5 --- /dev/null +++ b/Content.Shared/Doors/Electronics/DoorElectronicsComponent.cs @@ -0,0 +1,42 @@ +using Robust.Shared.GameStates; +using Robust.Shared.Serialization; +using Robust.Shared.Prototypes; +using Content.Shared.Access; + +namespace Content.Shared.Doors.Electronics; + +/// +/// Allows an entity's AccessReader to be configured via UI. +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class DoorElectronicsComponent : Component +{ +} + +[Serializable, NetSerializable] +public sealed class DoorElectronicsUpdateConfigurationMessage : BoundUserInterfaceMessage +{ + public List> AccessList; + + public DoorElectronicsUpdateConfigurationMessage(List> accessList) + { + AccessList = accessList; + } +} + +[Serializable, NetSerializable] +public sealed class DoorElectronicsConfigurationState : BoundUserInterfaceState +{ + public List> AccessList; + + public DoorElectronicsConfigurationState(List> accessList) + { + AccessList = accessList; + } +} + +[Serializable, NetSerializable] +public enum DoorElectronicsConfigurationUiKey : byte +{ + Key +} diff --git a/Content.Shared/Fluids/SharedPuddleSystem.Spillable.cs b/Content.Shared/Fluids/SharedPuddleSystem.Spillable.cs index 1e9e742a38..f88f13e8b0 100644 --- a/Content.Shared/Fluids/SharedPuddleSystem.Spillable.cs +++ b/Content.Shared/Fluids/SharedPuddleSystem.Spillable.cs @@ -1,3 +1,4 @@ +using Content.Shared.Chemistry.Components; using Content.Shared.Database; using Content.Shared.DoAfter; using Content.Shared.Examine; @@ -12,7 +13,7 @@ namespace Content.Shared.Fluids; public abstract partial class SharedPuddleSystem { - [Dependency] protected readonly SharedOpenableSystem Openable = default!; + [Dependency] protected readonly OpenableSystem Openable = default!; protected virtual void InitializeSpillable() { @@ -62,6 +63,12 @@ public abstract partial class SharedPuddleSystem { var puddleSolution = _solutionContainerSystem.SplitSolution(soln.Value, solution.Volume); TrySpillAt(Transform(target).Coordinates, puddleSolution, out _); + + if (TryComp(entity, out var injectorComp)) + { + injectorComp.ToggleState = InjectorToggleMode.Draw; + Dirty(entity, injectorComp); + } }; } else diff --git a/Content.Shared/Hands/Components/HandsComponent.cs b/Content.Shared/Hands/Components/HandsComponent.cs index 904b10b3bd..f1f25a69f7 100644 --- a/Content.Shared/Hands/Components/HandsComponent.cs +++ b/Content.Shared/Hands/Components/HandsComponent.cs @@ -31,6 +31,12 @@ public sealed partial class HandsComponent : Component /// public List SortedHands = new(); + /// + /// If true, the items in the hands won't be affected by explosions. + /// + [DataField] + public bool DisableExplosionRecursion = false; + /// /// The amount of throw impulse per distance the player is from the throw target. /// diff --git a/Content.Shared/Hands/EntitySystems/SharedHandsSystem.Drop.cs b/Content.Shared/Hands/EntitySystems/SharedHandsSystem.Drop.cs index e071cdc693..7b169b5d0a 100644 --- a/Content.Shared/Hands/EntitySystems/SharedHandsSystem.Drop.cs +++ b/Content.Shared/Hands/EntitySystems/SharedHandsSystem.Drop.cs @@ -134,8 +134,10 @@ public abstract partial class SharedHandsSystem return true; } + var (itemPos, itemRot) = TransformSystem.GetWorldPositionRotation(entity); + var origin = new MapCoordinates(itemPos, itemXform.MapID); var target = targetDropLocation.Value.ToMap(EntityManager, TransformSystem); - TransformSystem.SetWorldPosition(itemXform, GetFinalDropCoordinates(uid, userXform.MapPosition, target)); + TransformSystem.SetWorldPositionRotation(entity, GetFinalDropCoordinates(uid, origin, target), itemRot); return true; } diff --git a/Content.Shared/Lock/LockSystem.cs b/Content.Shared/Lock/LockSystem.cs index 6f7769e708..e6d1e1694e 100644 --- a/Content.Shared/Lock/LockSystem.cs +++ b/Content.Shared/Lock/LockSystem.cs @@ -1,6 +1,7 @@ using Content.Shared.Access.Components; using Content.Shared.Access.Systems; using Content.Shared.CrystallPunk.LockKey; +using Content.Shared.Construction.Components; using Content.Shared.DoAfter; using Content.Shared.Doors; using Content.Shared.Emag.Systems; @@ -11,6 +12,7 @@ using Content.Shared.Interaction; using Content.Shared.Popups; using Content.Shared.Storage.Components; using Content.Shared.Verbs; +using Content.Shared.Wires; using JetBrains.Annotations; using Robust.Shared.Audio.Systems; using Robust.Shared.Utility; @@ -44,8 +46,11 @@ public sealed class LockSystem : EntitySystem SubscribeLocalEvent(OnDoAfterLock); SubscribeLocalEvent(OnDoAfterUnlock); SubscribeLocalEvent(OnBeforeDoorOpened); //CrystallPunk Lock System Adapt - } + SubscribeLocalEvent(OnLockToggleAttempt); + SubscribeLocalEvent(OnAttemptChangePanel); + SubscribeLocalEvent(OnUnanchorAttempt); + } private void OnStartup(EntityUid uid, LockComponent lockComp, ComponentStartup args) { _appearanceSystem.SetData(uid, LockVisuals.Locked, lockComp.Locked); @@ -255,25 +260,25 @@ public sealed class LockSystem : EntitySystem { //CrystallPunk Lock System Adapt - //if (!args.CanAccess || !args.CanInteract || !CanToggleLock(uid, args.User)) + //if (!args.CanAccess || !args.CanInteract) // return; // //AlternativeVerb verb = new() //{ - // Act = component.Locked ? - // () => TryUnlock(uid, args.User, component) : - // () => TryLock(uid, args.User, component), + // Act = component.Locked + // ? () => TryUnlock(uid, args.User, component) + // : () => TryLock(uid, args.User, component), // Text = Loc.GetString(component.Locked ? "toggle-lock-verb-unlock" : "toggle-lock-verb-lock"), - // Icon = component.Locked ? - // new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/unlock.svg.192dpi.png")) : - // new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/lock.svg.192dpi.png")), + // Icon = !component.Locked + // ? new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/lock.svg.192dpi.png")) + // : new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/unlock.svg.192dpi.png")), //}; //args.Verbs.Add(verb); //CrystallPunk Lock System Adapt End } - private void OnEmagged(EntityUid uid, LockComponent component, ref GotEmaggedEvent args) +private void OnEmagged(EntityUid uid, LockComponent component, ref GotEmaggedEvent args) { if (!component.Locked || !component.BreakOnEmag) return; @@ -306,5 +311,53 @@ public sealed class LockSystem : EntitySystem TryUnlock(uid, args.User, skipDoAfter: true); } + + private void OnLockToggleAttempt(Entity ent, ref LockToggleAttemptEvent args) + { + if (args.Cancelled) + return; + + if (!TryComp(ent, out var panel) || !panel.Open) + return; + + if (!args.Silent) + { + _sharedPopupSystem.PopupClient(Loc.GetString("construction-step-condition-wire-panel-close"), + ent, + args.User); + } + args.Cancelled = true; + } + + + private void OnAttemptChangePanel(Entity ent, ref AttemptChangePanelEvent args) + { + if (args.Cancelled) + return; + + if (!TryComp(ent, out var lockComp) || !lockComp.Locked) + return; + + _sharedPopupSystem.PopupClient(Loc.GetString("lock-comp-generic-fail", + ("target", Identity.Entity(ent, EntityManager))), + ent, + args.User); + args.Cancelled = true; + } + + private void OnUnanchorAttempt(Entity ent, ref UnanchorAttemptEvent args) + { + if (args.Cancelled) + return; + + if (!TryComp(ent, out var lockComp) || !lockComp.Locked) + return; + + _sharedPopupSystem.PopupClient(Loc.GetString("lock-comp-generic-fail", + ("target", Identity.Entity(ent, EntityManager))), + ent, + args.User); + args.Cancel(); + } } diff --git a/Content.Shared/Lock/LockedAnchorableComponent.cs b/Content.Shared/Lock/LockedAnchorableComponent.cs new file mode 100644 index 0000000000..781b7f6532 --- /dev/null +++ b/Content.Shared/Lock/LockedAnchorableComponent.cs @@ -0,0 +1,13 @@ +using Content.Shared.Construction.Components; +using Robust.Shared.GameStates; + +namespace Content.Shared.Lock; + +/// +/// This is used for a that cannot be unanchored while locked. +/// +[RegisterComponent, NetworkedComponent, Access(typeof(LockSystem))] +public sealed partial class LockedAnchorableComponent : Component +{ + +} diff --git a/Content.Shared/Lock/LockedWiresPanelComponent.cs b/Content.Shared/Lock/LockedWiresPanelComponent.cs new file mode 100644 index 0000000000..1dbe6a4932 --- /dev/null +++ b/Content.Shared/Lock/LockedWiresPanelComponent.cs @@ -0,0 +1,13 @@ +using Content.Shared.Wires; +using Robust.Shared.GameStates; + +namespace Content.Shared.Lock; + +/// +/// This is used for a that cannot be opened while locked. +/// +[RegisterComponent, NetworkedComponent, Access(typeof(LockSystem))] +public sealed partial class LockedWiresPanelComponent : Component +{ + +} diff --git a/Content.Shared/Nutrition/Components/OpenableComponent.cs b/Content.Shared/Nutrition/Components/OpenableComponent.cs index 3a230fc765..0381888e28 100644 --- a/Content.Shared/Nutrition/Components/OpenableComponent.cs +++ b/Content.Shared/Nutrition/Components/OpenableComponent.cs @@ -9,7 +9,7 @@ namespace Content.Shared.Nutrition.Components; /// Starts closed, open it with Z or E. /// [NetworkedComponent, AutoGenerateComponentState] -[RegisterComponent, Access(typeof(SharedOpenableSystem))] +[RegisterComponent, Access(typeof(OpenableSystem))] public sealed partial class OpenableComponent : Component { /// diff --git a/Content.Shared/Nutrition/EntitySystems/SharedOpenableSystem.cs b/Content.Shared/Nutrition/EntitySystems/OpenableSystem.cs similarity index 91% rename from Content.Shared/Nutrition/EntitySystems/SharedOpenableSystem.cs rename to Content.Shared/Nutrition/EntitySystems/OpenableSystem.cs index f3b1127578..0ad0877d22 100644 --- a/Content.Shared/Nutrition/EntitySystems/SharedOpenableSystem.cs +++ b/Content.Shared/Nutrition/EntitySystems/OpenableSystem.cs @@ -1,3 +1,4 @@ +using Content.Shared.Chemistry.EntitySystems; using Content.Shared.Examine; using Content.Shared.Interaction; using Content.Shared.Interaction.Events; @@ -13,7 +14,7 @@ namespace Content.Shared.Nutrition.EntitySystems; /// /// Provides API for openable food and drinks, handles opening on use and preventing transfer when closed. /// -public abstract partial class SharedOpenableSystem : EntitySystem +public sealed partial class OpenableSystem : EntitySystem { [Dependency] protected readonly SharedAppearanceSystem Appearance = default!; [Dependency] protected readonly SharedAudioSystem Audio = default!; @@ -29,6 +30,7 @@ public abstract partial class SharedOpenableSystem : EntitySystem SubscribeLocalEvent(HandleIfClosed); SubscribeLocalEvent(HandleIfClosed); SubscribeLocalEvent>(AddOpenCloseVerbs); + SubscribeLocalEvent(OnTransferAttempt); } private void OnInit(EntityUid uid, OpenableComponent comp, ComponentInit args) @@ -89,6 +91,15 @@ public abstract partial class SharedOpenableSystem : EntitySystem args.Verbs.Add(verb); } + private void OnTransferAttempt(Entity ent, ref SolutionTransferAttemptEvent args) + { + if (!ent.Comp.Opened) + { + // message says its just for drinks, shouldn't matter since you typically dont have a food that is openable and can be poured out + args.Cancel(Loc.GetString("drink-component-try-use-drink-not-open", ("owner", ent.Owner))); + } + } + /// /// Returns true if the entity either does not have OpenableComponent or it is opened. /// Drinks that don't have OpenableComponent are automatically open, so it returns true. diff --git a/Content.Shared/Nutrition/EntitySystems/SealableSystem.cs b/Content.Shared/Nutrition/EntitySystems/SealableSystem.cs index b0873f23a1..414b8d182b 100644 --- a/Content.Shared/Nutrition/EntitySystems/SealableSystem.cs +++ b/Content.Shared/Nutrition/EntitySystems/SealableSystem.cs @@ -11,7 +11,7 @@ public sealed partial class SealableSystem : EntitySystem { base.Initialize(); - SubscribeLocalEvent(OnExamined, after: new[] { typeof(SharedOpenableSystem) }); + SubscribeLocalEvent(OnExamined, after: new[] { typeof(OpenableSystem) }); SubscribeLocalEvent(OnOpened); } diff --git a/Content.Shared/Objectives/Systems/SharedObjectivesSystem.cs b/Content.Shared/Objectives/Systems/SharedObjectivesSystem.cs index 2e1bdc4383..07032a00ce 100644 --- a/Content.Shared/Objectives/Systems/SharedObjectivesSystem.cs +++ b/Content.Shared/Objectives/Systems/SharedObjectivesSystem.cs @@ -1,6 +1,7 @@ using Content.Shared.Mind; using Content.Shared.Objectives; using Content.Shared.Objectives.Components; +using Robust.Shared.Prototypes; using Robust.Shared.Utility; namespace Content.Shared.Objectives.Systems; @@ -11,6 +12,7 @@ namespace Content.Shared.Objectives.Systems; public abstract class SharedObjectivesSystem : EntitySystem { [Dependency] private readonly SharedMindSystem _mind = default!; + [Dependency] private readonly IPrototypeManager _protoMan = default!; private EntityQuery _metaQuery; @@ -55,6 +57,9 @@ public abstract class SharedObjectivesSystem : EntitySystem /// public EntityUid? TryCreateObjective(EntityUid mindId, MindComponent mind, string proto) { + if (!_protoMan.HasIndex(proto)) + return null; + var uid = Spawn(proto); if (!TryComp(uid, out var comp)) { diff --git a/Content.Shared/Paint/PaintComponent.cs b/Content.Shared/Paint/PaintComponent.cs deleted file mode 100644 index ad09f4ca73..0000000000 --- a/Content.Shared/Paint/PaintComponent.cs +++ /dev/null @@ -1,60 +0,0 @@ -using Content.Shared.Chemistry.Reagent; -using Content.Shared.FixedPoint; -using Robust.Shared.Audio; -using Content.Shared.Whitelist; -using Robust.Shared.Prototypes; -using Robust.Shared.GameStates; - -namespace Content.Shared.Paint; - -/// -/// Entity when used on another entity will paint target entity. -/// -[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] -[Access(typeof(SharedPaintSystem))] -public sealed partial class PaintComponent : Component -{ - /// - /// Noise made when paint applied. - /// - [DataField] - public SoundSpecifier Spray = new SoundPathSpecifier("/Audio/Effects/spray2.ogg"); - - /// - /// Solution on the entity that contains the paint. - /// - [DataField] - public string Solution = "drink"; - - /// - /// How long the doafter will take. - /// - [DataField] - public int Delay = 2; - - /// - /// Reagent that will be used as paint. - /// - [DataField, AutoNetworkedField] - public ProtoId Reagent = "SpaceGlue"; - - /// - /// Color that the painting entity will instruct the painted entity to be. - /// - [DataField, AutoNetworkedField] - public Color Color = Color.FromHex("#c62121"); - - [DataField, ViewVariables(VVAccess.ReadWrite)] - public EntityWhitelist? Blacklist; - /// - /// Reagent consumption per use. - /// - [DataField] - public FixedPoint2 ConsumptionUnit = FixedPoint2.New(5); - - /// - /// Duration per unit - /// - [DataField] - public TimeSpan DurationPerUnit = TimeSpan.FromSeconds(6); -} diff --git a/Content.Shared/Paint/PaintDoAfterEvent.cs b/Content.Shared/Paint/PaintDoAfterEvent.cs deleted file mode 100644 index 0851f1541b..0000000000 --- a/Content.Shared/Paint/PaintDoAfterEvent.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Content.Shared.DoAfter; -using Robust.Shared.Serialization; - -namespace Content.Shared.Paint; - -[Serializable, NetSerializable] -public sealed partial class PaintDoAfterEvent : SimpleDoAfterEvent -{ -} diff --git a/Content.Shared/Paint/PaintRemoverComponent.cs b/Content.Shared/Paint/PaintRemoverComponent.cs deleted file mode 100644 index 54d0ed7a71..0000000000 --- a/Content.Shared/Paint/PaintRemoverComponent.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Robust.Shared.GameStates; -using Robust.Shared.Audio; - -namespace Content.Shared.Paint; - -/// -/// Removes paint from an entity that was painted with spray paint. -/// -[RegisterComponent, NetworkedComponent] -[Access(typeof(PaintRemoverSystem))] -public sealed partial class PaintRemoverComponent : Component -{ - /// - /// Sound when target is cleaned. - /// - [DataField] - public SoundSpecifier Sound = new SoundPathSpecifier("/Audio/Effects/Fluids/watersplash.ogg"); - - /// - /// DoAfter wait time. - /// - [DataField] - public float CleanDelay = 2f; -} diff --git a/Content.Shared/Paint/PaintRemoverDoAfterEvent.cs b/Content.Shared/Paint/PaintRemoverDoAfterEvent.cs deleted file mode 100644 index 940b1aa513..0000000000 --- a/Content.Shared/Paint/PaintRemoverDoAfterEvent.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Content.Shared.DoAfter; -using Robust.Shared.Serialization; - -namespace Content.Shared.Paint; - -[Serializable, NetSerializable] -public sealed partial class PaintRemoverDoAfterEvent : SimpleDoAfterEvent -{ -} diff --git a/Content.Shared/Paint/PaintRemoverSystem.cs b/Content.Shared/Paint/PaintRemoverSystem.cs deleted file mode 100644 index efc1ded067..0000000000 --- a/Content.Shared/Paint/PaintRemoverSystem.cs +++ /dev/null @@ -1,94 +0,0 @@ -using Content.Shared.Popups; -using Content.Shared.Interaction; -using Content.Shared.DoAfter; -using Content.Shared.Verbs; -using Content.Shared.Sprite; -using Robust.Shared.Audio.Systems; -using Robust.Shared.Timing; - -namespace Content.Shared.Paint; - -/// -/// Removes paint from an entity. -/// -public sealed class PaintRemoverSystem : SharedPaintSystem -{ - [Dependency] private readonly SharedPopupSystem _popup = default!; - [Dependency] private readonly SharedDoAfterSystem _doAfter = default!; - [Dependency] private readonly SharedAudioSystem _audio = default!; - [Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!; - - public override void Initialize() - { - base.Initialize(); - - SubscribeLocalEvent(OnInteract); - SubscribeLocalEvent(OnDoAfter); - SubscribeLocalEvent>(OnPaintRemoveVerb); - } - - // When entity is painted, remove paint from that entity. - private void OnInteract(EntityUid uid, PaintRemoverComponent component, AfterInteractEvent args) - { - if (args.Handled) - return; - - if (!args.CanReach || args.Target is not { Valid: true } target || !HasComp(target)) - return; - - _doAfter.TryStartDoAfter(new DoAfterArgs(EntityManager, args.User, component.CleanDelay, new PaintRemoverDoAfterEvent(), uid, args.Target, uid) - { - BreakOnMove = true, - BreakOnDamage = true, - MovementThreshold = 1.0f, - }); - args.Handled = true; - } - - private void OnDoAfter(EntityUid uid, PaintRemoverComponent component, DoAfterEvent args) - { - if (args.Cancelled || args.Handled || args.Args.Target == null) - return; - - if (args.Target is not { Valid: true } target) - return; - - if (!TryComp(target, out PaintedComponent? paint)) - return; - - paint.Enabled = false; - _audio.PlayPredicted(component.Sound, target, args.User); - _popup.PopupClient(Loc.GetString("paint-removed", ("target", target)), args.User, args.User, PopupType.Medium); - _appearanceSystem.SetData(target, PaintVisuals.Painted, false); - RemComp(target); - Dirty(target, paint); - - args.Handled = true; - } - - private void OnPaintRemoveVerb(EntityUid uid, PaintRemoverComponent component, GetVerbsEvent args) - { - if (!args.CanInteract || !args.CanAccess) - return; - - var paintremovalText = Loc.GetString("paint-remove-verb"); - - var verb = new UtilityVerb() - { - Act = () => - { - - _doAfter.TryStartDoAfter(new DoAfterArgs(EntityManager, args.User, component.CleanDelay, new PaintRemoverDoAfterEvent(), uid, args.Target, uid) - { - BreakOnMove = true, - BreakOnDamage = true, - MovementThreshold = 1.0f, - }); - }, - - Text = paintremovalText - }; - - args.Verbs.Add(verb); - } -} diff --git a/Content.Shared/Paint/PaintedComponent.cs b/Content.Shared/Paint/PaintedComponent.cs deleted file mode 100644 index a6ee7377e1..0000000000 --- a/Content.Shared/Paint/PaintedComponent.cs +++ /dev/null @@ -1,41 +0,0 @@ -using Robust.Shared.GameStates; -using Robust.Shared.Serialization; - -namespace Content.Shared.Paint; - -/// -/// Component applied to target entity when painted. -/// -[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] -public sealed partial class PaintedComponent : Component -{ - /// - /// Color of the paint. - /// - [DataField, AutoNetworkedField] - public Color Color = Color.FromHex("#2cdbd5"); - - /// - /// Used to remove the color when component removed. - /// - [DataField, AutoNetworkedField] - public Color BeforeColor; - - /// - /// If paint is enabled. - /// - [DataField, AutoNetworkedField] - public bool Enabled; - - /// - /// Name of the shader. - /// - [DataField, AutoNetworkedField] - public string ShaderName = "Greyscale"; -} - -[Serializable, NetSerializable] -public enum PaintVisuals : byte -{ - Painted, -} diff --git a/Content.Shared/Paint/SharedPaintSystem.cs b/Content.Shared/Paint/SharedPaintSystem.cs deleted file mode 100644 index 10185817b8..0000000000 --- a/Content.Shared/Paint/SharedPaintSystem.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Content.Shared.Paint; - -/// -/// Colors target and consumes reagent on each color success. -/// -public abstract class SharedPaintSystem : EntitySystem -{ - public virtual void UpdateAppearance(EntityUid uid, PaintedComponent? component = null) - { - } -} diff --git a/Content.Server/Plants/Components/PottedPlantHideComponent.cs b/Content.Shared/Plants/PottedPlantHideComponent.cs similarity index 80% rename from Content.Server/Plants/Components/PottedPlantHideComponent.cs rename to Content.Shared/Plants/PottedPlantHideComponent.cs index bc35bbe44f..2e02272494 100644 --- a/Content.Server/Plants/Components/PottedPlantHideComponent.cs +++ b/Content.Shared/Plants/PottedPlantHideComponent.cs @@ -1,8 +1,7 @@ -using Content.Server.Plants.Systems; -using Content.Server.Storage.Components; +using Content.Shared.Storage.Components; using Robust.Shared.Audio; -namespace Content.Server.Plants.Components +namespace Content.Shared.Plants { /// /// Interaction wrapper for . diff --git a/Content.Server/Plants/Systems/PottedPlantHideSystem.cs b/Content.Shared/Plants/PottedPlantHideSystem.cs similarity index 86% rename from Content.Server/Plants/Systems/PottedPlantHideSystem.cs rename to Content.Shared/Plants/PottedPlantHideSystem.cs index 09571c60a1..fd256fd926 100644 --- a/Content.Server/Plants/Systems/PottedPlantHideSystem.cs +++ b/Content.Shared/Plants/PottedPlantHideSystem.cs @@ -1,18 +1,15 @@ -using Content.Server.Plants.Components; -using Content.Server.Popups; -using Content.Server.Storage.Components; -using Content.Server.Storage.EntitySystems; -using Content.Shared.Audio; +using Content.Shared.Popups; +using Content.Shared.Storage.Components; +using Content.Shared.Storage.EntitySystems; using Content.Shared.Interaction; using Robust.Shared.Audio; using Robust.Shared.Audio.Systems; -using Robust.Shared.Player; -namespace Content.Server.Plants.Systems +namespace Content.Shared.Plants { public sealed class PottedPlantHideSystem : EntitySystem { - [Dependency] private readonly PopupSystem _popupSystem = default!; + [Dependency] private readonly SharedPopupSystem _popupSystem = default!; [Dependency] private readonly SecretStashSystem _stashSystem = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; diff --git a/Content.Shared/Plunger/Components/PlungerComponent.cs b/Content.Shared/Plunger/Components/PlungerComponent.cs new file mode 100644 index 0000000000..101121fe4c --- /dev/null +++ b/Content.Shared/Plunger/Components/PlungerComponent.cs @@ -0,0 +1,18 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Plunger.Components +{ + /// + /// Allows entity to unblock target entity with PlungerUseComponent. + /// + [RegisterComponent, NetworkedComponent,AutoGenerateComponentState] + public sealed partial class PlungerComponent : Component + { + /// + /// Duration of plunger doafter event. + /// + [DataField] + [AutoNetworkedField] + public float PlungeDuration = 2f; + } +} diff --git a/Content.Shared/Plunger/Components/PlungerUseComponent.cs b/Content.Shared/Plunger/Components/PlungerUseComponent.cs new file mode 100644 index 0000000000..e886a4ef7a --- /dev/null +++ b/Content.Shared/Plunger/Components/PlungerUseComponent.cs @@ -0,0 +1,42 @@ +using Robust.Shared.Audio; +using Robust.Shared.GameStates; +using Content.Shared.Random; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Plunger.Components +{ + /// + /// Entity can interact with plungers. + /// + [RegisterComponent, NetworkedComponent, AutoGenerateComponentState] + public sealed partial class PlungerUseComponent : Component + { + /// + /// If true entity has been plungered. + /// + [DataField] + [AutoNetworkedField] + public bool Plunged; + + /// + /// If true entity can interact with plunger. + /// + [DataField] + [AutoNetworkedField] + public bool NeedsPlunger = false; + + /// + /// A weighted random entity prototype containing the different loot that rummaging can provide. + /// + [DataField] + [AutoNetworkedField] + public ProtoId PlungerLoot = "PlungerLoot"; + + + /// + /// Sound played on rummage completion. + /// + [DataField] + public SoundSpecifier Sound = new SoundPathSpecifier("/Audio/Effects/Fluids/glug.ogg"); + } +} diff --git a/Content.Shared/Plunger/PlungerDoAfterEvent.cs b/Content.Shared/Plunger/PlungerDoAfterEvent.cs new file mode 100644 index 0000000000..b803f5136f --- /dev/null +++ b/Content.Shared/Plunger/PlungerDoAfterEvent.cs @@ -0,0 +1,10 @@ + +using Content.Shared.DoAfter; +using Robust.Shared.Serialization; + +namespace Content.Shared.Plunger; + +[Serializable, NetSerializable] +public sealed partial class PlungerDoAfterEvent : SimpleDoAfterEvent +{ +} diff --git a/Content.Shared/Plunger/Systems/PlungerSystem.cs b/Content.Shared/Plunger/Systems/PlungerSystem.cs new file mode 100644 index 0000000000..57bd77a7d9 --- /dev/null +++ b/Content.Shared/Plunger/Systems/PlungerSystem.cs @@ -0,0 +1,79 @@ +using Content.Shared.DoAfter; +using Content.Shared.Interaction; +using Content.Shared.Popups; +using Content.Shared.Plunger.Components; +using Robust.Shared.Audio.Systems; +using Robust.Shared.Timing; +using Content.Shared.Random.Helpers; +using Robust.Shared.Network; +using Robust.Shared.Prototypes; +using Robust.Shared.Random; +using Content.Shared.Random; + +namespace Content.Shared.Plunger.Systems; + +/// +/// Plungers can be used to unblock entities with PlungerUseComponent. +/// +public sealed class PlungerSystem : EntitySystem +{ + [Dependency] protected readonly IPrototypeManager _proto = default!; + [Dependency] protected readonly IRobustRandom _random = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly SharedDoAfterSystem _doAfter = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; + + public override void Initialize() + { + SubscribeLocalEvent(OnInteract); + SubscribeLocalEvent(OnDoAfter); + } + + private void OnInteract(EntityUid uid, PlungerComponent component, AfterInteractEvent args) + { + if (args.Handled) + return; + + if (!args.CanReach || args.Target is not { Valid: true } target) + return; + + if (!TryComp(args.Target, out var plunger)) + return; + + if (plunger.NeedsPlunger) + return; + + _doAfter.TryStartDoAfter(new DoAfterArgs(EntityManager, args.User, component.PlungeDuration, new PlungerDoAfterEvent(), uid, target, uid) + { + BreakOnMove = true, + BreakOnDamage = true, + MovementThreshold = 1.0f, + }); + args.Handled = true; + } + + private void OnDoAfter(EntityUid uid, PlungerComponent component, DoAfterEvent args) + { + if (args.Cancelled || args.Handled || args.Args.Target == null) + return; + + if (args.Target is not { Valid: true } target) + return; + + if (!TryComp(target, out PlungerUseComponent? plunge)) + return; + + _popup.PopupClient(Loc.GetString("plunger-unblock", ("target", target)), args.User, args.User, PopupType.Medium); + plunge.Plunged = true; + + var spawn = _proto.Index(plunge.PlungerLoot).Pick(_random); + + _audio.PlayPredicted(plunge.Sound, uid, uid); + Spawn(spawn, Transform(target).Coordinates); + RemComp(target); + Dirty(target, plunge); + + args.Handled = true; + } +} + diff --git a/Content.Shared/Popups/SharedPopupSystem.cs b/Content.Shared/Popups/SharedPopupSystem.cs index aeb85de2f5..b199884afb 100644 --- a/Content.Shared/Popups/SharedPopupSystem.cs +++ b/Content.Shared/Popups/SharedPopupSystem.cs @@ -86,7 +86,7 @@ namespace Content.Shared.Popups /// Variant of that only runs on the client, outside of prediction. /// Useful for shared code that is always ran by both sides to avoid duplicate popups. /// - public abstract void PopupClient(string? message, EntityUid uid, EntityUid recipient, PopupType type = PopupType.Small); + public abstract void PopupClient(string? message, EntityUid uid, EntityUid? recipient, PopupType type = PopupType.Small); /// /// Variant of for use with prediction. The local client will show diff --git a/Content.Shared/RCD/Components/RCDAmmoComponent.cs b/Content.Shared/RCD/Components/RCDAmmoComponent.cs index 7b1fc001d4..4135b606e2 100644 --- a/Content.Shared/RCD/Components/RCDAmmoComponent.cs +++ b/Content.Shared/RCD/Components/RCDAmmoComponent.cs @@ -12,7 +12,5 @@ public sealed partial class RCDAmmoComponent : Component /// Can be partially transferred into an RCD, until it is empty then it gets deleted. /// [DataField("charges"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] - public int Charges = 5; + public int Charges = 30; } - -// TODO: state??? check if it desyncs diff --git a/Content.Shared/RCD/Components/RCDComponent.cs b/Content.Shared/RCD/Components/RCDComponent.cs index 8e1032884a..39bb6fd3e9 100644 --- a/Content.Shared/RCD/Components/RCDComponent.cs +++ b/Content.Shared/RCD/Components/RCDComponent.cs @@ -1,20 +1,11 @@ -using Content.Shared.Maps; using Content.Shared.RCD.Systems; using Robust.Shared.Audio; using Robust.Shared.GameStates; -using Robust.Shared.Serialization; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; +using Robust.Shared.Physics; +using Robust.Shared.Prototypes; namespace Content.Shared.RCD.Components; -public enum RcdMode : byte -{ - Floors, - Walls, - Airlock, - Deconstruct -} - /// /// Main component for the RCD /// Optionally uses LimitedChargesComponent. @@ -25,27 +16,57 @@ public enum RcdMode : byte public sealed partial class RCDComponent : Component { /// - /// Time taken to do an action like placing a wall + /// List of RCD prototypes that the device comes loaded with /// - [DataField("delay"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] - public float Delay = 2f; - - [DataField("swapModeSound")] - public SoundSpecifier SwapModeSound = new SoundPathSpecifier("/Audio/Items/genhit.ogg"); - - [DataField("successSound")] - public SoundSpecifier SuccessSound = new SoundPathSpecifier("/Audio/Items/deconstruct.ogg"); + [DataField, AutoNetworkedField] + public HashSet> AvailablePrototypes { get; set; } = new(); /// - /// What mode are we on? Can be floors, walls, airlock, deconstruct. + /// Sound that plays when a RCD operation successfully completes /// - [DataField("mode"), AutoNetworkedField] - public RcdMode Mode = RcdMode.Floors; + [DataField] + public SoundSpecifier SuccessSound { get; set; } = new SoundPathSpecifier("/Audio/Items/deconstruct.ogg"); /// - /// ID of the floor to create when using the floor mode. + /// The ProtoId of the currently selected RCD prototype /// - [DataField("floor", customTypeSerializer: typeof(PrototypeIdSerializer))] - [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] - public string Floor = "FloorSteel"; + [DataField, AutoNetworkedField] + public ProtoId ProtoId { get; set; } = "Invalid"; + + /// + /// A cached copy of currently selected RCD prototype + /// + /// + /// If the ProtoId is changed, make sure to update the CachedPrototype as well + /// + [ViewVariables(VVAccess.ReadOnly)] + public RCDPrototype CachedPrototype { get; set; } = default!; + + /// + /// The direction constructed entities will face upon spawning + /// + [DataField, AutoNetworkedField] + public Direction ConstructionDirection + { + get + { + return _constructionDirection; + } + set + { + _constructionDirection = value; + ConstructionTransform = new Transform(new(), _constructionDirection.ToAngle()); + } + } + + private Direction _constructionDirection = Direction.South; + + /// + /// Returns a rotated transform based on the specified ConstructionDirection + /// + /// + /// Contains no position data + /// + [ViewVariables(VVAccess.ReadOnly)] + public Transform ConstructionTransform { get; private set; } = default!; } diff --git a/Content.Shared/RCD/Components/RCDDeconstructibleComponent.cs b/Content.Shared/RCD/Components/RCDDeconstructibleComponent.cs new file mode 100644 index 0000000000..0ddc6897f0 --- /dev/null +++ b/Content.Shared/RCD/Components/RCDDeconstructibleComponent.cs @@ -0,0 +1,34 @@ +using Content.Shared.RCD.Systems; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared.RCD.Components; + +[RegisterComponent, NetworkedComponent] +[Access(typeof(RCDSystem))] +public sealed partial class RCDDeconstructableComponent : Component +{ + /// + /// Number of charges consumed when the deconstruction is completed + /// + [DataField, ViewVariables(VVAccess.ReadWrite)] + public int Cost = 1; + + /// + /// The length of the deconstruction + /// + [DataField, ViewVariables(VVAccess.ReadWrite)] + public float Delay = 1f; + + /// + /// The visual effect that plays during deconstruction + /// + [DataField("fx"), ViewVariables(VVAccess.ReadWrite)] + public EntProtoId? Effect = null; + + /// + /// Toggles whether this entity is deconstructable or not + /// + [DataField, ViewVariables(VVAccess.ReadWrite)] + public bool Deconstructable = true; +} diff --git a/Content.Shared/RCD/RCDEvents.cs b/Content.Shared/RCD/RCDEvents.cs new file mode 100644 index 0000000000..a15a010277 --- /dev/null +++ b/Content.Shared/RCD/RCDEvents.cs @@ -0,0 +1,34 @@ +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization; + +namespace Content.Shared.RCD; + +[Serializable, NetSerializable] +public sealed class RCDSystemMessage : BoundUserInterfaceMessage +{ + public ProtoId ProtoId; + + public RCDSystemMessage(ProtoId protoId) + { + ProtoId = protoId; + } +} + +[Serializable, NetSerializable] +public sealed class RCDConstructionGhostRotationEvent : EntityEventArgs +{ + public readonly NetEntity NetEntity; + public readonly Direction Direction; + + public RCDConstructionGhostRotationEvent(NetEntity netEntity, Direction direction) + { + NetEntity = netEntity; + Direction = direction; + } +} + +[Serializable, NetSerializable] +public enum RcdUiKey : byte +{ + Key +} diff --git a/Content.Shared/RCD/RCDPrototype.cs b/Content.Shared/RCD/RCDPrototype.cs new file mode 100644 index 0000000000..1e80abfb72 --- /dev/null +++ b/Content.Shared/RCD/RCDPrototype.cs @@ -0,0 +1,144 @@ +using Content.Shared.Physics; +using Robust.Shared.Physics.Collision.Shapes; +using Robust.Shared.Prototypes; +using Robust.Shared.Utility; + +namespace Content.Shared.RCD; + +/// +/// Contains the parameters for a RCD construction / operation +/// +[Prototype("rcd")] +public sealed class RCDPrototype : IPrototype +{ + [IdDataField] + public string ID { get; private set; } = default!; + + /// + /// The RCD mode associated with the operation + /// + [DataField(required: true), ViewVariables(VVAccess.ReadOnly)] + public RcdMode Mode { get; private set; } = RcdMode.Invalid; + + /// + /// The name associated with the prototype + /// + [DataField("name"), ViewVariables(VVAccess.ReadOnly)] + public string SetName { get; private set; } = "Unknown"; + + /// + /// The name of the radial container that this prototype will be listed under on the RCD menu + /// + [DataField, ViewVariables(VVAccess.ReadOnly)] + public string Category { get; private set; } = "Undefined"; + + /// + /// Texture path for this prototypes menu icon + /// + [DataField, ViewVariables(VVAccess.ReadOnly)] + public SpriteSpecifier? Sprite { get; private set; } = null; + + /// + /// The entity prototype that will be constructed (mode dependent) + /// + [DataField, ViewVariables(VVAccess.ReadOnly)] + public string? Prototype { get; private set; } = string.Empty; + + /// + /// Number of charges consumed when the operation is completed + /// + [DataField, ViewVariables(VVAccess.ReadOnly)] + public int Cost { get; private set; } = 1; + + /// + /// The length of the operation + /// + [DataField, ViewVariables(VVAccess.ReadOnly)] + public float Delay { get; private set; } = 1f; + + /// + /// The visual effect that plays during this operation + /// + [DataField("fx"), ViewVariables(VVAccess.ReadOnly)] + public EntProtoId? Effect { get; private set; } = null; + + /// + /// A list of rules that govern where the entity prototype can be contructed + /// + [DataField("rules"), ViewVariables(VVAccess.ReadOnly)] + public HashSet ConstructionRules { get; private set; } = new(); + + /// + /// The collision mask used for determining whether the entity prototype will fit into a target tile + /// + [DataField, ViewVariables(VVAccess.ReadOnly)] + public CollisionGroup CollisionMask { get; private set; } = CollisionGroup.None; + + /// + /// Specifies a set of custom collision bounds for determining whether the entity prototype will fit into a target tile + /// + /// + /// Should be set assuming that the entity faces south. + /// Make sure that Rotation is set to RcdRotation.User if the entity is to be rotated by the user + /// + [DataField, ViewVariables(VVAccess.ReadOnly)] + public Box2? CollisionBounds + { + get + { + return _collisionBounds; + } + + private set + { + _collisionBounds = value; + + if (_collisionBounds != null) + { + var poly = new PolygonShape(); + poly.SetAsBox(_collisionBounds.Value); + + CollisionPolygon = poly; + } + } + } + + private Box2? _collisionBounds = null; + + /// + /// The polygon shape associated with the prototype CollisionBounds (if set) + /// + [ViewVariables(VVAccess.ReadOnly)] + public PolygonShape? CollisionPolygon { get; private set; } = null; + + /// + /// Governs how the local rotation of the constructed entity will be set + /// + [DataField, ViewVariables(VVAccess.ReadOnly)] + public RcdRotation Rotation { get; private set; } = RcdRotation.User; +} + +public enum RcdMode : byte +{ + Invalid, + Deconstruct, + ConstructTile, + ConstructObject, +} + +// These are to be replaced with more flexible 'RulesRule' at a later time +public enum RcdConstructionRule : byte +{ + MustBuildOnEmptyTile, // Can only be built on empty space (e.g. lattice) + CanBuildOnEmptyTile, // Can be built on empty space or replace an existing tile (e.g. hull plating) + MustBuildOnSubfloor, // Can only be built on exposed subfloor (e.g. catwalks on lattice or hull plating) + IsWindow, // The entity is a window and can be built on grilles + IsCatwalk, // The entity is a catwalk +} + +public enum RcdRotation : byte +{ + Fixed, // The entity has a local rotation of zero + Camera, // The rotation of the entity matches the local player camera + User, // The entity can be rotated by the local player prior to placement +} diff --git a/Content.Shared/RCD/Systems/RCDSystem.cs b/Content.Shared/RCD/Systems/RCDSystem.cs index 6282a117bb..cd1e90dc1f 100644 --- a/Content.Shared/RCD/Systems/RCDSystem.cs +++ b/Content.Shared/RCD/Systems/RCDSystem.cs @@ -1,28 +1,35 @@ using Content.Shared.Administration.Logs; using Content.Shared.Charges.Components; using Content.Shared.Charges.Systems; +using Content.Shared.Construction; using Content.Shared.Database; using Content.Shared.DoAfter; using Content.Shared.Examine; +using Content.Shared.Hands.Components; using Content.Shared.Interaction; -using Content.Shared.Interaction.Events; using Content.Shared.Maps; using Content.Shared.Physics; using Content.Shared.Popups; using Content.Shared.RCD.Components; using Content.Shared.Tag; using Content.Shared.Tiles; -using Robust.Shared.Audio; using Robust.Shared.Audio.Systems; using Robust.Shared.Map; using Robust.Shared.Map.Components; using Robust.Shared.Network; +using Robust.Shared.Physics; +using Robust.Shared.Physics.Collision.Shapes; +using Robust.Shared.Physics.Dynamics; +using Robust.Shared.Prototypes; using Robust.Shared.Serialization; using Robust.Shared.Timing; +using System.Diagnostics.CodeAnalysis; +using System.Linq; namespace Content.Shared.RCD.Systems; -public sealed class RCDSystem : EntitySystem +[Virtual] +public class RCDSystem : EntitySystem { [Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly INetManager _net = default!; @@ -34,312 +41,599 @@ public sealed class RCDSystem : EntitySystem [Dependency] private readonly SharedDoAfterSystem _doAfter = default!; [Dependency] private readonly SharedInteractionSystem _interaction = default!; [Dependency] private readonly SharedPopupSystem _popup = default!; - [Dependency] private readonly TagSystem _tag = default!; [Dependency] private readonly TurfSystem _turf = default!; - [Dependency] private readonly IGameTiming _gameTiming = default!; + [Dependency] private readonly EntityLookupSystem _lookup = default!; + [Dependency] private readonly IPrototypeManager _protoManager = default!; + [Dependency] private readonly SharedMapSystem _mapSystem = default!; + [Dependency] private readonly TagSystem _tags = default!; - private readonly int _rcdModeCount = Enum.GetValues(typeof(RcdMode)).Length; + private readonly int _instantConstructionDelay = 0; + private readonly EntProtoId _instantConstructionFx = "EffectRCDConstruct0"; + private readonly ProtoId _deconstructTileProto = "DeconstructTile"; + private readonly ProtoId _deconstructLatticeProto = "DeconstructLattice"; + + private HashSet _intersectingEntities = new(); public override void Initialize() { base.Initialize(); + SubscribeLocalEvent(OnMapInit); SubscribeLocalEvent(OnExamine); - SubscribeLocalEvent(OnUseInHand); SubscribeLocalEvent(OnAfterInteract); SubscribeLocalEvent(OnDoAfter); SubscribeLocalEvent>(OnDoAfterAttempt); + SubscribeLocalEvent(OnRCDSystemMessage); + SubscribeNetworkEvent(OnRCDconstructionGhostRotationEvent); } - private void OnExamine(EntityUid uid, RCDComponent comp, ExaminedEvent args) + #region Event handling + + private void OnMapInit(EntityUid uid, RCDComponent component, MapInitEvent args) + { + // On init, set the RCD to its first available recipe + if (component.AvailablePrototypes.Any()) + { + component.ProtoId = component.AvailablePrototypes.First(); + UpdateCachedPrototype(uid, component); + Dirty(uid, component); + + return; + } + + // The RCD has no valid recipes somehow? Get rid of it + QueueDel(uid); + } + + private void OnRCDSystemMessage(EntityUid uid, RCDComponent component, RCDSystemMessage args) + { + // Exit if the RCD doesn't actually know the supplied prototype + if (!component.AvailablePrototypes.Contains(args.ProtoId)) + return; + + if (!_protoManager.HasIndex(args.ProtoId)) + return; + + // Set the current RCD prototype to the one supplied + component.ProtoId = args.ProtoId; + UpdateCachedPrototype(uid, component); + Dirty(uid, component); + + if (args.Session.AttachedEntity != null) + { + // Popup message + var msg = (component.CachedPrototype.Prototype != null) ? + Loc.GetString("rcd-component-change-build-mode", ("name", Loc.GetString(component.CachedPrototype.SetName))) : + Loc.GetString("rcd-component-change-mode", ("mode", Loc.GetString(component.CachedPrototype.SetName))); + + _popup.PopupClient(msg, uid, args.Session.AttachedEntity.Value); + } + } + + private void OnExamine(EntityUid uid, RCDComponent component, ExaminedEvent args) { if (!args.IsInDetailsRange) return; - var msg = Loc.GetString("rcd-component-examine-detail", ("mode", comp.Mode)); + // Update cached prototype if required + UpdateCachedPrototype(uid, component); + + var msg = (component.CachedPrototype.Prototype != null) ? + Loc.GetString("rcd-component-examine-build-details", ("name", Loc.GetString(component.CachedPrototype.SetName))) : + Loc.GetString("rcd-component-examine-mode-details", ("mode", Loc.GetString(component.CachedPrototype.SetName))); + args.PushMarkup(msg); } - private void OnUseInHand(EntityUid uid, RCDComponent comp, UseInHandEvent args) - { - if (args.Handled) - return; - - NextMode(uid, comp, args.User); - args.Handled = true; - } - - private void OnAfterInteract(EntityUid uid, RCDComponent comp, AfterInteractEvent args) + private void OnAfterInteract(EntityUid uid, RCDComponent component, AfterInteractEvent args) { if (args.Handled || !args.CanReach) return; var user = args.User; - - TryComp(uid, out var charges); - if (_charges.IsEmpty(uid, charges)) - { - _popup.PopupClient(Loc.GetString("rcd-component-no-ammo-message"), uid, user); - return; - } - var location = args.ClickLocation; - // Initial validity check + + // Initial validity checks if (!location.IsValid(EntityManager)) return; - var gridId = location.GetGridUid(EntityManager); - if (!HasComp(gridId)) + if (!TryGetMapGridData(location, out var mapGridData)) { - location = location.AlignWithClosestGridTile(); - gridId = location.GetGridUid(EntityManager); - // Check if fixing it failed / get final grid ID - if (!HasComp(gridId)) - return; + _popup.PopupClient(Loc.GetString("rcd-component-no-valid-grid"), uid, user); + return; } - var doAfterArgs = new DoAfterArgs(EntityManager, user, comp.Delay, new RCDDoAfterEvent(GetNetCoordinates(location), comp.Mode), uid, target: args.Target, used: uid) + if (!IsRCDOperationStillValid(uid, component, mapGridData.Value, args.Target, args.User)) + return; + + if (!_net.IsServer) + return; + + // Get the starting cost, delay, and effect from the prototype + var cost = component.CachedPrototype.Cost; + var delay = component.CachedPrototype.Delay; + var effectPrototype = component.CachedPrototype.Effect; + + #region: Operation modifiers + + // Deconstruction modifiers + switch (component.CachedPrototype.Mode) + { + case RcdMode.Deconstruct: + + // Deconstructing an object + if (args.Target != null) + { + if (TryComp(args.Target, out var destructible)) + { + cost = destructible.Cost; + delay = destructible.Delay; + effectPrototype = destructible.Effect; + } + } + + // Deconstructing a tile + else + { + var deconstructedTile = _mapSystem.GetTileRef(mapGridData.Value.GridUid, mapGridData.Value.Component, mapGridData.Value.Location); + var protoName = deconstructedTile.IsSpace() ? _deconstructTileProto : _deconstructLatticeProto; + + if (_protoManager.TryIndex(protoName, out var deconProto)) + { + cost = deconProto.Cost; + delay = deconProto.Delay; + effectPrototype = deconProto.Effect; + } + } + + break; + + case RcdMode.ConstructTile: + + // If replacing a tile, make the construction instant + var contructedTile = _mapSystem.GetTileRef(mapGridData.Value.GridUid, mapGridData.Value.Component, mapGridData.Value.Location); + + if (!contructedTile.Tile.IsEmpty) + { + delay = _instantConstructionDelay; + effectPrototype = _instantConstructionFx; + } + + break; + } + + #endregion + + // Try to start the do after + var effect = Spawn(effectPrototype, mapGridData.Value.Location); + var ev = new RCDDoAfterEvent(GetNetCoordinates(mapGridData.Value.Location), component.ProtoId, cost, EntityManager.GetNetEntity(effect)); + + var doAfterArgs = new DoAfterArgs(EntityManager, user, delay, ev, uid, target: args.Target, used: uid) { BreakOnDamage = true, - NeedHand = true, BreakOnHandChange = true, BreakOnMove = true, - AttemptFrequency = AttemptFrequency.EveryTick + AttemptFrequency = AttemptFrequency.EveryTick, + CancelDuplicate = false, + BlockDuplicate = false }; args.Handled = true; - if (_doAfter.TryStartDoAfter(doAfterArgs) && _gameTiming.IsFirstTimePredicted) - Spawn("EffectRCDConstruction", location); + if (!_doAfter.TryStartDoAfter(doAfterArgs)) + QueueDel(effect); } - private void OnDoAfterAttempt(EntityUid uid, RCDComponent comp, DoAfterAttemptEvent args) + private void OnDoAfterAttempt(EntityUid uid, RCDComponent component, DoAfterAttemptEvent args) { - // sus client crash why if (args.Event?.DoAfter?.Args == null) return; + // Exit if the RCD prototype has changed + if (component.ProtoId != args.Event.StartingProtoId) + return; + + // Ensure the RCD operation is still valid var location = GetCoordinates(args.Event.Location); - var gridId = location.GetGridUid(EntityManager); - if (!HasComp(gridId)) - { - location = location.AlignWithClosestGridTile(); - gridId = location.GetGridUid(EntityManager); - // Check if fixing it failed / get final grid ID - if (!HasComp(gridId)) - return; - } + if (!TryGetMapGridData(location, out var mapGridData)) + return; - var mapGrid = Comp(gridId.Value); - var tile = mapGrid.GetTileRef(location); - - if (!IsRCDStillValid(uid, comp, args.Event.User, args.Event.Target, mapGrid, tile, args.Event.StartingMode)) + if (!IsRCDOperationStillValid(uid, component, mapGridData.Value, args.Event.Target, args.Event.User)) args.Cancel(); } - private void OnDoAfter(EntityUid uid, RCDComponent comp, RCDDoAfterEvent args) + private void OnDoAfter(EntityUid uid, RCDComponent component, RCDDoAfterEvent args) { + if (args.Cancelled && _net.IsServer) + QueueDel(EntityManager.GetEntity(args.Effect)); + if (args.Handled || args.Cancelled || !_timing.IsFirstTimePredicted) return; - var user = args.User; + args.Handled = true; + var location = GetCoordinates(args.Location); - var gridId = location.GetGridUid(EntityManager); - if (!HasComp(gridId)) - { - location = location.AlignWithClosestGridTile(); - gridId = location.GetGridUid(EntityManager); - // Check if fixing it failed / get final grid ID - if (!HasComp(gridId)) - return; - } + if (!TryGetMapGridData(location, out var mapGridData)) + return; - var mapGrid = Comp(gridId.Value); - var tile = mapGrid.GetTileRef(location); - var snapPos = mapGrid.TileIndicesFor(location); + // Ensure the RCD operation is still valid + if (!IsRCDOperationStillValid(uid, component, mapGridData.Value, args.Target, args.User)) + return; - // I love that this uses entirely separate code to construction and tile placement!!! + // Finalize the operation + FinalizeRCDOperation(uid, component, mapGridData.Value, args.Target, args.User); - switch (comp.Mode) - { - //Floor mode just needs the tile to be a space tile (subFloor) - case RcdMode.Floors: - if (!_floors.CanPlaceTile(gridId.Value, mapGrid, out var reason)) - { - _popup.PopupClient(reason, user, user); - return; - } - - mapGrid.SetTile(snapPos, new Tile(_tileDefMan[comp.Floor].TileId)); - _adminLogger.Add(LogType.RCD, LogImpact.High, $"{ToPrettyString(args.User):user} used RCD to set grid: {tile.GridUid} {snapPos} to {comp.Floor}"); - break; - //We don't want to place a space tile on something that's already a space tile. Let's do the inverse of the last check. - case RcdMode.Deconstruct: - if (!IsTileBlocked(tile)) // Delete the turf - { - mapGrid.SetTile(snapPos, Tile.Empty); - _adminLogger.Add(LogType.RCD, LogImpact.High, $"{ToPrettyString(args.User):user} used RCD to set grid: {tile.GridUid} tile: {snapPos} to space"); - } - else // Delete the targeted thing - { - var target = args.Target!.Value; - _adminLogger.Add(LogType.RCD, LogImpact.High, $"{ToPrettyString(args.User):user} used RCD to delete {ToPrettyString(target):target}"); - QueueDel(target); - } - break; - //Walls are a special behaviour, and require us to build a new object with a transform rather than setting a grid tile, - // thus we early return to avoid the tile set code. - case RcdMode.Walls: - // only spawn on the server - if (_net.IsServer) - { - var ent = Spawn("WallSolid", mapGrid.GridTileToLocal(snapPos)); - Transform(ent).LocalRotation = Angle.Zero; // Walls always need to point south. - _adminLogger.Add(LogType.RCD, LogImpact.High, $"{ToPrettyString(args.User):user} used RCD to spawn {ToPrettyString(ent)} at {snapPos} on grid {tile.GridUid}"); - } - break; - case RcdMode.Airlock: - // only spawn on the server - if (_net.IsServer) - { - var airlock = Spawn("Airlock", mapGrid.GridTileToLocal(snapPos)); - Transform(airlock).LocalRotation = Transform(uid).LocalRotation; //Now apply icon smoothing. - _adminLogger.Add(LogType.RCD, LogImpact.High, $"{ToPrettyString(args.User):user} used RCD to spawn {ToPrettyString(airlock)} at {snapPos} on grid {tile.GridUid}"); - } - break; - default: - args.Handled = true; - return; //I don't know why this would happen, but sure I guess. Get out of here invalid state! - } - - _audio.PlayPredicted(comp.SuccessSound, uid, user); - _charges.UseCharge(uid); - args.Handled = true; + // Play audio and consume charges + _audio.PlayPredicted(component.SuccessSound, uid, args.User); + _charges.UseCharges(uid, args.Cost); } - private bool IsRCDStillValid(EntityUid uid, RCDComponent comp, EntityUid user, EntityUid? target, MapGridComponent mapGrid, TileRef tile, RcdMode startingMode) + private void OnRCDconstructionGhostRotationEvent(RCDConstructionGhostRotationEvent ev, EntitySessionEventArgs session) { - //Less expensive checks first. Failing those ones, we need to check that the tile isn't obstructed. - if (comp.Mode != startingMode) - return false; + var uid = GetEntity(ev.NetEntity); - var unobstructed = target == null - ? _interaction.InRangeUnobstructed(user, mapGrid.GridTileToWorld(tile.GridIndices), popup: true) - : _interaction.InRangeUnobstructed(user, target.Value, popup: true); + // Determine if player that send the message is carrying the specified RCD in their active hand + if (session.SenderSession.AttachedEntity == null) + return; + + if (!TryComp(session.SenderSession.AttachedEntity, out var hands) || + uid != hands.ActiveHand?.HeldEntity) + return; + + if (!TryComp(uid, out var rcd)) + return; + + // Update the construction direction + rcd.ConstructionDirection = ev.Direction; + Dirty(uid, rcd); + } + + #endregion + + #region Entity construction/deconstruction rule checks + + public bool IsRCDOperationStillValid(EntityUid uid, RCDComponent component, MapGridData mapGridData, EntityUid? target, EntityUid user, bool popMsgs = true) + { + // Update cached prototype if required + UpdateCachedPrototype(uid, component); + + // Check that the RCD has enough ammo to get the job done + TryComp(uid, out var charges); + + // Both of these were messages were suppose to be predicted, but HasInsufficientCharges wasn't being checked on the client for some reason? + if (_charges.IsEmpty(uid, charges)) + { + if (popMsgs) + _popup.PopupClient(Loc.GetString("rcd-component-no-ammo-message"), uid, user); + + return false; + } + + if (_charges.HasInsufficientCharges(uid, component.CachedPrototype.Cost, charges)) + { + if (popMsgs) + _popup.PopupClient(Loc.GetString("rcd-component-insufficient-ammo-message"), uid, user); + + return false; + } + + // Exit if the target / target location is obstructed + var unobstructed = (target == null) + ? _interaction.InRangeUnobstructed(user, _mapSystem.GridTileToWorld(mapGridData.GridUid, mapGridData.Component, mapGridData.Position), popup: popMsgs) + : _interaction.InRangeUnobstructed(user, target.Value, popup: popMsgs); if (!unobstructed) return false; - switch (comp.Mode) + // Return whether the operation location is valid + switch (component.CachedPrototype.Mode) { - //Floor mode just needs the tile to be a space tile (subFloor) - case RcdMode.Floors: - if (!tile.Tile.IsEmpty) + case RcdMode.ConstructTile: return IsConstructionLocationValid(uid, component, mapGridData, user, popMsgs); + case RcdMode.ConstructObject: return IsConstructionLocationValid(uid, component, mapGridData, user, popMsgs); + case RcdMode.Deconstruct: return IsDeconstructionStillValid(uid, component, mapGridData, target, user, popMsgs); + } + + return false; + } + + private bool IsConstructionLocationValid(EntityUid uid, RCDComponent component, MapGridData mapGridData, EntityUid user, bool popMsgs = true) + { + // Check rule: Must build on empty tile + if (component.CachedPrototype.ConstructionRules.Contains(RcdConstructionRule.MustBuildOnEmptyTile) && !mapGridData.Tile.Tile.IsEmpty) + { + if (popMsgs) + _popup.PopupClient(Loc.GetString("rcd-component-must-build-on-empty-tile-message"), uid, user); + + return false; + } + + // Check rule: Must build on non-empty tile + if (!component.CachedPrototype.ConstructionRules.Contains(RcdConstructionRule.CanBuildOnEmptyTile) && mapGridData.Tile.Tile.IsEmpty) + { + if (popMsgs) + _popup.PopupClient(Loc.GetString("rcd-component-cannot-build-on-empty-tile-message"), uid, user); + + return false; + } + + // Check rule: Must place on subfloor + if (component.CachedPrototype.ConstructionRules.Contains(RcdConstructionRule.MustBuildOnSubfloor) && !mapGridData.Tile.Tile.GetContentTileDefinition().IsSubFloor) + { + if (popMsgs) + _popup.PopupClient(Loc.GetString("rcd-component-must-build-on-subfloor-message"), uid, user); + + return false; + } + + // Tile specific rules + if (component.CachedPrototype.Mode == RcdMode.ConstructTile) + { + // Check rule: Tile placement is valid + if (!_floors.CanPlaceTile(mapGridData.GridUid, mapGridData.Component, out var reason)) + { + if (popMsgs) + _popup.PopupClient(reason, uid, user); + + return false; + } + + // Check rule: Tiles can't be identical + if (mapGridData.Tile.Tile.GetContentTileDefinition().ID == component.CachedPrototype.Prototype) + { + if (popMsgs) + _popup.PopupClient(Loc.GetString("rcd-component-cannot-build-identical-tile"), uid, user); + + return false; + } + + // Ensure that all construction rules shared between tiles and object are checked before exiting here + return true; + } + + // Entity specific rules + + // Check rule: The tile is unoccupied + var isWindow = component.CachedPrototype.ConstructionRules.Contains(RcdConstructionRule.IsWindow); + var isCatwalk = component.CachedPrototype.ConstructionRules.Contains(RcdConstructionRule.IsCatwalk); + + _intersectingEntities.Clear(); + _lookup.GetLocalEntitiesIntersecting(mapGridData.GridUid, mapGridData.Position, _intersectingEntities, -0.05f, LookupFlags.Uncontained); + + foreach (var ent in _intersectingEntities) + { + if (isWindow && HasComp(ent)) + continue; + + if (isCatwalk && _tags.HasTag(ent, "Catwalk")) + { + if (popMsgs) + _popup.PopupClient(Loc.GetString("rcd-component-cannot-build-on-occupied-tile-message"), uid, user); + + return false; + } + + if (component.CachedPrototype.CollisionMask != CollisionGroup.None && TryComp(ent, out var fixtures)) + { + foreach (var fixture in fixtures.Fixtures.Values) { - _popup.PopupClient(Loc.GetString("rcd-component-cannot-build-floor-tile-not-empty-message"), uid, user); + // Continue if no collision is possible + if (fixture.CollisionLayer <= 0 || (fixture.CollisionLayer & (int) component.CachedPrototype.CollisionMask) == 0) + continue; + + // Continue if our custom collision bounds are not intersected + if (component.CachedPrototype.CollisionPolygon != null && + !DoesCustomBoundsIntersectWithFixture(component.CachedPrototype.CollisionPolygon, component.ConstructionTransform, ent, fixture)) + continue; + + // Collision was detected + if (popMsgs) + _popup.PopupClient(Loc.GetString("rcd-component-cannot-build-on-occupied-tile-message"), uid, user); + return false; } + } + } + + return true; + } + + private bool IsDeconstructionStillValid(EntityUid uid, RCDComponent component, MapGridData mapGridData, EntityUid? target, EntityUid user, bool popMsgs = true) + { + // Attempt to deconstruct a floor tile + if (target == null) + { + // The tile is empty + if (mapGridData.Tile.Tile.IsEmpty) + { + if (popMsgs) + _popup.PopupClient(Loc.GetString("rcd-component-nothing-to-deconstruct-message"), uid, user); + + return false; + } + + // The tile has a structure sitting on it + if (_turf.IsTileBlocked(mapGridData.Tile, CollisionGroup.MobMask)) + { + if (popMsgs) + _popup.PopupClient(Loc.GetString("rcd-component-tile-obstructed-message"), uid, user); + + return false; + } + + // The tile cannot be destroyed + var tileDef = (ContentTileDefinition) _tileDefMan[mapGridData.Tile.Tile.TypeId]; + + if (tileDef.Indestructible) + { + if (popMsgs) + _popup.PopupClient(Loc.GetString("rcd-component-tile-indestructible-message"), uid, user); + + return false; + } + } + + // Attempt to deconstruct an object + else + { + // The object is not in the whitelist + if (!TryComp(target, out var deconstructible) || !deconstructible.Deconstructable) + { + if (popMsgs) + _popup.PopupClient(Loc.GetString("rcd-component-deconstruct-target-not-on-whitelist-message"), uid, user); + + return false; + } + } + + return true; + } + + #endregion + + #region Entity construction/deconstruction + + private void FinalizeRCDOperation(EntityUid uid, RCDComponent component, MapGridData mapGridData, EntityUid? target, EntityUid user) + { + if (!_net.IsServer) + return; + + if (component.CachedPrototype.Prototype == null) + return; + + switch (component.CachedPrototype.Mode) + { + case RcdMode.ConstructTile: + _mapSystem.SetTile(mapGridData.GridUid, mapGridData.Component, mapGridData.Position, new Tile(_tileDefMan[component.CachedPrototype.Prototype].TileId)); + _adminLogger.Add(LogType.RCD, LogImpact.High, $"{ToPrettyString(user):user} used RCD to set grid: {mapGridData.GridUid} {mapGridData.Position} to {component.CachedPrototype.Prototype}"); + break; + + case RcdMode.ConstructObject: + var ent = Spawn(component.CachedPrototype.Prototype, _mapSystem.GridTileToLocal(mapGridData.GridUid, mapGridData.Component, mapGridData.Position)); + + switch (component.CachedPrototype.Rotation) + { + case RcdRotation.Fixed: + Transform(ent).LocalRotation = Angle.Zero; + break; + case RcdRotation.Camera: + Transform(ent).LocalRotation = Transform(uid).LocalRotation; + break; + case RcdRotation.User: + Transform(ent).LocalRotation = component.ConstructionDirection.ToAngle(); + break; + } + + _adminLogger.Add(LogType.RCD, LogImpact.High, $"{ToPrettyString(user):user} used RCD to spawn {ToPrettyString(ent)} at {mapGridData.Position} on grid {mapGridData.GridUid}"); + break; - return true; - //We don't want to place a space tile on something that's already a space tile. Let's do the inverse of the last check. case RcdMode.Deconstruct: - if (tile.Tile.IsEmpty) - return false; - //They tried to decon a turf but... if (target == null) { - // the turf is blocked - if (IsTileBlocked(tile)) - { - _popup.PopupClient(Loc.GetString("rcd-component-tile-obstructed-message"), uid, user); - return false; - } - // the turf can't be destroyed (planet probably) - var tileDef = (ContentTileDefinition) _tileDefMan[tile.Tile.TypeId]; - if (tileDef.Indestructible) - { - _popup.PopupClient(Loc.GetString("rcd-component-tile-indestructible-message"), uid, user); - return false; - } + // Deconstruct tile (either converts the tile to lattice, or removes lattice) + var tile = (mapGridData.Tile.Tile.GetContentTileDefinition().ID != "Lattice") ? new Tile(_tileDefMan["Lattice"].TileId) : Tile.Empty; + _mapSystem.SetTile(mapGridData.GridUid, mapGridData.Component, mapGridData.Position, tile); + _adminLogger.Add(LogType.RCD, LogImpact.High, $"{ToPrettyString(user):user} used RCD to set grid: {mapGridData.GridUid} tile: {mapGridData.Position} open to space"); } - //They tried to decon a non-turf but it's not in the whitelist - else if (!_tag.HasTag(target.Value, "RCDDeconstructWhitelist")) + else { - _popup.PopupClient(Loc.GetString("rcd-component-deconstruct-target-not-on-whitelist-message"), uid, user); - return false; + // Deconstruct object + _adminLogger.Add(LogType.RCD, LogImpact.High, $"{ToPrettyString(user):user} used RCD to delete {ToPrettyString(target):target}"); + QueueDel(target); } - return true; - //Walls are a special behaviour, and require us to build a new object with a transform rather than setting a grid tile, thus we early return to avoid the tile set code. - case RcdMode.Walls: - if (tile.Tile.IsEmpty) - { - _popup.PopupClient(Loc.GetString("rcd-component-cannot-build-wall-tile-not-empty-message"), uid, user); - return false; - } - - if (IsTileBlocked(tile)) - { - _popup.PopupClient(Loc.GetString("rcd-component-tile-obstructed-message"), uid, user); - return false; - } - return true; - case RcdMode.Airlock: - if (tile.Tile.IsEmpty) - { - _popup.PopupClient(Loc.GetString("rcd-component-cannot-build-airlock-tile-not-empty-message"), uid, user); - return false; - } - if (IsTileBlocked(tile)) - { - _popup.PopupClient(Loc.GetString("rcd-component-tile-obstructed-message"), uid, user); - return false; - } - return true; - default: - return false; //I don't know why this would happen, but sure I guess. Get out of here invalid state! + break; } } - private void NextMode(EntityUid uid, RCDComponent comp, EntityUid user) + #endregion + + #region Utility functions + + public bool TryGetMapGridData(EntityCoordinates location, [NotNullWhen(true)] out MapGridData? mapGridData) { - _audio.PlayPredicted(comp.SwapModeSound, uid, user); + mapGridData = null; + var gridUid = location.GetGridUid(EntityManager); - var mode = (int) comp.Mode; - mode = ++mode % _rcdModeCount; - comp.Mode = (RcdMode) mode; - Dirty(uid, comp); + if (!TryComp(gridUid, out var mapGrid)) + { + location = location.AlignWithClosestGridTile(1.75f, EntityManager); + gridUid = location.GetGridUid(EntityManager); - var msg = Loc.GetString("rcd-component-change-mode", ("mode", comp.Mode.ToString())); - _popup.PopupClient(msg, uid, user); + // Check if we got a grid ID the second time round + if (!TryComp(gridUid, out mapGrid)) + return false; + } + + gridUid = mapGrid.Owner; + + var tile = _mapSystem.GetTileRef(gridUid.Value, mapGrid, location); + var position = _mapSystem.TileIndicesFor(gridUid.Value, mapGrid, location); + mapGridData = new MapGridData(gridUid.Value, mapGrid, location, tile, position); + + return true; } - private bool IsTileBlocked(TileRef tile) + private bool DoesCustomBoundsIntersectWithFixture(PolygonShape boundingPolygon, Transform boundingTransform, EntityUid fixtureOwner, Fixture fixture) { - return _turf.IsTileBlocked(tile, CollisionGroup.MobMask); + var entXformComp = Transform(fixtureOwner); + var entXform = new Transform(new(), entXformComp.LocalRotation); + + return boundingPolygon.ComputeAABB(boundingTransform, 0).Intersects(fixture.Shape.ComputeAABB(entXform, 0)); + } + + public void UpdateCachedPrototype(EntityUid uid, RCDComponent component) + { + if (component.ProtoId.Id != component.CachedPrototype?.Prototype) + component.CachedPrototype = _protoManager.Index(component.ProtoId); + } + + #endregion +} + +public struct MapGridData +{ + public EntityUid GridUid; + public MapGridComponent Component; + public EntityCoordinates Location; + public TileRef Tile; + public Vector2i Position; + + public MapGridData(EntityUid gridUid, MapGridComponent component, EntityCoordinates location, TileRef tile, Vector2i position) + { + GridUid = gridUid; + Component = component; + Location = location; + Tile = tile; + Position = position; } } [Serializable, NetSerializable] public sealed partial class RCDDoAfterEvent : DoAfterEvent { - [DataField("location", required: true)] - public NetCoordinates Location = default!; + [DataField(required: true)] + public NetCoordinates Location { get; private set; } = default!; - [DataField("startingMode", required: true)] - public RcdMode StartingMode = default!; + [DataField] + public ProtoId StartingProtoId { get; private set; } = default!; - private RCDDoAfterEvent() - { - } + [DataField] + public int Cost { get; private set; } = 1; - public RCDDoAfterEvent(NetCoordinates location, RcdMode startingMode) + [DataField("fx")] + public NetEntity? Effect { get; private set; } = null; + + private RCDDoAfterEvent() { } + + public RCDDoAfterEvent(NetCoordinates location, ProtoId startingProtoId, int cost, NetEntity? effect = null) { Location = location; - StartingMode = startingMode; + StartingProtoId = startingProtoId; + Cost = cost; + Effect = effect; } public override DoAfterEvent Clone() => this; diff --git a/Content.Shared/Random/RulesPrototype.cs b/Content.Shared/Random/RulesPrototype.cs index 6bbc3a68f8..20961af8e7 100644 --- a/Content.Shared/Random/RulesPrototype.cs +++ b/Content.Shared/Random/RulesPrototype.cs @@ -116,8 +116,8 @@ public sealed partial class NearbyAccessRule : RulesRule [DataField("count")] public int Count = 1; - [DataField("access", required: true, customTypeSerializer: typeof(PrototypeIdListSerializer))] - public List Access = new(); + [DataField("access", required: true)] + public List> Access = new(); [DataField("range")] public float Range = 10f; diff --git a/Content.Shared/Roles/JobPrototype.cs b/Content.Shared/Roles/JobPrototype.cs index 0064fcdf17..34a8ce64bf 100644 --- a/Content.Shared/Roles/JobPrototype.cs +++ b/Content.Shared/Roles/JobPrototype.cs @@ -105,17 +105,17 @@ namespace Content.Shared.Roles [DataField("special", serverOnly: true)] public JobSpecial[] Special { get; private set; } = Array.Empty(); - [DataField("access", customTypeSerializer: typeof(PrototypeIdListSerializer))] - public IReadOnlyCollection Access { get; private set; } = Array.Empty(); + [DataField("access")] + public IReadOnlyCollection> Access { get; private set; } = Array.Empty>(); - [DataField("accessGroups", customTypeSerializer: typeof(PrototypeIdListSerializer))] - public IReadOnlyCollection AccessGroups { get; private set; } = Array.Empty(); + [DataField("accessGroups")] + public IReadOnlyCollection> AccessGroups { get; private set; } = Array.Empty>(); - [DataField("extendedAccess", customTypeSerializer: typeof(PrototypeIdListSerializer))] - public IReadOnlyCollection ExtendedAccess { get; private set; } = Array.Empty(); + [DataField("extendedAccess")] + public IReadOnlyCollection> ExtendedAccess { get; private set; } = Array.Empty>(); - [DataField("extendedAccessGroups", customTypeSerializer: typeof(PrototypeIdListSerializer))] - public IReadOnlyCollection ExtendedAccessGroups { get; private set; } = Array.Empty(); + [DataField("extendedAccessGroups")] + public IReadOnlyCollection> ExtendedAccessGroups { get; private set; } = Array.Empty>(); } /// diff --git a/Content.Shared/Salvage/Expeditions/SalvageExpeditions.cs b/Content.Shared/Salvage/Expeditions/SalvageExpeditions.cs index fe4d59b81a..4844a1f3fd 100644 --- a/Content.Shared/Salvage/Expeditions/SalvageExpeditions.cs +++ b/Content.Shared/Salvage/Expeditions/SalvageExpeditions.cs @@ -1,4 +1,5 @@ using Content.Shared.Salvage.Expeditions.Modifiers; +using Robust.Shared.Audio; using Robust.Shared.GameStates; using Robust.Shared.Serialization; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; @@ -30,7 +31,11 @@ public sealed class SalvageExpeditionConsoleState : BoundUserInterfaceState [RegisterComponent, NetworkedComponent] public sealed partial class SalvageExpeditionConsoleComponent : Component { - + /// + /// The sound made when spawning a coordinates disk + /// + [DataField] + public SoundSpecifier PrintSound = new SoundPathSpecifier("/Audio/Machines/terminal_insert_disc.ogg"); } [Serializable, NetSerializable] diff --git a/Content.Shared/Shuttles/Components/FTLDestinationComponent.cs b/Content.Shared/Shuttles/Components/FTLDestinationComponent.cs index 58cff96c2b..d4bc536a29 100644 --- a/Content.Shared/Shuttles/Components/FTLDestinationComponent.cs +++ b/Content.Shared/Shuttles/Components/FTLDestinationComponent.cs @@ -23,4 +23,10 @@ public sealed partial class FTLDestinationComponent : Component /// [DataField, AutoNetworkedField] public bool BeaconsOnly; + + /// + /// Shuttles must use a corresponding CD to travel to this location. + /// + [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField] + public bool RequireCoordinateDisk = false; } diff --git a/Content.Shared/Shuttles/Components/SharedShuttleConsoleComponent.cs b/Content.Shared/Shuttles/Components/SharedShuttleConsoleComponent.cs index 436c830d20..2ee03210ba 100644 --- a/Content.Shared/Shuttles/Components/SharedShuttleConsoleComponent.cs +++ b/Content.Shared/Shuttles/Components/SharedShuttleConsoleComponent.cs @@ -9,7 +9,7 @@ namespace Content.Shared.Shuttles.Components [NetworkedComponent] public abstract partial class SharedShuttleConsoleComponent : Component { - + public static string DiskSlotName = "disk_slot"; } [Serializable, NetSerializable] diff --git a/Content.Shared/Shuttles/Components/ShuttleDestinationCoordinatesComponent.cs b/Content.Shared/Shuttles/Components/ShuttleDestinationCoordinatesComponent.cs new file mode 100644 index 0000000000..009dee49d1 --- /dev/null +++ b/Content.Shared/Shuttles/Components/ShuttleDestinationCoordinatesComponent.cs @@ -0,0 +1,15 @@ +namespace Content.Shared.Shuttles.Components; +using Robust.Shared.GameStates; + +/// +/// Enables a shuttle to travel to a destination with an item inserted into its console +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class ShuttleDestinationCoordinatesComponent : Component +{ + /// + /// Uid for entity containing the FTLDestination component + /// + [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField] + public EntityUid? Destination; +} diff --git a/Content.Shared/Shuttles/Systems/SharedShuttleSystem.cs b/Content.Shared/Shuttles/Systems/SharedShuttleSystem.cs index ca25a49b23..d859d9f485 100644 --- a/Content.Shared/Shuttles/Systems/SharedShuttleSystem.cs +++ b/Content.Shared/Shuttles/Systems/SharedShuttleSystem.cs @@ -1,3 +1,4 @@ +using Content.Shared.Containers.ItemSlots; using Content.Shared.Shuttles.BUIStates; using Content.Shared.Shuttles.Components; using Content.Shared.Shuttles.UI.MapObjects; @@ -10,7 +11,8 @@ namespace Content.Shared.Shuttles.Systems; public abstract partial class SharedShuttleSystem : EntitySystem { - [Dependency] private readonly IMapManager _mapManager = default!; + [Dependency] private readonly IMapManager _mapManager = default!; + [Dependency] private readonly ItemSlotsSystem _itemSlots = default!; [Dependency] protected readonly SharedMapSystem Maps = default!; [Dependency] protected readonly SharedTransformSystem XformSystem = default!; @@ -34,7 +36,7 @@ public abstract partial class SharedShuttleSystem : EntitySystem /// /// Returns whether an entity can FTL to the specified map. /// - public bool CanFTLTo(EntityUid shuttleUid, MapId targetMap) + public bool CanFTLTo(EntityUid shuttleUid, MapId targetMap, EntityUid consoleUid) { var mapUid = _mapManager.GetMapEntityId(targetMap); var shuttleMap = _xformQuery.GetComponent(shuttleUid).MapID; @@ -42,10 +44,40 @@ public abstract partial class SharedShuttleSystem : EntitySystem if (shuttleMap == targetMap) return true; - if (!TryComp(mapUid, out var destination) || - !destination.Enabled) - { + if (!TryComp(mapUid, out var destination) || !destination.Enabled) return false; + + if (destination.RequireCoordinateDisk) + { + if (!TryComp(consoleUid, out var slot)) + { + return false; + } + + if (!_itemSlots.TryGetSlot(consoleUid, SharedShuttleConsoleComponent.DiskSlotName, out var itemSlot, component: slot) || !itemSlot.HasItem) + { + return false; + } + + if (itemSlot.Item is { Valid: true } disk) + { + ShuttleDestinationCoordinatesComponent? diskCoordinates = null; + if (!Resolve(disk, ref diskCoordinates)) + { + return false; + } + + var diskCoords = diskCoordinates.Destination; + + if (diskCoords == null || !TryComp(diskCoords.Value, out var diskDestination) || diskDestination != destination) + { + return false; + } + } + else + { + return false; + } } if (HasComp(mapUid)) diff --git a/Content.Shared/Sound/Components/EmitSoundOnInteractUsingComponent.cs b/Content.Shared/Sound/Components/EmitSoundOnInteractUsingComponent.cs new file mode 100644 index 0000000000..49118d9799 --- /dev/null +++ b/Content.Shared/Sound/Components/EmitSoundOnInteractUsingComponent.cs @@ -0,0 +1,15 @@ +using Content.Shared.Whitelist; +using Robust.Shared.Prototypes; +using Robust.Shared.GameStates; + +namespace Content.Shared.Sound.Components; + +/// +/// Whenever this item is used upon by an entity, with a tag or component within a whitelist, in the hand of a user, play a sound +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class EmitSoundOnInteractUsingComponent : BaseEmitSoundComponent +{ + [DataField(required: true)] + public EntityWhitelist Whitelist = new(); +} diff --git a/Content.Shared/Sound/SharedEmitSoundSystem.cs b/Content.Shared/Sound/SharedEmitSoundSystem.cs index cd7828fc6b..329626964e 100644 --- a/Content.Shared/Sound/SharedEmitSoundSystem.cs +++ b/Content.Shared/Sound/SharedEmitSoundSystem.cs @@ -41,6 +41,7 @@ public abstract class SharedEmitSoundSystem : EntitySystem SubscribeLocalEvent(OnEmitSoundOnActivateInWorld); SubscribeLocalEvent(OnEmitSoundOnPickup); SubscribeLocalEvent(OnEmitSoundOnDrop); + SubscribeLocalEvent(OnEmitSoundOnInteractUsing); SubscribeLocalEvent(OnEmitSoundOnCollide); } @@ -102,6 +103,13 @@ public abstract class SharedEmitSoundSystem : EntitySystem TryEmitSound(uid, component, args.User); } + private void OnEmitSoundOnInteractUsing(Entity ent, ref InteractUsingEvent args) + { + if (ent.Comp.Whitelist.IsValid(args.Used, EntityManager)) + { + TryEmitSound(ent, ent.Comp, args.User); + } + } protected void TryEmitSound(EntityUid uid, BaseEmitSoundComponent component, EntityUid? user=null, bool predict=true) { if (component.Sound == null) diff --git a/Content.Shared/SprayPainter/SharedSprayPainterSystem.cs b/Content.Shared/SprayPainter/SharedSprayPainterSystem.cs index feb1cebb8e..b238c6fc72 100644 --- a/Content.Shared/SprayPainter/SharedSprayPainterSystem.cs +++ b/Content.Shared/SprayPainter/SharedSprayPainterSystem.cs @@ -4,7 +4,6 @@ using Content.Shared.DoAfter; using Content.Shared.Doors.Components; using Content.Shared.Interaction; using Content.Shared.Popups; -using Content.Shared.Paint; using Content.Shared.SprayPainter.Components; using Content.Shared.SprayPainter.Prototypes; using Robust.Shared.Audio.Systems; @@ -130,8 +129,6 @@ public abstract class SharedSprayPainterSystem : EntitySystem return; } - RemComp(ent); - var doAfterEventArgs = new DoAfterArgs(EntityManager, args.User, painter.AirlockSprayTime, new SprayPainterDoorDoAfterEvent(sprite, style.Department), args.Used, target: ent, used: args.Used) { BreakOnMove = true, diff --git a/Content.Shared/Storage/Components/SecretStashComponent.cs b/Content.Shared/Storage/Components/SecretStashComponent.cs new file mode 100644 index 0000000000..8595f79ca5 --- /dev/null +++ b/Content.Shared/Storage/Components/SecretStashComponent.cs @@ -0,0 +1,90 @@ +using Content.Shared.Storage.EntitySystems; +using Content.Shared.Containers.ItemSlots; +using Content.Shared.Item; +using Robust.Shared.Containers; +using Robust.Shared.Prototypes; +using Content.Shared.Tools; +using Robust.Shared.GameStates; +using Content.Shared.DoAfter; +using Robust.Shared.Serialization; + +namespace Content.Shared.Storage.Components +{ + /// + /// Logic for a secret slot stash, like plant pot or toilet cistern. + /// Unlike it doesn't have interaction logic or verbs. + /// Other classes like should implement it. + /// + [RegisterComponent, NetworkedComponent, AutoGenerateComponentState] + [Access(typeof(SecretStashSystem))] + public sealed partial class SecretStashComponent : Component + { + /// + /// Max item size that can be fitted into secret stash. + /// + [DataField("maxItemSize")] + public ProtoId MaxItemSize = "Small"; + + /// + /// If stash has way to open then this will switch between open and closed. + /// + [DataField, AutoNetworkedField] + public bool ToggleOpen; + + /// + /// Prying the door. + /// + [DataField] + public float PryDoorTime = 1f; + + [DataField] + public ProtoId PryingQuality = "Prying"; + + /// + /// Is stash openable?. + /// + [DataField, AutoNetworkedField] + public bool OpenableStash = false; + + /// + /// IC secret stash name. For example "the toilet cistern". + /// If empty string, will replace it with entity name in init. + /// + [DataField] + public string SecretPartName { get; set; } = ""; + + [DataField, AutoNetworkedField] + public string ExamineStash = "comp-secret-stash-on-examine-found-hidden-item"; + + /// + /// Container used to keep secret stash item. + /// + [ViewVariables] + public ContainerSlot ItemContainer = default!; + + } + + /// + /// Simple pry event for prying open a stash door. + /// + [Serializable, NetSerializable] + public sealed partial class StashPryDoAfterEvent : SimpleDoAfterEvent + { + } + + /// + /// Visualizers for handling stash open closed state if stash has door. + /// + [Serializable, NetSerializable] + public enum StashVisuals : byte + { + DoorVisualState, + } + + [Serializable, NetSerializable] + public enum DoorVisualState : byte + { + DoorOpen, + DoorClosed + } +} diff --git a/Content.Shared/Storage/EntitySystems/DumpableSystem.cs b/Content.Shared/Storage/EntitySystems/DumpableSystem.cs index 8a8b636a67..91acde47e1 100644 --- a/Content.Shared/Storage/EntitySystems/DumpableSystem.cs +++ b/Content.Shared/Storage/EntitySystems/DumpableSystem.cs @@ -159,11 +159,11 @@ public sealed class DumpableSystem : EntitySystem { dumped = true; - var targetPos = _transformSystem.GetWorldPosition(args.Args.Target.Value); + var (targetPos, targetRot) = _transformSystem.GetWorldPositionRotation(args.Args.Target.Value); foreach (var entity in dumpQueue) { - _transformSystem.SetWorldPosition(entity, targetPos + _random.NextVector2Box() / 4); + _transformSystem.SetWorldPositionRotation(entity, targetPos + _random.NextVector2Box() / 4, targetRot); } } else diff --git a/Content.Server/Storage/EntitySystems/SecretStashSystem.cs b/Content.Shared/Storage/EntitySystems/SecretStashSystem.cs similarity index 55% rename from Content.Server/Storage/EntitySystems/SecretStashSystem.cs rename to Content.Shared/Storage/EntitySystems/SecretStashSystem.cs index 49be0a2f88..9aee1b982e 100644 --- a/Content.Server/Storage/EntitySystems/SecretStashSystem.cs +++ b/Content.Shared/Storage/EntitySystems/SecretStashSystem.cs @@ -1,25 +1,37 @@ -using Content.Server.Popups; -using Content.Server.Storage.Components; +using Content.Shared.Popups; +using Content.Shared.Storage.Components; using Content.Shared.Destructible; using Content.Shared.Hands.Components; using Content.Shared.Hands.EntitySystems; using Content.Shared.Item; using Robust.Shared.Containers; +using Content.Shared.Interaction; +using Content.Shared.Tools.Systems; +using Content.Shared.Examine; -namespace Content.Server.Storage.EntitySystems +namespace Content.Shared.Storage.EntitySystems { + /// + /// Secret Stash allows an item to be hidden within. + /// public sealed class SecretStashSystem : EntitySystem { - [Dependency] private readonly PopupSystem _popupSystem = default!; + [Dependency] private readonly SharedPopupSystem _popupSystem = default!; [Dependency] private readonly SharedHandsSystem _handsSystem = default!; [Dependency] private readonly SharedContainerSystem _containerSystem = default!; [Dependency] private readonly SharedItemSystem _item = default!; + [Dependency] private readonly SharedToolSystem _tool = default!; + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnInit); SubscribeLocalEvent(OnDestroyed); + SubscribeLocalEvent(OnSecretStashPried); + SubscribeLocalEvent(OnInteractUsing); + SubscribeLocalEvent(OnInteractHand); + SubscribeLocalEvent(OnExamine); } private void OnInit(EntityUid uid, SecretStashComponent component, ComponentInit args) @@ -42,6 +54,73 @@ namespace Content.Server.Storage.EntitySystems return component.ItemContainer.ContainedEntity != null; } + private void OnInteractUsing(EntityUid uid, SecretStashComponent component, InteractUsingEvent args) + { + if (args.Handled) + return; + + if (!component.OpenableStash) + return; + + // is player trying place or lift off cistern lid? + if (_tool.UseTool(args.Used, args.User, uid, component.PryDoorTime, component.PryingQuality, new StashPryDoAfterEvent())) + args.Handled = true; + // maybe player is trying to hide something inside cistern? + else if (component.ToggleOpen) + { + TryHideItem(uid, args.User, args.Used); + args.Handled = true; + } + } + + private void OnInteractHand(EntityUid uid, SecretStashComponent component, InteractHandEvent args) + { + if (args.Handled) + return; + + if (!component.OpenableStash) + return; + + // trying to get something from stash? + if (component.ToggleOpen) + { + var gotItem = TryGetItem(uid, args.User); + if (gotItem) + { + args.Handled = true; + return; + } + } + args.Handled = true; + } + + private void OnSecretStashPried(EntityUid uid, SecretStashComponent component, StashPryDoAfterEvent args) + { + if (args.Cancelled) + return; + + ToggleOpen(uid, component); + } + + public void ToggleOpen(EntityUid uid, SecretStashComponent? component = null, MetaDataComponent? meta = null) + { + if (!Resolve(uid, ref component)) + return; + + component.ToggleOpen = !component.ToggleOpen; + + UpdateAppearance(uid, component); + Dirty(uid, component, meta); + } + + private void UpdateAppearance(EntityUid uid, SecretStashComponent? component = null) + { + if (!Resolve(uid, ref component)) + return; + + _appearance.SetData(uid, StashVisuals.DoorVisualState, component.ToggleOpen ? DoorVisualState.DoorOpen : DoorVisualState.DoorClosed); + } + /// /// Tries to hide item inside secret stash from hands of user. /// @@ -62,7 +141,7 @@ namespace Content.Server.Storage.EntitySystems if (container.ContainedEntity != null) { var msg = Loc.GetString("comp-secret-stash-action-hide-container-not-empty"); - _popupSystem.PopupEntity(msg, uid, userUid); + _popupSystem.PopupClient(msg, uid, userUid); return false; } @@ -71,7 +150,7 @@ namespace Content.Server.Storage.EntitySystems { var msg = Loc.GetString("comp-secret-stash-action-hide-item-too-big", ("item", itemToHideUid), ("stash", GetSecretPartName(uid, component))); - _popupSystem.PopupEntity(msg, uid, userUid); + _popupSystem.PopupClient(msg, uid, userUid); return false; } @@ -84,7 +163,7 @@ namespace Content.Server.Storage.EntitySystems // all done, show success message var successMsg = Loc.GetString("comp-secret-stash-action-hide-success", ("item", itemToHideUid), ("this", GetSecretPartName(uid, component))); - _popupSystem.PopupEntity(successMsg, uid, userUid); + _popupSystem.PopupClient(successMsg, uid, userUid); return true; } @@ -113,11 +192,23 @@ namespace Content.Server.Storage.EntitySystems // show success message var successMsg = Loc.GetString("comp-secret-stash-action-get-item-found-something", ("stash", GetSecretPartName(uid, component))); - _popupSystem.PopupEntity(successMsg, uid, userUid); + _popupSystem.PopupClient(successMsg, uid, userUid); return true; } + private void OnExamine(EntityUid uid, SecretStashComponent component, ExaminedEvent args) + { + if (args.IsInDetailsRange && component.ToggleOpen) + { + if (HasItemInside(uid)) + { + var msg = Loc.GetString(component.ExamineStash); + args.PushMarkup(msg); + } + } + } + private string GetSecretPartName(EntityUid uid, SecretStashComponent stash) { if (stash.SecretPartName != "") diff --git a/Content.Shared/Store/ListingLocalisationHelpers.cs b/Content.Shared/Store/ListingLocalisationHelpers.cs new file mode 100644 index 0000000000..3ac75cd801 --- /dev/null +++ b/Content.Shared/Store/ListingLocalisationHelpers.cs @@ -0,0 +1,42 @@ +using Robust.Shared.Prototypes; + +namespace Content.Shared.Store; + +public static class ListingLocalisationHelpers +{ + /// + /// ListingData's Name field can be either a localisation string or the actual entity's name. + /// This function gets a localised name from the localisation string if it exists, and if not, it gets the entity's name. + /// If neither a localised string exists, or an associated entity name, it will return the value of the "Name" field. + /// + public static string GetLocalisedNameOrEntityName(ListingData listingData, IPrototypeManager prototypeManager) + { + bool wasLocalised = Loc.TryGetString(listingData.Name, out string? listingName); + + if (!wasLocalised && listingData.ProductEntity != null) + { + var proto = prototypeManager.Index(listingData.ProductEntity); + listingName = proto.Name; + } + + return listingName ?? listingData.Name; + } + + /// + /// ListingData's Description field can be either a localisation string or the actual entity's description. + /// This function gets a localised description from the localisation string if it exists, and if not, it gets the entity's description. + /// If neither a localised string exists, or an associated entity description, it will return the value of the "Description" field. + /// + public static string GetLocalisedDescriptionOrEntityDescription(ListingData listingData, IPrototypeManager prototypeManager) + { + bool wasLocalised = Loc.TryGetString(listingData.Description, out string? listingDesc); + + if (!wasLocalised && listingData.ProductEntity != null) + { + var proto = prototypeManager.Index(listingData.ProductEntity); + listingDesc = proto.Description; + } + + return listingDesc ?? listingData.Description; + } +} diff --git a/Content.Shared/Toilet/Components/ToiletComponent.cs b/Content.Shared/Toilet/Components/ToiletComponent.cs new file mode 100644 index 0000000000..5de74e08f6 --- /dev/null +++ b/Content.Shared/Toilet/Components/ToiletComponent.cs @@ -0,0 +1,40 @@ +using Robust.Shared.Audio; +using Robust.Shared.GameStates; +using Robust.Shared.Serialization; + +namespace Content.Shared.Toilet.Components +{ + /// + /// Toilets that can be flushed, seats toggled up and down, items hidden in cistern. + /// + [RegisterComponent, NetworkedComponent, AutoGenerateComponentState] + public sealed partial class ToiletComponent : Component + { + /// + /// Toggles seat state. + /// + [DataField, AutoNetworkedField] + public bool ToggleSeat; + + + /// + /// Sound to play when toggling toilet seat. + /// + [DataField] + public SoundSpecifier SeatSound = new SoundPathSpecifier("/Audio/Effects/toilet_seat_down.ogg"); + } + + [Serializable, NetSerializable] + public enum ToiletVisuals : byte + { + SeatVisualState, + } + + [Serializable, NetSerializable] + public enum SeatVisualState : byte + { + SeatUp, + SeatDown + } +} + diff --git a/Content.Shared/Toilet/Systems/SharedToiletSystem.cs b/Content.Shared/Toilet/Systems/SharedToiletSystem.cs new file mode 100644 index 0000000000..87df69e88d --- /dev/null +++ b/Content.Shared/Toilet/Systems/SharedToiletSystem.cs @@ -0,0 +1,109 @@ +using Content.Shared.Buckle.Components; +using Content.Shared.Interaction; +using Content.Shared.Verbs; +using Content.Shared.Plunger.Components; +using Robust.Shared.Audio.Systems; +using Robust.Shared.Random; +using Robust.Shared.Utility; +using Content.Shared.Toilet.Components; + +namespace Content.Shared.Toilet.Systems +{ + /// + /// Handles sprite changes for both toilet seat up and down as well as for lid open and closed. Handles interactions with hidden stash + /// + + public abstract class SharedToiletSystem : EntitySystem + { + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnMapInit); + SubscribeLocalEvent>(OnToggleSeatVerb); + SubscribeLocalEvent(OnActivateInWorld); + } + + private void OnMapInit(EntityUid uid, ToiletComponent component, MapInitEvent args) + { + if (_random.Prob(0.5f)) + component.ToggleSeat = true; + + if (_random.Prob(0.3f)) + { + TryComp(uid, out var plunger); + + if (plunger == null) + return; + + plunger.NeedsPlunger = true; + } + + UpdateAppearance(uid); + Dirty(uid, component); + } + + public bool CanToggle(EntityUid uid) + { + return TryComp(uid, out var strap) && strap.BuckledEntities.Count == 0; + } + + private void OnToggleSeatVerb(EntityUid uid, ToiletComponent component, GetVerbsEvent args) + { + if (!args.CanInteract || !args.CanAccess || !CanToggle(uid) || args.Hands == null) + return; + + AlternativeVerb toggleVerb = new() + { + Act = () => ToggleToiletSeat(uid, args.User, component) + }; + + if (component.ToggleSeat) + { + toggleVerb.Text = Loc.GetString("toilet-seat-close"); + toggleVerb.Icon = + new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/VerbIcons/close.svg.192dpi.png")); + } + else + { + toggleVerb.Text = Loc.GetString("toilet-seat-open"); + toggleVerb.Icon = + new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/VerbIcons/open.svg.192dpi.png")); + } + args.Verbs.Add(toggleVerb); + } + + private void OnActivateInWorld(EntityUid uid, ToiletComponent comp, ActivateInWorldEvent args) + { + if (args.Handled) + return; + + args.Handled = true; + ToggleToiletSeat(uid, args.User, comp); + } + + public void ToggleToiletSeat(EntityUid uid, EntityUid? user = null, ToiletComponent? component = null, MetaDataComponent? meta = null) + { + if (!Resolve(uid, ref component)) + return; + + component.ToggleSeat = !component.ToggleSeat; + + _audio.PlayPredicted(component.SeatSound, uid, uid); + UpdateAppearance(uid, component); + Dirty(uid, component, meta); + } + + private void UpdateAppearance(EntityUid uid, ToiletComponent? component = null) + { + if (!Resolve(uid, ref component)) + return; + + _appearance.SetData(uid, ToiletVisuals.SeatVisualState, component.ToggleSeat ? SeatVisualState.SeatUp : SeatVisualState.SeatDown); + } + } +} diff --git a/Content.Shared/Toilet/ToiletComponent.cs b/Content.Shared/Toilet/ToiletComponent.cs deleted file mode 100644 index 161bf81c99..0000000000 --- a/Content.Shared/Toilet/ToiletComponent.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Content.Shared.DoAfter; -using Content.Shared.Tools; -using Robust.Shared.Audio; -using Robust.Shared.Serialization; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; - -namespace Content.Shared.Toilet -{ - [RegisterComponent] - public sealed partial class ToiletComponent : Component - { - [DataField("pryLidTime")] - public float PryLidTime = 1f; - - [DataField("pryingQuality", customTypeSerializer:typeof(PrototypeIdSerializer))] - public string PryingQuality = "Prying"; - - [DataField("toggleSound")] - public SoundSpecifier ToggleSound = new SoundPathSpecifier("/Audio/Effects/toilet_seat_down.ogg"); - - [DataField("lidOpen")] - public bool LidOpen = false; - - [DataField("isSeatUp")] - public bool IsSeatUp = false; - } - - [Serializable, NetSerializable] - public sealed partial class ToiletPryDoAfterEvent : SimpleDoAfterEvent - { - } -} diff --git a/Content.Shared/Toilet/ToiletVisuals.cs b/Content.Shared/Toilet/ToiletVisuals.cs deleted file mode 100644 index c5992bc0be..0000000000 --- a/Content.Shared/Toilet/ToiletVisuals.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Robust.Shared.Serialization; - -namespace Content.Shared.Toilet; - -[Serializable, NetSerializable] -public enum ToiletVisuals -{ - LidOpen, - SeatUp -} diff --git a/Content.Shared/Weapons/Melee/MeleeSoundSystem.cs b/Content.Shared/Weapons/Melee/MeleeSoundSystem.cs new file mode 100644 index 0000000000..5bf7480202 --- /dev/null +++ b/Content.Shared/Weapons/Melee/MeleeSoundSystem.cs @@ -0,0 +1,108 @@ +using Content.Shared.Weapons.Melee.Components; +using Robust.Shared.Audio; +using Robust.Shared.Audio.Systems; + +namespace Content.Shared.Weapons.Melee; + +/// +/// This handles +/// +public sealed class MeleeSoundSystem : EntitySystem +{ + [Dependency] private readonly SharedAudioSystem _audio = default!; + + public const float DamagePitchVariation = 0.05f; + + /// + /// Plays the SwingSound from a weapon component + /// for immediate feedback, misses and such + /// (Swinging a weapon goes "whoosh" whether it hits or not) + /// + public void PlaySwingSound(EntityUid userUid, EntityUid weaponUid, MeleeWeaponComponent weaponComponent) + { + _audio.PlayPredicted(weaponComponent.SwingSound, weaponUid, userUid); + } + + /// + /// Takes a "damageType" string as an argument and uses it to + /// search one of the various Dictionaries in the MeleeSoundComponent + /// for a sound to play, and falls back if that fails + /// + /// Serves as a lookup key for a hit sound + /// A sound can be supplied by the itself to override everything else + public void PlayHitSound(EntityUid targetUid, EntityUid? userUid, string? damageType, SoundSpecifier? hitSoundOverride, MeleeWeaponComponent weaponComponent) + { + var hitSound = weaponComponent.HitSound; + var noDamageSound = weaponComponent.NoDamageSound; + + var playedSound = false; + + if (Deleted(targetUid)) + return; + + // hitting can obv destroy an entity so we play at coords and not following them + var coords = Transform(targetUid).Coordinates; + // Play sound based off of highest damage type. + if (TryComp(targetUid, out var damageSoundComp)) + { + if (damageType == null && damageSoundComp.NoDamageSound != null) + { + _audio.PlayPredicted(damageSoundComp.NoDamageSound, coords, userUid, AudioParams.Default.WithVariation(DamagePitchVariation)); + playedSound = true; + } + else if (damageType != null && damageSoundComp.SoundTypes?.TryGetValue(damageType, out var damageSoundType) == true) + { + _audio.PlayPredicted(damageSoundType, coords, userUid, AudioParams.Default.WithVariation(DamagePitchVariation)); + playedSound = true; + } + else if (damageType != null && damageSoundComp.SoundGroups?.TryGetValue(damageType, out var damageSoundGroup) == true) + { + _audio.PlayPredicted(damageSoundGroup, coords, userUid, AudioParams.Default.WithVariation(DamagePitchVariation)); + playedSound = true; + } + } + + // Use weapon sounds if the thing being hit doesn't specify its own sounds. + if (!playedSound) + { + if (hitSoundOverride != null) + { + _audio.PlayPredicted(hitSoundOverride, coords, userUid, AudioParams.Default.WithVariation(DamagePitchVariation)); + playedSound = true; + } + else if (hitSound != null) + { + _audio.PlayPredicted(hitSound, coords, userUid, AudioParams.Default.WithVariation(DamagePitchVariation)); + playedSound = true; + } + else + { + _audio.PlayPredicted(noDamageSound, coords, userUid, AudioParams.Default.WithVariation(DamagePitchVariation)); + playedSound = true; + } + } + + // Fallback to generic sounds. + if (!playedSound) + { + switch (damageType) + { + // Unfortunately heat returns caustic group so can't just use the damagegroup in that instance. + case "Burn": + case "Heat": + case "Radiation": + case "Cold": + _audio.PlayPredicted(new SoundPathSpecifier("/Audio/Items/welder.ogg"), targetUid, userUid, AudioParams.Default.WithVariation(DamagePitchVariation)); + break; + // No damage, fallback to tappies + case null: + _audio.PlayPredicted(new SoundCollectionSpecifier("WeakHit"), targetUid, userUid, AudioParams.Default.WithVariation(DamagePitchVariation)); + break; + case "Brute": + _audio.PlayPredicted(new SoundCollectionSpecifier("MetalThud"), targetUid, userUid, AudioParams.Default.WithVariation(DamagePitchVariation)); + break; + } + } + } + +} diff --git a/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs b/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs index 6a5127f2c9..e59b4a13fe 100644 --- a/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs +++ b/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs @@ -21,8 +21,6 @@ using Content.Shared.Weapons.Melee.Events; using Content.Shared.Weapons.Ranged.Components; using Content.Shared.Weapons.Ranged.Events; using Content.Shared.Weapons.Ranged.Systems; -using Robust.Shared.Audio; -using Robust.Shared.Audio.Systems; using Robust.Shared.Map; using Robust.Shared.Physics; using Robust.Shared.Physics.Systems; @@ -36,22 +34,21 @@ namespace Content.Shared.Weapons.Melee; public abstract class SharedMeleeWeaponSystem : EntitySystem { - [Dependency] protected readonly IGameTiming Timing = default!; - [Dependency] protected readonly IMapManager MapManager = default!; - [Dependency] private readonly IPrototypeManager _protoManager = default!; - [Dependency] protected readonly ISharedAdminLogManager AdminLogger = default!; - [Dependency] protected readonly ActionBlockerSystem Blocker = default!; - [Dependency] protected readonly DamageableSystem Damageable = default!; - [Dependency] private readonly InventorySystem _inventory = default!; - [Dependency] protected readonly SharedAudioSystem Audio = default!; - [Dependency] protected readonly SharedCombatModeSystem CombatMode = default!; - [Dependency] protected readonly SharedInteractionSystem Interaction = default!; - [Dependency] private readonly SharedPhysicsSystem _physics = default!; - [Dependency] protected readonly SharedPopupSystem PopupSystem = default!; - [Dependency] protected readonly SharedTransformSystem TransformSystem = default!; - [Dependency] private readonly StaminaSystem _stamina = default!; + [Dependency] protected readonly ISharedAdminLogManager AdminLogger = default!; + [Dependency] protected readonly ActionBlockerSystem Blocker = default!; + [Dependency] protected readonly SharedCombatModeSystem CombatMode = default!; + [Dependency] protected readonly DamageableSystem Damageable = default!; + [Dependency] protected readonly SharedInteractionSystem Interaction = default!; + [Dependency] protected readonly IMapManager MapManager = default!; + [Dependency] protected readonly SharedPopupSystem PopupSystem = default!; + [Dependency] protected readonly IGameTiming Timing = default!; + [Dependency] protected readonly SharedTransformSystem TransformSystem = default!; + [Dependency] private readonly InventorySystem _inventory = default!; + [Dependency] private readonly MeleeSoundSystem _meleeSound = default!; + [Dependency] private readonly SharedPhysicsSystem _physics = default!; + [Dependency] private readonly IPrototypeManager _protoManager = default!; + [Dependency] private readonly StaminaSystem _stamina = default!; - public const float DamagePitchVariation = 0.05f; private const int AttackMask = (int) (CollisionGroup.MobMask | CollisionGroup.Opaque); /// @@ -83,7 +80,8 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem SubscribeAllEvent(OnStopAttack); #if DEBUG - SubscribeLocalEvent(OnMapInit); + SubscribeLocalEvent (OnMapInit); } private void OnMapInit(EntityUid uid, MeleeWeaponComponent component, MapInitEvent args) @@ -465,7 +463,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem } var missEvent = new MeleeHitEvent(new List(), user, meleeUid, damage, null); RaiseLocalEvent(meleeUid, missEvent); - Audio.PlayPredicted(component.SwingSound, meleeUid, user); + _meleeSound.PlaySwingSound(user, meleeUid, component); return; } @@ -520,7 +518,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem } - PlayHitSound(target.Value, user, GetHighestDamageSound(modifiedDamage, _protoManager), hitEvent.HitSoundOverride, component.HitSound, component.NoDamageSound); + _meleeSound.PlayHitSound(target.Value, user, GetHighestDamageSound(modifiedDamage, _protoManager), hitEvent.HitSoundOverride, component); if (damageResult?.GetTotal() > FixedPoint2.Zero) { @@ -563,7 +561,9 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem var missEvent = new MeleeHitEvent(new List(), user, meleeUid, damage, direction); RaiseLocalEvent(meleeUid, missEvent); - Audio.PlayPredicted(component.SwingSound, meleeUid, user); + // immediate audio feedback + _meleeSound.PlaySwingSound(user, meleeUid, component); + return true; } @@ -658,7 +658,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem if (entities.Count != 0) { var target = entities.First(); - PlayHitSound(target, user, GetHighestDamageSound(appliedDamage, _protoManager), hitEvent.HitSoundOverride, component.HitSound, component.NoDamageSound); + _meleeSound.PlayHitSound(target, user, GetHighestDamageSound(appliedDamage, _protoManager), hitEvent.HitSoundOverride, component); } if (appliedDamage.GetTotal() > FixedPoint2.Zero) @@ -702,77 +702,6 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem return true; } - public void PlayHitSound(EntityUid target, EntityUid? user, string? type, SoundSpecifier? hitSoundOverride, SoundSpecifier? hitSound, SoundSpecifier? noDamageSound) - { - var playedSound = false; - - if (Deleted(target)) - return; - - // hitting can obv destroy an entity so we play at coords and not following them - var coords = Transform(target).Coordinates; - // Play sound based off of highest damage type. - if (TryComp(target, out var damageSoundComp)) - { - if (type == null && damageSoundComp.NoDamageSound != null) - { - Audio.PlayPredicted(damageSoundComp.NoDamageSound, coords, user, AudioParams.Default.WithVariation(DamagePitchVariation)); - playedSound = true; - } - else if (type != null && damageSoundComp.SoundTypes?.TryGetValue(type, out var damageSoundType) == true) - { - Audio.PlayPredicted(damageSoundType, coords, user, AudioParams.Default.WithVariation(DamagePitchVariation)); - playedSound = true; - } - else if (type != null && damageSoundComp.SoundGroups?.TryGetValue(type, out var damageSoundGroup) == true) - { - Audio.PlayPredicted(damageSoundGroup, coords, user, AudioParams.Default.WithVariation(DamagePitchVariation)); - playedSound = true; - } - } - - // Use weapon sounds if the thing being hit doesn't specify its own sounds. - if (!playedSound) - { - if (hitSoundOverride != null) - { - Audio.PlayPredicted(hitSoundOverride, coords, user, AudioParams.Default.WithVariation(DamagePitchVariation)); - playedSound = true; - } - else if (hitSound != null) - { - Audio.PlayPredicted(hitSound, coords, user, AudioParams.Default.WithVariation(DamagePitchVariation)); - playedSound = true; - } - else if (noDamageSound != null) - { - Audio.PlayPredicted(noDamageSound, coords, user, AudioParams.Default.WithVariation(DamagePitchVariation)); - playedSound = true; - } - } - - // Fallback to generic sounds. - if (!playedSound) - { - switch (type) - { - // Unfortunately heat returns caustic group so can't just use the damagegroup in that instance. - case "Burn": - case "Heat": - case "Radiation": - case "Cold": - Audio.PlayPredicted(new SoundPathSpecifier("/Audio/Items/welder.ogg"), target, user, AudioParams.Default.WithVariation(DamagePitchVariation)); - break; - // No damage, fallback to tappies - case null: - Audio.PlayPredicted(new SoundCollectionSpecifier("WeakHit"), target, user, AudioParams.Default.WithVariation(DamagePitchVariation)); - break; - case "Brute": - Audio.PlayPredicted(new SoundCollectionSpecifier("MetalThud"), target, user, AudioParams.Default.WithVariation(DamagePitchVariation)); - break; - } - } - } public static string? GetHighestDamageSound(DamageSpecifier modifiedDamage, IPrototypeManager protoManager) { @@ -809,7 +738,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem } // Play a sound to give instant feedback; same with playing the animations - Audio.PlayPredicted(component.SwingSound, meleeUid, user); + _meleeSound.PlaySwingSound(user, meleeUid, component); return true; } diff --git a/Content.Shared/Wires/SharedWiresSystem.cs b/Content.Shared/Wires/SharedWiresSystem.cs index f069687ffb..b4b0768e0f 100644 --- a/Content.Shared/Wires/SharedWiresSystem.cs +++ b/Content.Shared/Wires/SharedWiresSystem.cs @@ -28,15 +28,24 @@ public abstract class SharedWiresSystem : EntitySystem if (args.Cancelled) return; - TogglePanel(uid, panel, !panel.Open); + if (!TogglePanel(uid, panel, !panel.Open, args.User)) + return; + AdminLogger.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(args.User):user} screwed {ToPrettyString(uid):target}'s maintenance panel {(panel.Open ? "open" : "closed")}"); var sound = panel.Open ? panel.ScrewdriverOpenSound : panel.ScrewdriverCloseSound; Audio.PlayPredicted(sound, uid, args.User); + args.Handled = true; } private void OnInteractUsing(Entity ent, ref InteractUsingEvent args) { + if (!Tool.HasQuality(args.Used, ent.Comp.OpeningTool)) + return; + + if (!CanTogglePanel(ent, args.User)) + return; + if (!Tool.UseTool( args.Used, args.User, @@ -89,14 +98,25 @@ public abstract class SharedWiresSystem : EntitySystem Appearance.SetData(uid, WiresVisuals.MaintenancePanelState, panel.Open && panel.Visible, appearance); } - public void TogglePanel(EntityUid uid, WiresPanelComponent component, bool open) + public bool TogglePanel(EntityUid uid, WiresPanelComponent component, bool open, EntityUid? user = null) { + if (!CanTogglePanel((uid, component), user)) + return false; + component.Open = open; UpdateAppearance(uid, component); Dirty(uid, component); var ev = new PanelChangedEvent(component.Open); RaiseLocalEvent(uid, ref ev); + return true; + } + + public bool CanTogglePanel(Entity ent, EntityUid? user) + { + var attempt = new AttemptChangePanelEvent(ent.Comp.Open, user); + RaiseLocalEvent(ent, ref attempt); + return !attempt.Cancelled; } public bool IsPanelOpen(Entity entity) diff --git a/Content.Shared/Wires/WiresPanelComponent.cs b/Content.Shared/Wires/WiresPanelComponent.cs index 9c7444778e..a18e590e21 100644 --- a/Content.Shared/Wires/WiresPanelComponent.cs +++ b/Content.Shared/Wires/WiresPanelComponent.cs @@ -57,6 +57,12 @@ public sealed partial class WiresPanelComponent : Component public LocId? ExamineTextOpen = "wires-panel-component-on-examine-open"; } +/// +/// Event raised on a before its open state is about to be changed. +/// +[ByRefEvent] +public record struct AttemptChangePanelEvent(bool Open, EntityUid? User, bool Cancelled = false); + /// /// Event raised when a panel is opened or closed. /// diff --git a/Resources/Audio/Effects/Fluids/attributions.yml b/Resources/Audio/Effects/Fluids/attributions.yml index 4e28c99252..aebe3e3c3f 100644 --- a/Resources/Audio/Effects/Fluids/attributions.yml +++ b/Resources/Audio/Effects/Fluids/attributions.yml @@ -12,3 +12,13 @@ license: "CC0-1.0" copyright: "Created by brittmosel" source: "https://freesound.org/people/brittmosel/sounds/529300/" + +- files: ["splash.ogg"] + license: "CC0-1.0" + copyright: "Created by deadrobotmusic" + source: "https://freesound.org/people/deadrobotmusic/sounds/609953/" + +- files: ["flush.ogg"] + license: "CC-BY-SA-3.0" + copyright: "Created by the_toilet_guy" + source: "https://freesound.org/people/the_toilet_guy/sounds/98770/" diff --git a/Resources/Audio/Effects/Fluids/flush.ogg b/Resources/Audio/Effects/Fluids/flush.ogg new file mode 100644 index 0000000000000000000000000000000000000000..f4ef31c2ab17c405f90f919d5d2449b4eb6ffc7b GIT binary patch literal 132202 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

Rm;+rLYzNcc+E1pe0C9bit2 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 pT8}>{|7@%mm&ZF literal 0 HcmV?d00001 diff --git a/Resources/Audio/Items/attributions.yml b/Resources/Audio/Items/attributions.yml index e63b678ef8..c6fea50bd2 100644 --- a/Resources/Audio/Items/attributions.yml +++ b/Resources/Audio/Items/attributions.yml @@ -107,3 +107,13 @@ license: "CC0-1.0" copyright: "Bhijn and Myr (github username deathride58)" source: "https://github.com/space-wizards/space-station-14/pull/23476" + +- files: ["drill_hit.ogg"] + license: "CC-BY-4.0" + copyright: "Created by vanilla with sounds from MinecraftGamerLR and stomachache on freesound.org" + source: "https://github.com/space-wizards/space-station-14/pull/26622" + +- files: ["drill_use.ogg"] + license: "CC0-1.0" + copyright: "Original sound by stomachache on freesound.org, processed by vanilla" + source: "https://freesound.org/s/262213/" diff --git a/Resources/Audio/Items/drill_hit.ogg b/Resources/Audio/Items/drill_hit.ogg index 0f8fa631aa1a0943d7cad0e33ccaa1d703d3b8ba..dcdfe5df3a1ca5c5ba0f1eb233bd5dbd5beb6efe 100644 GIT binary patch delta 38991 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 diff --git a/Resources/Audio/Items/drill_use.ogg b/Resources/Audio/Items/drill_use.ogg index 82f37cd35bb2c3e233211e0b99ebb0e09b3ea5ba..6cd027d3b27e27e8232eff2312b44d6374015a08 100644 GIT binary patch delta 53931 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 diff --git a/Resources/Audio/Machines/attributions.yml b/Resources/Audio/Machines/attributions.yml index a0f1c9f7e7..38267ebd69 100644 --- a/Resources/Audio/Machines/attributions.yml +++ b/Resources/Audio/Machines/attributions.yml @@ -152,3 +152,12 @@ license: "CC0-1.0" copyright: "dakamakat on freesound.org" source: "https://freesound.org/people/Dakamakat/sounds/717370/" + +- files: + - twobeep.ogg + - chime.ogg + - buzz-sigh.ogg + - buzztwo.ogg + license: "CC-BY-SA-3.0" + copyright: "Taken from TG station." + source: "https://github.com/tgstation/tgstation/tree/d4f678a1772007ff8d7eddd21cf7218c8e07bfc0" diff --git a/Resources/Audio/Machines/buzz-sigh.ogg b/Resources/Audio/Machines/buzz-sigh.ogg new file mode 100644 index 0000000000000000000000000000000000000000..109c196e2c4fef313bdb2a17c4c7b4a59668eda4 GIT binary patch literal 8972 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 z zUk9!0d;3}>o&Dsi4=l7-Z$>{%*Xqx1?h?N5VpE+h}prvd?FuTHoDuR4N(cu|9Xs7dss5)QR458ev;{~B!gnJKs zDHaWUh)(V3YP*J5W~NCVWX{Zkcj25eJI(Rzyp*$Ddu<5y z(jnAV&w|`rKk=!pgIN9rz)-Y?vRfr4ga8+qlr@lFk0X|3v>_#BPY04Pc`#qMl`g~tGHg1Q61%7Zs?`K@RqEr0kKmaC%xrBf~@K*`AMGY?e1!Sp+vt{Q{)ES-M6 z6ux_Mw8;eBh1%i%>gfYTro7?Exc9}DlzGZw9MSnHf)U3HdtZJ!^)%r(trw5JG05{O zEpiy(7P)H-0qM55i|dBN%aOclEt)m4DXZ-|(Z0&7qv@Jk$Np;irOO_QHM*OePrWEZSFZYnbCt&($v3 z0AI}R;O+y^j#hR9uxA5gkX;FRAv> zbDw4iNyCW`wj18Hx6ON59vfBkEstkX=Znb(KBA{aUii1%UlqMnuh@$12jR2MI$-vK z+ut%BG~g58$^-B9U{&l*N0NYxk6o0w{ytL)dH}PTPR!HB%XRmvJHK zDFK0Wbr@YgM-O^VQKQshsGv*pfwr0VFBCDUC%qiLU(|n;tgYQ|F zk?x-}Jw?b`1i9aCg4|L8J>y_eUWl&fUeC43l(v<%A z6Z;;fB3vLKk@~v1iVx#J8#;d)rS8CkcT5sjrEgIta+?k!Q|P{ka2$)FikvtMVozVv zakI?02vDK#YBm}y#{Cg#+dd_}={{%Z#ry?4+-JV_;r8sPrS^)%x*^&F9%rf?I%Tz$eVT z_Zw5e1^m99$Eb$KqWhFm$z>}k4+V0GSM}xIQ(E{PX?&k@80Zw?QjcoG7GnbH;<00S zl@_$8W8Zu`5JxxN`DmN@D@SBShiNy)6eQx%A22Tf2>W)QfF2rj9Ki++62r=1q^i#t zjZYptrw=_Vb(EuF*b0GRwo$BZxz0nE^czp#d{&%)bl}6C$=jO7*BCLk+3Y2k zWKK$?oiS9d^O*W0n{#9Gr?0BaqGMyquGT%dwe9%4bMIqRQ%;PI*JDOUR30teSof-K z&3mKt?Y@NkUgC!_*G|&1->Q9oUKvaZkIXMxbANq72BOgELrQu8%n5rgEW=P4{@Lo? z9W>pu&ykB!3ufs9#u3d%OONZNjz79#Er0VR8)jfeO|u>O?d^$%lg@Jc8^-W@){K#? YpWW{(cLm8@!@I_{S#7+Mw$|`}0FkJ~c>n+a literal 0 HcmV?d00001 diff --git a/Resources/Audio/Machines/twobeep.ogg b/Resources/Audio/Machines/twobeep.ogg new file mode 100644 index 0000000000000000000000000000000000000000..26fc5a95a57bb4a0537355f874665e4a9199c02a GIT binary patch literal 6851 zcmai22|UzY_rGHwh9+A>>KQebv1KgPC^bYeOfrlZlr`C9>nUVpdF_cwj3wJBLM5Yz zQd%q_S%*qdLZLm{^S?8CmjC@v#E};Ma3VXL%5E z(?1Wf77-a7>fsy4n?jh?{91At!5{pAu;K0e>*4L>QAQcN+R_p%~qx6#XU<(Wpa>J5FS650&|WNX5(gJ)ff zh--9MFL9>uSBK>5frV!=6;bd)n~L$+C*v#gLLsYVwXlEz)dagv%35BM?Y^XRuODag zUdvX-uwUQY&YnVpPlW5^$`r@TbxKVqEzNOT@ebp4d*j!F8}KF5rI;x)eN zSOh3pPt2Xfm#tGQdqyl1Oh~E`0A4(kV3FDD@Y&^-l?VLld=}$)L>Vb zK}XnD*mi}R-DO(e`)Ix5Pbcu)4giUu)OJYeF0=+!doa{+ZwT;X2;|mT1)jN4VFi zk2QU+NfwS$m<4K_Ci`W6zhF_dudw$f@hRMq^02_a3F!()U%U!m-$U}|{vAFf=r{LK zOncFBY)qzzhpcj?a?aZD6H+-Pgid_L+KkMd$- zbSl;>%S1$hA0$b6pjHG2LkJwVRhpC3cRBf8Q@qdmONF6qy3>rYgo&rDtfc4PH3Fy?&EYl!k zM=`=QPPmjPQhEoIa2BnPB1*0c&oWUn{v(@s8}(s=sxD_{9iO4HDHAJstJ1}CYO@$j zdqTh#00yCxa0e6GYk9ZCte1c+Vs;YM*f|51c&NZD+2zRsvCHj1GE~L2*KUYF|d+Vv63;rFY7%bLm4?`aL>Td z)}GcaLmRfIJ(8!;8dWGV6v{_?nv6M3jy9M}p>YE58+bpkr#+UZ4L5o}l0UXLH)33$ z;sjs0kQy;2#p%}M^4^GM>;#h9lU9_Nwa2uOA3db?kV7+3dY`TCWet7fTJ zS65Xx23FVAI+wkuF01aU_o=R{>8ihQzAj)6QtQrD*K1W*Yn`vJ`Btqp*LbeFxwfnR zVnN;cxyCmVx3%V)L#pfQ&ezZLsLi!=?T6-?b)zfs-IeEOo2#0egXWqK^)v=5l~>PR z*XX`=v8(>gT=Ry82xVJZ#ABxGa;3od{d_LNJd%pY_mr9 zbts51)*h^MRaeRN(MCups;`xZ@$CGByzl?0{m?g~$;F8B3n*mA35X2@4;wOFq*7%~ z0mfzo5K*3ywL@#PVZ+hXS!{(pK}0!hH@QuTxrgkh%pB5a$J%FFb{6JHlMmvV160vc z_8zi-DU(a}zf?Ko@d{fZPxjSj4$%Fo+K1@rD?QPAGZkLFmPmF3j{sTClvGHWlGzoq zR%C659th;}0TYX=3TZpbDh_1Du8_AP6B=cmg9uzDxT8Ya*%IF_YZs{9&RXA&g{98oCR@W(k;#`5sq_E>w~!iO2u}rBWs?K6 z+v(2MoCq{sf`6)7j)T8nZ95dM!p2yUFLC7kg9y`#WZznz@TxX>=S(Qv&fl<->&GKF z2O4u(VdPrw5H$l5JOf*XSy6BP)ZD{QyPfM%%M-3~=~OlpKK+oMPGk;vKvvn*bhyJg zps6y~4-#0^G|u$HumHowA$ko@h84Ua!cH_TIKZsK5CkL!(z}G0LU>_ol1%Nj^hJmE z5H*mdJw&ytP-{~>p4MX`ro!nZ;_+=O>-bzEe&A}g!hgxXEx`Q9KB9xRigt(*= z5}3g#ZpXsBBci~@#P?w;WIfUA*cj*+wyY<#EhbFLR71hD*F+tku!pRHPehX~RoJk= z6<31wTtFYwQ3)PsIghxZJWzxrY`DFi#>xb1vRYLfv}kPvgaW&*hwfL~FiH}uP2}oX zsX!LJ1oZ3+pn-YboV9h*78BT&gNv2YI04(Ab=RB-?_LSRL7(bg;M_{kEOGX=mAUd|*F zMN64G@$FbJ#puxh98AlJ4z`qwG5xgIr!BM`)# zX_h}368!Hq0Wc;k3N8w+Hs7d*L24Ly@s(g;p&8Q&NwOZPgqgw}V)(W^SmRV;c%=ut zWO?;RIwZi?c1R%3DDk?&u*|;;lfOsE|3`@`SZA$tfVXu!X0_OIRlZZ2|LPg=t4PmV ze*H(y{&)5MpGMC9wGeXu>;UP8xF}c>UG1=IGhR_bi>D)63Kn{|^Wcd^)+8k1UsNPO z_mu7+6V+89O7M6H9~jY0Iypa#O4U$d=kij=5S^?Id5fyBxl}(W#Yl|ZFvJrzYGQ$B zbLnZ?FyzSa)g#?7i3*prje67&Dh8-9J~5s(Fo5X(@aX>9cn;SiodfL;GX&Qo&5%o% z024tWfMId*P|~T2%eVR`_`X(##kMKm+Pn_~D)dDO4=u`OWQZyrMwAnv818p`08cT6e| zkUS=_5YP`!^wd3ELl4b&nXP%xitak=ZX6vws-ehz zBdT`v!j;x1JB++mr-=aBqrwKKZ9-#z%9P7p);#l&Be-?dCN&H~7|3ZpeL3kFk@V2i z){B!WtR-nKvi|D67FWf`7*?lwb~9;lY2t+UtaSF5H?m9cprhMQxs5TV^jaT%yKexz zOg=5h1Fu-d2vmTP;+g4d-6Swg_o;Nz&TIBL9{td;Lh+rPd5*+~2d^x>`^VJnhgQ#0 zI?l>{sU9`zbLeuu^J8vFCk(eXCzV9q!xYkVYBXMbZA5HGX<^J@?8Dd9VUAzkub7Qk z>k=-~SzTtt`TXQo`%&cTXTKfYuzQ;0kmp|;z2oJ-w#spQTVl(k92Gw|2Io!CC*Hk{ zcafqImezha_~2vUR&aeZF|mp9E%vR={J;E3k!uttR>1?i36Dwu=R{QNlP+;kvLDV| zJLYj3{*xog;J_IJ9QYoE4$XV2+LKu?Ev^F$b7Mw!mZa=*C*)&>MSSn7d_Wvk--@OB z3Pv>+rn6eF>8*07Spag(c6*)6ERS37)_)EguD;bcy(lQ+*ZaHH##b4&etTb@XkNTy zF%hyoCev~M;BV?K2Q1@)7ljLw_6I&3YkBz&fI{=v76j8j=ExMbl)_8%@(P^3gY>}&iDNApEcIcT8K8UFLC;?A=QBNcaF>&-Z=z9aeS7qZF9Ao^q2_CHE z7yx{yxPqZ3*TAGr_EcFNdFRZpqqL-MzN$QSpZuXK?z>n)M;bi|A5K zq0N%9Ip329w<0#lgsVQe+?a|WD+me}CyZVpGaa`5jFPh^bWC0c(>;-^R*?kdkV|#1u zMW_=>4d8nSe`q(fJ#&qr4x1tyQfRV5>My@5pWe7LXMjX{^-joM)GhC+smpXcE&q9L zz?quw+QUt#C^h=Cr;M!Q3&i)wJBW^P5qp5Su#$Ym?aF6l6{m>{UXOF0OATyk{a_+F z(!IL6^_ZaqIc!ad-DR49Zfhflo0`i4>!P}j%+!SDN7Hsj@p8d6pQF}y z%YMF+N~_gw$ycTHJc;uBt{G=wX%cdh=Birzbyjlh3FpiF zQxS~k<8Ic*DMWC2WP24jZ8BGDGuraX$L;6*UVkXoUbR{i4ZPbc?;S% zRHrBD^IK0(Z&FJX5sGQ778o-01@oM(O4-ge)@|Ft3SAS1N=C01J2)!E;9rsN3SV(& ziuYu1L~XQ{{mhL;I%jLLDBJG3WPwZ9>iW{x-Q1!T&)st6_;u5FwraP)5J9-I;)uoy zj$C%y1Fzrq07FF4nf_Ih6sP`8lSdA;JfpBXrXp7@lH0=?BEsccuI6q}Tyxj;VEqbpMkpyV z=-W?nVot=54@)T@Ppu_}K3NDp;nNVylo1r#w({QKU}SEri4{6$Ovq*<5IrYwKu$4# zbg?`{oT74e(&I+% z{Wh9yi)pv?QzgE3dKVu>1TUc~&Lc#J-Ga%qUJbb9Sbi#oKhM5= z`c(lmZ*RT8OHBt~oKVUL+V5Nti@I{Qh$Z~ikR+|6)vs>#vRT_}f-c}&q@s05D3z`v zSwOMN)Rta-mO(pYlv4Tr>XZ*H9Hh=1VU{|2xrEzil>0C`PyD_rQzLA|Yt7X&iJT;I ze(}l+qrL>)E$)Z(9;PU&nhD*`FWtd?bfkc~$MR7Rs*6~_lMtZ2!XHgM_$JKinp-x1{wwc(W;xxj&5cf_PDS5aXkZYsq*E<&yLj>0>VQhX}C|$pA z{_!`rR^A0BsfC|Fw9fqyC>8`yp4cM6JV>&1@2UyX8CVA*{Lfyx8dM~5YwNu1c83tw4AI-O5)?0!PigV8*w zM%Z?+Sr)k55CmDr5FlXtrEEw!B?}C|VZ11K^QQE)P$4c^#(AZ!a<8CIFzzw{Lpntp z#KDqIyFqeFZPKYM-N`$9(|X>$Q3K%UCg5@NTGFG^UTcO;?)+Zdd%61!_>6mJh7I?b zN2*_aeRBP)^cMpX=&h*&Mg3+nu?Jqemjqecr?euse9awNvi%0!L}$*_7_OPx7NLKx zM7~j`>n6$Dsc`yQpVA%EK*8&yhH}mE>9GxGUk{u4%&#dN*Z@H!UIXCGJQ$UTa655W z0${tRKRGKhz6p*&U0OrvKnu)GLW6{^dHY;(4v8yg&`cGNm|hGvt-It_jmkbT6_DNxES^Ro*{Tg*h>4SpLq+7vN6{J?<9AXQj27p!s`b9U&YC^5 zSB_C>XGW-%>fF`~E!w$Z1!Jq^6`kL&N>9n8$%9CdCE#O{QX}tpP98NrEVDL0BIUtx zdTj5u=JCeY()BIlSIvjsaPQ^6Oi69loHsu=|pJlceU9m#-kh$Pp=5(V^;o1d*JYD)pPrhW+gd zZ}rGWyV@>rsU)svqk)b*i*s w{dLC{6~?g}8=zHz+tQh!6Q11*jyi~uUF*vWb|PB&4`8IhM?kluy}cd$54qP)uK)l5 literal 0 HcmV?d00001 diff --git a/Resources/Audio/Weapons/glug.ogg b/Resources/Audio/Weapons/glug.ogg new file mode 100644 index 0000000000000000000000000000000000000000..424bedd35169c7adffd61011c23b4b375429d92f GIT binary patch literal 27517 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 P>2DsC+9J2}@%aA-FPz9A literal 0 HcmV?d00001 diff --git a/Resources/Changelog/Admin.yml b/Resources/Changelog/Admin.yml index b4b7f699fe..8acf404ad3 100644 --- a/Resources/Changelog/Admin.yml +++ b/Resources/Changelog/Admin.yml @@ -136,5 +136,13 @@ Entries: id: 18 time: '2024-03-29T05:03:34.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/26500 +- author: Simyon + changes: + - message: The aghost command now accepts a optional username argument to aghost + other people. + type: Tweak + id: 19 + time: '2024-03-31T02:05:44.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/26546 Name: Admin Order: 1 diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 136f7054ef..0ca98f46df 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,265 +1,4 @@ Entries: -- author: Menshin - changes: - - message: The PA control box should now properly detect the PA parts in all situations - (notably on Origin) - type: Fix - - message: The PA control box now automatically face the control box on part scanning - type: Tweak - id: 5761 - time: '2024-01-21T09:17:17.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24356 -- author: metalgearsloth - changes: - - message: Fix revolver prediction. - type: Fix - id: 5762 - time: '2024-01-21T11:16:46.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/19649 -- author: metalgearsloth - changes: - - message: Fix shuttle docking highlights being inaccurate. - type: Fix - id: 5763 - time: '2024-01-21T12:14:47.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24369 -- author: icekot8 - changes: - - message: Increased the size of flatpacks made by the Flatpacker 1001. - type: Tweak - id: 5764 - time: '2024-01-21T17:07:59.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24367 -- author: Nairodian - changes: - - message: All vent critter events now have a small delay and alert message before - they spawn. - type: Add - id: 5765 - time: '2024-01-22T01:33:38.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24383 -- author: Flareguy - changes: - - message: The Research Director's hardsuit now uses its older sprites. - type: Tweak - id: 5766 - time: '2024-01-22T01:52:32.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24377 -- author: SonicHDC - changes: - - message: Added reinforced diagonal! - type: Add - id: 5767 - time: '2024-01-22T14:53:19.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24393 -- author: Alekshhh - changes: - - message: Hud eyepatches have been added to BarDrobes, MediDrobes and SecTechs. - They're just cooler looking huds. - type: Add - id: 5768 - time: '2024-01-22T14:59:32.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24132 -- author: CrigCrag - changes: - - message: Removed the revolutionaries gamemode pending a rework. - type: Remove - id: 5769 - time: '2024-01-23T02:11:09.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24420 -- author: themias - changes: - - message: Added different footstep sounds for blood, soda and juice - type: Add - id: 5770 - time: '2024-01-23T04:18:33.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24406 -- author: TheShuEd - changes: - - message: 'Flesh and Rock anom reworked: It should be easier to maintain them now - (I guess)' - type: Tweak - id: 5771 - time: '2024-01-23T12:32:05.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24381 -- author: metalgearsloth - changes: - - message: Fix thrusters. - type: Fix - id: 5772 - time: '2024-01-23T12:49:19.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24446 -- author: '0x6273' - changes: - - message: Hotplates now work again - type: Fix - id: 5773 - time: '2024-01-23T13:06:14.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24450 -- author: Boaz1111 - changes: - - message: Lizards can now properly eat fruit cakes and banana cream pie slices. - type: Fix - id: 5774 - time: '2024-01-23T18:08:32.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24457 -- author: icekot8 - changes: - - message: The bounty of briefcases has been removed - type: Remove - id: 5775 - time: '2024-01-23T18:26:28.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24392 -- author: Errant - changes: - - message: '"Not enough oxygen" hud alerts now indicate the proper gas for nitrogen - breathers.' - type: Fix - id: 5776 - time: '2024-01-23T20:17:41.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24373 -- author: themias - changes: - - message: Cyborgs can no longer spawn with the Wheelchair Bound or Muted trait - type: Fix - id: 5777 - time: '2024-01-23T20:18:01.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24459 -- author: Nimfar11 - changes: - - message: Adds solo comfy benches in different colors. - type: Add - id: 5778 - time: '2024-01-23T22:15:48.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24203 -- author: Tin-Man-Tim - changes: - - message: Attempting to microwave metal now can cause the microwave to spark and - explode. - type: Tweak - id: 5779 - time: '2024-01-23T22:59:10.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/23887 -- author: DrMelon - changes: - - message: The Microwave works as intended after power outages again. - type: Fix - id: 5780 - time: '2024-01-24T01:14:55.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/23997 -- author: Krunk - changes: - - message: To prevent accidental spills, buckets can no longer be quick-equipped. - type: Fix - id: 5781 - time: '2024-01-24T02:35:37.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24472 -- author: lzk228 - changes: - - message: Fixed escaping from locked artifact crate. - type: Fix - id: 5782 - time: '2024-01-25T00:46:07.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24442 -- author: Krunk - changes: - - message: Players will once again spawn at arrivals instead of cryostorage. - type: Fix - id: 5783 - time: '2024-01-25T00:48:58.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24476 -- author: Krunk - changes: - - message: Paper cups can now be worn as party hats! - type: Add - id: 5784 - time: '2024-01-25T01:02:33.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24334 -- author: Blackern5000 - changes: - - message: Botany's hatchet, spade, and hoe have received a damage decrease to 10, - 10, and 6 damage respectively. - type: Tweak - id: 5785 - time: '2024-01-25T01:37:11.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24481 -- author: Minty642 - changes: - - message: Fixed Reinforced Glass Recipe in Ore Processor! - type: Fix - - message: Added Premium Material that can only be processed by Industrial Ore Processor! - type: Add - id: 5786 - time: '2024-01-25T08:33:56.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24345 -- author: Blackern5000 - changes: - - message: Smoking now causes mild lung cancer in the form of cellular damage. - type: Tweak - id: 5787 - time: '2024-01-25T09:51:26.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24546 -- author: metalgearsloth - changes: - - message: Add title2.ogg to space ambience tracks. - type: Tweak - id: 5788 - time: '2024-01-25T13:59:49.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24501 -- author: Tayrtahn - changes: - - message: Glued mobs can no longer struggle free from their captor's hands. - type: Tweak - id: 5789 - time: '2024-01-25T14:01:13.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24488 -- author: mirrorcult - changes: - - message: Atomic Amnesia MMX, Vibe Ace, Monument and Marhaba have been removed - as lobby music tracks - type: Remove - id: 5790 - time: '2024-01-25T14:08:29.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24480 -- author: Dutch-VanDerLinde - changes: - - message: To prevent accidental spills, paper cups can no longer be quick-equipped. - type: Fix - id: 5791 - time: '2024-01-25T22:04:31.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24560 -- author: Agoichi - changes: - - message: Bio hoods hiding your face now - type: Tweak - - message: Bio hoods now can be used as a breath mask - type: Tweak - - message: You can not eat while you wearing bio hood - type: Tweak - id: 5792 - time: '2024-01-26T00:13:42.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24570 -- author: yathxyz - changes: - - message: Updated nixpkgs input - type: Tweak - id: 5793 - time: '2024-01-26T01:40:52.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24572 -- author: mirrorcult - changes: - - message: We lied Atomic Amnesia MMX is back - type: Add - id: 5794 - time: '2024-01-26T05:48:29.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24575 -- author: EmoGarbage404 - changes: - - message: Cigarettes no longer deal cellular damage when smoked. - type: Remove - id: 5795 - time: '2024-01-26T09:50:03.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24568 - author: ERORR404V1 changes: - message: Added mime hardsuit @@ -3794,3 +3533,280 @@ id: 6260 time: '2024-03-30T06:52:27.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/25886 +- author: Flareguy + changes: + - message: Removed SCAF armor. + type: Remove + id: 6261 + time: '2024-03-31T02:01:28.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/26566 +- author: lzk228 + changes: + - message: Syndicate duffelbag storage increased from 8x5 to 9x5. + type: Tweak + id: 6262 + time: '2024-03-31T02:21:31.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/26565 +- author: Velcroboy + changes: + - message: Changed plastic flaps to be completely constructable/deconstructable + type: Tweak + id: 6263 + time: '2024-03-31T02:24:39.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/26341 +- author: Flareguy + changes: + - message: Security glasses have been moved from research to roundstart gear. All + officers now start with them instead of sunglasses by default. + type: Tweak + - message: You can now craft security glasses. + type: Add + id: 6264 + time: '2024-03-31T03:00:45.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/26487 +- author: brainfood1183 + changes: + - message: Toilets can now be connected to the disposal system. + type: Add + id: 6265 + time: '2024-03-31T03:21:18.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/22133 +- author: DrMelon + changes: + - message: Syndicate Uplinks now have a searchbar to help those dirty, rotten antagonists + find appropriate equipment more easily! + type: Tweak + id: 6266 + time: '2024-03-31T04:09:15.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/24287 +- author: chromiumboy + changes: + - message: Additional construction options have been added to the Rapid Construction + Device (RCD), along with a radial style UI for fast navigation + type: Add + - message: The number of charges and the length of time required to build a structure + with the RCD now vary depending on the complexity of the constructed fixture + type: Tweak + id: 6267 + time: '2024-03-31T04:29:47.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/22799 +- author: UBlueberry + changes: + - message: Nanotransen is now recruitin' personnel that speak with a Southern drawl. + type: Add + id: 6268 + time: '2024-03-31T04:39:40.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/26543 +- author: Tayrtahn + changes: + - message: You can no longer drink out of or put liquids into buckets worn on your + head. + type: Fix + id: 6269 + time: '2024-03-31T04:40:22.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/24412 +- author: DrTeaspoon + changes: + - message: Hypopen no longer shows chemical contents when examined, when not held + by the examinee. + type: Fix + id: 6270 + time: '2024-03-31T04:59:36.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/26453 +- author: lzk228 + changes: + - message: Hairflower was removed. + type: Remove + - message: Now you can wear poppy (and other flowers) on your head instead of crafting + hairflower with it. + type: Tweak + id: 6271 + time: '2024-03-31T05:33:23.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/25475 +- author: EmoGarbage404 + changes: + - message: Borgs, Emitters, and APEs can no longer have their panels opened while + locked. APEs and Emitters additionally cannot be unanchored either. + type: Add + id: 6272 + time: '2024-03-31T06:34:17.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/26600 +- author: lzk228 + changes: + - message: Flower crown and wreath were combined. Now you can wear wreath both on + head and on neck. + type: Tweak + id: 6273 + time: '2024-03-31T08:52:52.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/26605 +- author: Ubaser + changes: + - message: Throwing knives now additionally do armour piercing damage. + type: Tweak + id: 6274 + time: '2024-03-31T11:48:36.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/26380 +- author: graevy + changes: + - message: clicking the brig timer button will now cancel its countdown + type: Tweak + id: 6275 + time: '2024-03-31T20:44:02.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/26557 +- author: lzk228 + changes: + - message: Briefcases was added to CuraDrobe and LawDrobe. + type: Tweak + id: 6276 + time: '2024-03-31T20:52:49.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/26527 +- author: RiceMar + changes: + - message: Added milk cartons to the BoozeOMat vendor. Got milk? + type: Add + id: 6277 + time: '2024-04-01T00:07:30.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/26635 +- author: nikthechampiongr + changes: + - message: Radio jammers now actually block suit sensors. + type: Fix + id: 6278 + time: '2024-04-01T02:13:52.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/26632 +- author: Flareguy + changes: + - message: All wheeled objects now have lower friction. Portable items, like fuel + canisters & portable scrubbers, should now be easier to carry around. + type: Tweak + - message: High-capacity reagent tanks are now much heavier. + type: Tweak + id: 6279 + time: '2024-04-01T03:23:59.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/26601 +- author: Tayrtahn + changes: + - message: spears, darts, and hypodarts can inject targets again. + type: Fix + - message: arrows can no longer inject targets they don't actually hit. + type: Fix + id: 6280 + time: '2024-04-01T03:39:35.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/26268 +- author: SoulFN + changes: + - message: Changed textures of the assault borg modules + type: Tweak + id: 6281 + time: '2024-04-01T04:21:12.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/26502 +- author: Keer-Sar + changes: + - message: Cyborgs now have audio for some emotes. + type: Add + id: 6282 + time: '2024-04-01T04:35:21.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/26594 +- author: SlamBamActionman + changes: + - message: Added Coordinates Disks to the Salvage expeditions console, which are + now a requirement for expedition FTL. + type: Add + id: 6283 + time: '2024-04-01T04:50:00.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/23240 +- author: kseandi + changes: + - message: NT has declassified the documentation for door electronics, now anyone + can configure its access using network configurator or multitool. + type: Add + id: 6284 + time: '2024-04-01T06:06:14.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/17778 +- author: musicmanvr + changes: + - message: Added Sol Dry, 8 new cocktails and coconut water. + type: Add + id: 6285 + time: '2024-04-01T06:41:14.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/25367 +- author: f0x-n3rd + changes: + - message: Added pages for each categories from the chemical page in the guidebook, + no more infinite scrolling when looking up certain chemicals. + type: Add + id: 6286 + time: '2024-04-01T07:20:38.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/25831 +- author: TheShuEd + changes: + - message: Added new transformation particles types for APE and CHIMP + type: Add + - message: Added new anomaly behaviour mechanic. Different behaviors can change + the gameplay of an anomaly. Players can get random behaviors by bombarding the + anomaly with new particles + type: Add + id: 6287 + time: '2024-04-01T08:29:13.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/24683 +- author: Sk1tch + changes: + - message: Added chat window opacity slider to options. + type: Add + id: 6288 + time: '2024-04-01T20:48:02.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/24990 +- author: TheShuEd + changes: + - message: added procedurally generating books to library. + type: Add + - message: full books resprite + type: Add + id: 6289 + time: '2024-04-01T21:00:10.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/25840 +- author: osjarw + changes: + - message: Ambuzol plus pills now have different sprites from ambuzol pills. Now + CBURN agents and Nukies who bought the syndicate zombie bundle might realize + that they also have some ambuzol plus. + type: Tweak + id: 6290 + time: '2024-04-02T00:50:43.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/26651 +- author: osjarw + changes: + - message: Air injectors finally have working indicator lights while enabled. + type: Fix + id: 6291 + time: '2024-04-02T05:17:26.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/26654 +- author: Simyon + changes: + - message: The hands of cyborgs are now explosion proof. Your beakers wont ever + break again! + type: Fix + id: 6292 + time: '2024-04-02T05:18:31.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/26515 +- author: lzk228 + changes: + - message: Typing indicator now can be shaded by shadows. + type: Tweak + id: 6293 + time: '2024-04-03T02:12:47.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/26678 +- author: EmoGarbage404 + changes: + - message: Increased time between pulses for various anomalies. + type: Tweak + id: 6294 + time: '2024-04-03T03:15:57.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/26677 +- author: Plykiya + changes: + - message: Dropped items are no longer rotated to world north. + type: Fix + id: 6295 + time: '2024-04-03T05:31:57.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/26662 diff --git a/Resources/Credits/GitHub.txt b/Resources/Credits/GitHub.txt index f918d9320f..f201c03630 100644 --- a/Resources/Credits/GitHub.txt +++ b/Resources/Credits/GitHub.txt @@ -1 +1 @@ -0x6273, 2013HORSEMEATSCANDAL, 20kdc, 21Melkuu, 4dplanner, 612git, 778b, Ablankmann, Acruid, actioninja, adamsong, Admiral-Obvious-001, Adrian16199, Aerocrux, Aexxie, africalimedrop, Agoichi, Ahion, AJCM-git, AjexRose, Alekshhh, AlexMorgan3817, AlexUmAndXGabriel08X, AlmondFlour, AlphaQwerty, Altoids1, amylizzle, ancientpower, ArchPigeon, Arendian, arimah, artak10t, Arteben, AruMoon, as334, AsikKEsel, asperger-sind, avghdev, AzzyIsNotHere, BananaFlambe, BasedUser, beck-thompson, BGare, BingoJohnson-zz, BismarckShuffle, Bixkitts, Blackern5000, Blazeror, Boaz1111, BobdaBiscuit, brainfood1183, Brandon-Huu, Bright0, brndd, BubblegumBlue, BYONDFuckery, c4llv07e, CakeQ, CaptainSqrBeard, Carbonhell, casperr04, CatTheSystem, Centronias, chairbender, Charlese2, Cheackraze, cheesePizza2, Chief-Engineer, chromiumboy, Chronophylos, clement-or, Clyybber, Cojoke-dot, ColdAutumnRain, collinlunn, ComicIronic, coolmankid12345, corentt, CrafterKolyan, crazybrain23, creadth, CrigCrag, Crotalus, CrudeWax, CrzyPotato, Cyberboss, d34d10cc, Daemon, daerSeebaer, dahnte, dakamakat, dakimasu, DamianX, DangerRevolution, daniel-cr, Darkenson, DawBla, dch-GH, Deahaka, DEATHB4DEFEAT, DeathCamel58, deathride58, DebugOk, Decappi, deepdarkdepths, deepy, Delete69, deltanedas, DerbyX, DmitriyMX, Doctor-Cpu, DoctorBeard, DogZeroX, dontbetank, Doru991, DoubleRiceEddiedd, DoutorWhite, DrMelon, DrSmugleaf, drteaspoon420, DTanxxx, DubiousDoggo, Duddino, Dutch-VanDerLinde, Easypoller, eclips_e, EdenTheLiznerd, EEASAS, Efruit, ElectroSR, elthundercloud, Emisse, EmoGarbage404, Endecc, enumerate0, eoineoineoin, ERORR404V1, Errant-4, estacaoespacialpirata, exincore, exp111, Fahasor, FairlySadPanda, ficcialfaint, Fildrance, FillerVK, Fishfish458, Flareguy, FluffiestFloof, FluidRock, FoLoKe, fooberticus, Fortune117, freeman2651, Fromoriss, FungiFellow, GalacticChimp, gbasood, Geekyhobo, Genkail, Git-Nivrak, github-actions[bot], gituhabu, GNF54, Golinth, GoodWheatley, Gotimanga, graevy, GreyMario, gusxyz, Gyrandola, h3half, Hanzdegloker, Hardly3D, harikattar, Hebiman, Henry12116, HerCoyote23, Hmeister-real, HoofedEar, hord-brayden, hubismal, Hugal31, Hyenh, iacore, IamVelcroboy, icekot8, igorsaux, ike709, Illiux, Ilya246, IlyaElDunaev, Injazz, Insineer, IntegerTempest, Interrobang01, IProduceWidgets, ItsMeThom, j-giebel, Jackal298, Jackrost, jamessimo, janekvap, JerryImMouse, Jessetriesagain, jessicamaybe, Jezithyr, jicksaw, JiimBob, JoeHammad1844, joelhed, JohnGinnane, johnku1, joshepvodka, jproads, Jrpl, juliangiebel, JustArt1m, JustCone14, JustinTether, JustinTrotter, Kadeo64, KaiShibaa, kalane15, kalanosh, KEEYNy, Keikiru, Kelrak, kerisargit, keronshb, KIBORG04, Killerqu00, KingFroozy, kira-er, Kit0vras, KittenColony, Kmc2000, Ko4ergaPunk, komunre, koteq, Krunklehorn, Kukutis96513, kxvvv, Lamrr, LankLTE, lapatison, Leander-0, LetterN, Level10Cybermancer, lever1209, LightVillet, liltenhead, LittleBuilderJane, Lomcastar, LordCarve, LordEclipse, luckyshotpictures, LudwigVonChesterfield, Lukasz825700516, lunarcomets, luringens, lvvova1, lzimann, lzk228, M3739, MACMAN2003, Macoron, MagnusCrowe, ManelNavola, Mangohydra, matthst, Matz05, MehimoNemo, MeltedPixel, MemeProof, Menshin, Mervill, metalgearsloth, mhamsterr, MilenVolf, Minty642, Mirino97, mirrorcult, MishaUnity, MisterMecky, Mith-randalf, MjrLandWhale, Moneyl, Moomoobeef, moony, Morb0, Mr0maks, musicmanvr, Myakot, Myctai, N3X15, Nails-n-Tape, Nairodian, Naive817, NakataRin, namespace-Memory, NickPowers43, nikthechampiongr, Nimfar11, Nirnael, nmajask, nok-ko, Nopey, notafet, notquitehadouken, noudoit, noverd, nuke-haus, NULL882, Nylux, OctoRocket, OldDanceJacket, OliverOtter, onoira, Owai-Seek, pali6, Pangogie, patrikturi, PaulRitter, Peptide90, peptron1, Phantom-Lily, Phill101, PixelTheKermit, PJB3005, Plykiya, pofitlo, pointer-to-null, PolterTzi, PoorMansDreams, potato1234x, PotentiallyTom, ProfanedBane, ProPandaBear, PrPleGoo, ps3moira, Psychpsyo, psykzz, PuroSlavKing, PursuitInAshes, Putnam3145, quatre, QuietlyWhisper, qwerltaz, Radosvik, Radrark, Rainbeon, Rainfey, Rane, Ranger6012, ravage123321, rbertoche, Redict, RedlineTriad, RednoWCirabrab, RemberBM, RemieRichards, RemTim, rene-descartes2021, renodubois, RiceMar1244, RieBi, RIKELOLDABOSS, Rinkashikachi, Rockdtben, rolfero, rosieposieeee, Saakra, Samsterious, SamV522, SaphireLattice, ScalyChimp, scrato, Scribbles0, ScumbagDog, Serkket, SethLafuente, ShadowCommander, Shadowtheprotogen546, shampunj, SignalWalker, Simyon264, SirDragooon, Sirionaut, siyengar04, Skarletto, Skrauz, Skyedra, SlamBamActionman, Slava0135, snebl, Snowni, snowsignal, SonicHDC, SoulSloth, SpaceManiac, SpeltIncorrectyl, SphiraI, spoogemonster, ssdaniel24, Stanislav4ix, Stealthbomber16, StrawberryMoses, Subversionary, SweptWasTaken, Szunti, takemysoult, TaralGit, Tayrtahn, tday93, TekuNut, TemporalOroboros, tentekal, tgrkzus, thatrandomcanadianguy, TheArturZh, theashtronaut, thedraccx, themias, Theomund, theOperand, TheShuEd, TimrodDX, Titian3, tkdrg, tmtmtl30, tom-leys, tomasalves8, Tomeno, tosatur, TsjipTsjip, Tunguso4ka, TurboTrackerss14, Tyler-IN, Tyzemol, UbaserB, UKNOWH, Uriende, UristMcDorf, Vaaankas, Varen, VasilisThePikachu, veliebm, Veritius, Verslebas, VigersRay, Visne, volundr-, Vordenburg, vulppine, wafehling, waylon531, weaversam8, Willhelm53, wixoaGit, WlarusFromDaSpace, wrexbe, xRiriq, yathxyz, Ygg01, YotaXP, youarereadingthis, YuriyKiss, zach-hill, Zandario, Zap527, ZelteHonor, zerorulez, zionnBE, zlodo, ZNixian, ZoldorfTheWizard, Zumorica, Zymem +0x6273, 2013HORSEMEATSCANDAL, 20kdc, 21Melkuu, 4dplanner, 612git, 778b, Ablankmann, Acruid, actioninja, adamsong, Admiral-Obvious-001, Adrian16199, Aerocrux, Aexxie, africalimedrop, Agoichi, Ahion, AJCM-git, AjexRose, Alekshhh, AlexMorgan3817, AlexUmAndXGabriel08X, AlmondFlour, AlphaQwerty, Altoids1, amylizzle, ancientpower, ArchPigeon, Arendian, arimah, Arteben, AruMoon, as334, AsikKEsel, asperger-sind, avghdev, AzzyIsNotHere, BananaFlambe, Baptr0b0t, BasedUser, beck-thompson, BGare, BingoJohnson-zz, BismarckShuffle, Bixkitts, Blackern5000, Blazeror, Boaz1111, BobdaBiscuit, brainfood1183, Brandon-Huu, Bright0, brndd, BubblegumBlue, BYONDFuckery, c4llv07e, CakeQ, Callmore, CaptainSqrBeard, Carbonhell, casperr04, CatTheSystem, Centronias, chairbender, Charlese2, Cheackraze, cheesePizza2, Chief-Engineer, chromiumboy, Chronophylos, clement-or, Clyybber, Cojoke-dot, ColdAutumnRain, collinlunn, ComicIronic, coolmankid12345, corentt, CrafterKolyan, crazybrain23, creadth, CrigCrag, Crotalus, CrudeWax, CrzyPotato, Cyberboss, d34d10cc, Daemon, daerSeebaer, dahnte, dakamakat, dakimasu, DamianX, DangerRevolution, daniel-cr, Darkenson, DawBla, dch-GH, Deahaka, DEATHB4DEFEAT, DeathCamel58, deathride58, DebugOk, Decappi, deepdarkdepths, deepy, Delete69, deltanedas, DerbyX, DmitriyMX, Doctor-Cpu, DoctorBeard, DogZeroX, dontbetank, Doru991, DoubleRiceEddiedd, DoutorWhite, DrMelon, DrSmugleaf, drteaspoon420, DTanxxx, DubiousDoggo, Duddino, Dutch-VanDerLinde, Easypoller, eclips_e, EdenTheLiznerd, EEASAS, Efruit, ElectroSR, elthundercloud, Emisse, EmoGarbage404, Endecc, enumerate0, eoineoineoin, ERORR404V1, Errant-4, estacaoespacialpirata, exincore, exp111, Fahasor, FairlySadPanda, ficcialfaint, Fildrance, FillerVK, Fishfish458, Flareguy, FluffiestFloof, FluidRock, FoLoKe, fooberticus, Fortune117, freeman2651, Fromoriss, FungiFellow, GalacticChimp, gbasood, Geekyhobo, Genkail, Ghagliiarghii, Git-Nivrak, github-actions[bot], gituhabu, GNF54, Golinth, GoodWheatley, Gotimanga, graevy, GreyMario, gusxyz, Gyrandola, h3half, Hanzdegloker, Hardly3D, harikattar, Hebiman, Henry12116, HerCoyote23, Hmeister-real, HoofedEar, hord-brayden, hubismal, Hugal31, Huxellberger, Hyenh, iacore, IamVelcroboy, icekot8, igorsaux, ike709, Illiux, Ilya246, IlyaElDunaev, Injazz, Insineer, IntegerTempest, Interrobang01, IProduceWidgets, ItsMeThom, j-giebel, Jackal298, Jackrost, jamessimo, janekvap, JerryImMouse, Jessetriesagain, jessicamaybe, Jezithyr, jicksaw, JiimBob, JoeHammad1844, joelhed, JohnGinnane, johnku1, joshepvodka, jproads, Jrpl, juliangiebel, JustArt1m, JustCone14, JustinTether, JustinTrotter, Kadeo64, KaiShibaa, kalane15, kalanosh, KEEYNy, Keikiru, Kelrak, kerisargit, keronshb, KIBORG04, Killerqu00, KingFroozy, kira-er, Kit0vras, KittenColony, Kmc2000, Ko4ergaPunk, komunre, koteq, Krunklehorn, Kukutis96513, kxvvv, Lamrr, LankLTE, lapatison, Leander-0, LetterN, Level10Cybermancer, lever1209, LightVillet, liltenhead, LittleBuilderJane, Lomcastar, LordCarve, LordEclipse, luckyshotpictures, LudwigVonChesterfield, Lukasz825700516, lunarcomets, luringens, lvvova1, lzimann, lzk228, M3739, MACMAN2003, Macoron, MagnusCrowe, ManelNavola, Mangohydra, matthst, Matz05, MehimoNemo, MeltedPixel, MemeProof, Menshin, Mervill, metalgearsloth, mhamsterr, MilenVolf, Minty642, Mirino97, mirrorcult, MishaUnity, MisterMecky, Mith-randalf, MjrLandWhale, Moneyl, Moomoobeef, moony, Morb0, Mr0maks, musicmanvr, Myakot, Myctai, N3X15, Nails-n-Tape, Nairodian, Naive817, NakataRin, namespace-Memory, NickPowers43, nikthechampiongr, Nimfar11, Nirnael, nmajask, nok-ko, Nopey, notafet, notquitehadouken, noudoit, noverd, nuke-haus, NULL882, Nylux, OctoRocket, OldDanceJacket, OliverOtter, onoira, Owai-Seek, pali6, Pangogie, patrikturi, PaulRitter, Peptide90, peptron1, Phantom-Lily, Phill101, PixelTheKermit, PJB3005, Plykiya, pofitlo, pointer-to-null, PolterTzi, PoorMansDreams, potato1234x, PotentiallyTom, ProfanedBane, ProPandaBear, PrPleGoo, ps3moira, Psychpsyo, psykzz, PuroSlavKing, PursuitInAshes, Putnam3145, quatre, QuietlyWhisper, qwerltaz, Radosvik, Radrark, Rainbeon, Rainfey, Rane, Ranger6012, ravage123321, rbertoche, Redict, RedlineTriad, RednoWCirabrab, RemberBM, RemieRichards, RemTim, rene-descartes2021, renodubois, RiceMar1244, RieBi, RIKELOLDABOSS, Rinkashikachi, Rockdtben, rolfero, rosieposieeee, Saakra, Samsterious, SaphireLattice, ScalyChimp, scrato, Scribbles0, Serkket, SethLafuente, ShadowCommander, Shadowtheprotogen546, shampunj, SignalWalker, Simyon264, SirDragooon, Sirionaut, siyengar04, Skarletto, Skrauz, Skyedra, SlamBamActionman, Slava0135, snebl, Snowni, snowsignal, SonicHDC, SoulSloth, SpaceManiac, SpeltIncorrectyl, SphiraI, spoogemonster, ssdaniel24, Stealthbomber16, StrawberryMoses, Subversionary, SweptWasTaken, Szunti, takemysoult, TaralGit, Tayrtahn, tday93, TekuNut, TemporalOroboros, tentekal, tgrkzus, thatrandomcanadianguy, TheArturZh, theashtronaut, thedraccx, themias, Theomund, theOperand, TheShuEd, TimrodDX, Titian3, tkdrg, tmtmtl30, tom-leys, tomasalves8, Tomeno, tosatur, TsjipTsjip, Tunguso4ka, TurboTrackerss14, Tyler-IN, Tyzemol, UbaserB, UKNOWH, Uriende, UristMcDorf, Vaaankas, Varen, VasilisThePikachu, veliebm, Veritius, Vermidia, Verslebas, VigersRay, Visne, volundr-, Vordenburg, vulppine, wafehling, waylon531, weaversam8, Willhelm53, wixoaGit, WlarusFromDaSpace, wrexbe, xRiriq, yathxyz, Ygg01, YotaXP, YuriyKiss, zach-hill, Zandario, Zap527, ZelteHonor, zerorulez, zionnBE, zlodo, ZNixian, ZoldorfTheWizard, Zumorica, Zymem diff --git a/Resources/Credits/Patrons.yml b/Resources/Credits/Patrons.yml index 193caa7350..f7e8df9bc0 100644 --- a/Resources/Credits/Patrons.yml +++ b/Resources/Credits/Patrons.yml @@ -1,13 +1,9 @@ -- Name: "Tomeno" - Tier: Revolutionary - Name: "Daniel Thompson" Tier: Revolutionary - Name: "Farewell Fire" Tier: Syndicate Agent - Name: "CPM311" Tier: Revolutionary -- Name: "Bobberunio" - Tier: Revolutionary - Name: "vifs_vestige" Tier: Syndicate Agent - Name: "Anthony Fleck" @@ -30,8 +26,6 @@ Tier: Revolutionary - Name: "clyf" Tier: Nuclear Operative -- Name: "spinnermaster" - Tier: Syndicate Agent - Name: "Will M." Tier: Revolutionary - Name: "The Hateful Flesh" @@ -78,8 +72,6 @@ Tier: Syndicate Agent - Name: "Saphire" Tier: Revolutionary -- Name: "DubzyVEVO" - Tier: Revolutionary - Name: "Never Solus" Tier: Syndicate Agent - Name: "Gnomo" @@ -100,8 +92,6 @@ Tier: Revolutionary - Name: "tokie" Tier: Nuclear Operative -- Name: "BlueisDumb" - Tier: Nuclear Operative - Name: "Enricoc3l" Tier: Revolutionary - Name: "DadNotTheBelt" @@ -138,14 +128,10 @@ Tier: Revolutionary - Name: "Adam Smedstad" Tier: Revolutionary -- Name: "oBerry" - Tier: Nuclear Operative - Name: "DireBoar" Tier: Revolutionary - Name: "Ignoramis" Tier: Revolutionary -- Name: "Repo" - Tier: Nuclear Operative - Name: "612" Tier: Revolutionary - Name: "Higgtastic" @@ -208,8 +194,6 @@ Tier: Revolutionary - Name: "Georgia Partyka" Tier: Syndicate Agent -- Name: "YuNii" - Tier: Syndicate Agent - Name: "Nojan Niaki" Tier: Revolutionary - Name: "nokko" @@ -284,5 +268,23 @@ Tier: Revolutionary - Name: "Black Rose" Tier: Revolutionary -- Name: "Dourbii" +- Name: "Kim" + Tier: Nuclear Operative +- Name: "Kyu, The Meme Fairy" + Tier: Syndicate Agent +- Name: "Russian TS" + Tier: Nuclear Operative +- Name: "Andrew" + Tier: Revolutionary +- Name: "Jack" + Tier: Syndicate Agent +- Name: "Brandon Roughley" + Tier: Syndicate Agent +- Name: "Sean Lilly" + Tier: Syndicate Agent +- Name: "Dieselmohawk D." + Tier: Revolutionary +- Name: "Hannah Dawson" + Tier: Syndicate Agent +- Name: "Godfiend" Tier: Revolutionary diff --git a/Resources/Locale/en-US/accent/southern.ftl b/Resources/Locale/en-US/accent/southern.ftl new file mode 100644 index 0000000000..7e1657a3ed --- /dev/null +++ b/Resources/Locale/en-US/accent/southern.ftl @@ -0,0 +1,17 @@ +accent-southern-words-1 = you all +accent-southern-words-replace-1 = y'all + +accent-southern-words-2 = you guys +accent-southern-words-replace-2 = y'all + +accent-southern-words-3 = isn't +accent-southern-words-replace-3 = ain't + +accent-southern-words-4 = is not +accent-southern-words-replace-4 = ain't + +accent-southern-words-5 = aren't +accent-southern-words-replace-5 = ain't + +accent-southern-words-6 = are not +accent-southern-words-replace-6 = ain't diff --git a/Resources/Locale/en-US/administration/commands/aghost.ftl b/Resources/Locale/en-US/administration/commands/aghost.ftl new file mode 100644 index 0000000000..4de0639981 --- /dev/null +++ b/Resources/Locale/en-US/administration/commands/aghost.ftl @@ -0,0 +1,3 @@ +aghost-description = Makes you an admin ghost. +aghost-no-mind-self = You can't ghost here! +aghost-no-mind-other = They can't ghost here! diff --git a/Resources/Locale/en-US/anomaly/anomaly.ftl b/Resources/Locale/en-US/anomaly/anomaly.ftl index 3a398d482e..da5882fa62 100644 --- a/Resources/Locale/en-US/anomaly/anomaly.ftl +++ b/Resources/Locale/en-US/anomaly/anomaly.ftl @@ -8,20 +8,29 @@ anomaly-particles-delta = Delta particles anomaly-particles-epsilon = Epsilon particles anomaly-particles-zeta = Zeta particles anomaly-particles-omega = Omega particles +anomaly-particles-sigma = Sigma particles anomaly-scanner-component-scan-complete = Scan complete! anomaly-scanner-ui-title = anomaly scanner anomaly-scanner-no-anomaly = No anomaly currently scanned. anomaly-scanner-severity-percentage = Current severity: [color=gray]{$percent}[/color] +anomaly-scanner-severity-percentage-unknown = Current severity: [color=red]ERROR[/color] anomaly-scanner-stability-low = Current anomaly state: [color=gold]Decaying[/color] anomaly-scanner-stability-medium = Current anomaly state: [color=forestgreen]Stable[/color] anomaly-scanner-stability-high = Current anomaly state: [color=crimson]Growing[/color] +anomaly-scanner-stability-unknown = Current anomaly state: [color=red]ERROR[/color] anomaly-scanner-point-output = Point output: [color=gray]{$point}[/color] +anomaly-scanner-point-output-unknown = Point output: [color=red]ERROR[/color] anomaly-scanner-particle-readout = Particle Reaction Analysis: anomaly-scanner-particle-danger = - [color=crimson]Danger type:[/color] {$type} anomaly-scanner-particle-unstable = - [color=plum]Unstable type:[/color] {$type} anomaly-scanner-particle-containment = - [color=goldenrod]Containment type:[/color] {$type} +anomaly-scanner-particle-transformation = - [color=#6b75fa]Transformation type:[/color] {$type} +anomaly-scanner-particle-danger-unknown = - [color=crimson]Danger type:[/color] [color=red]ERROR[/color] +anomaly-scanner-particle-unstable-unknown = - [color=plum]Unstable type:[/color] [color=red]ERROR[/color] +anomaly-scanner-particle-containment-unknown = - [color=goldenrod]Containment type:[/color] [color=red]ERROR[/color] +anomaly-scanner-particle-transformation-unknown = - [color=#6b75fa]Transformation type:[/color] [color=red]ERROR[/color] anomaly-scanner-pulse-timer = Time until next pulse: [color=gray]{$time}[/color] anomaly-gorilla-core-slot-name = Anomaly core @@ -65,3 +74,23 @@ anomaly-command-supercritical = Makes a target anomaly go supercritical # Flavor text on the footer anomaly-generator-flavor-left = Anomaly may spawn inside the operator. anomaly-generator-flavor-right = v1.1 + +anomaly-behavior-unknown = [color=red]ERROR. Cannot be read.[/color] + +anomaly-behavior-title = behavior deviation analysis: +anomaly-behavior-point =[color=gold]Anomaly produces {$mod}% of the points[/color] + +anomaly-behavior-safe = [color=forestgreen]The anomaly is extremely stable. Extremely rare pulsations.[/color] +anomaly-behavior-slow = [color=forestgreen]The frequency of pulsations is much less frequent.[/color] +anomaly-behavior-light = [color=forestgreen]Pulsation power is significantly reduced.[/color] +anomaly-behavior-balanced = No behavior deviations detected. +anomaly-behavior-delayed-force = The frequency of pulsations is greatly reduced, but their power is increased. +anomaly-behavior-rapid = The frequency of the pulsation is much higher, but its strength is attenuated. +anomaly-behavior-reflect = A protective coating was detected. +anomaly-behavior-nonsensivity = A weak reaction to particles was detected. +anomaly-behavior-sensivity = Amplified reaction to particles was detected. +anomaly-behavior-secret = Interference detected. Some data cannot be read +anomaly-behavior-inconstancy = [color=crimson]Impermanence has been detected. Particle types can change over time.[/color] +anomaly-behavior-fast = [color=crimson]The pulsation frequency is strongly increased.[/color] +anomaly-behavior-strenght = [color=crimson]The pulsation power is significantly increased.[/color] +anomaly-behavior-moving = [color=crimson]Coordinate instability was detected.[/color] \ No newline at end of file diff --git a/Resources/Locale/en-US/chemistry/components/scoopable-component.ftl b/Resources/Locale/en-US/chemistry/components/scoopable-component.ftl new file mode 100644 index 0000000000..c2593cc61e --- /dev/null +++ b/Resources/Locale/en-US/chemistry/components/scoopable-component.ftl @@ -0,0 +1 @@ +scoopable-component-popup = You scoop up {$scooped} into {THE($beaker)}. diff --git a/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl b/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl index ff56d54274..67d09c9012 100644 --- a/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl +++ b/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl @@ -48,6 +48,8 @@ ui-options-fancy-name-background = Add background to speech bubble names ui-options-enable-color-name = Add colors to character names ui-options-colorblind-friendly = Colorblind friendly mode ui-options-reduced-motion = Reduce motion of visual effects +ui-options-chat-window-opacity = Chat window opacity +ui-options-chat-window-opacity-percent = { TOSTRING($opacity, "P0") } ui-options-screen-shake-intensity = Screen shake intensity ui-options-screen-shake-percent = { TOSTRING($intensity, "P0") } ui-options-vsync = VSync diff --git a/Resources/Locale/en-US/flavors/flavor-profiles.ftl b/Resources/Locale/en-US/flavors/flavor-profiles.ftl index 35de5555a2..61567d8695 100644 --- a/Resources/Locale/en-US/flavors/flavor-profiles.ftl +++ b/Resources/Locale/en-US/flavors/flavor-profiles.ftl @@ -188,6 +188,7 @@ flavor-complex-tonic-water = like angry water flavor-complex-cola = like cola flavor-complex-energy-drink = like battery acid flavor-complex-dr-gibb = like malpractice +flavor-complex-ginger-soda = like ginger flavor-complex-grape-soda = like grape soda flavor-complex-lemon-lime-soda = like lemon-lime soda flavor-complex-pwr-game-soda = like gaming @@ -200,6 +201,7 @@ flavor-complex-vodka = like fermented grain flavor-complex-tequila = like fermented death flavor-complex-sake = like sweet, alcoholic rice flavor-complex-rum = like fermented sugar +flavor-complex-coconut-rum = like nutty fermented sugar flavor-complex-coffee-liquor = like strong, bitter coffee flavor-complex-whiskey = like molasses flavor-complex-shitty-wine = like grape rinds @@ -212,6 +214,11 @@ flavor-complex-ice = like ice flavor-complex-mopwata = like stagnant, dirty water ## Cocktails +flavor-complex-arnold-palmer = like a hole-in-one +flavor-complex-blue-hawaiian = like the tropics +flavor-complex-cosmopolitan = sweet and tangy +flavor-complex-painkiller = like spiked pineapple juice +flavor-complex-pina-colada = like tropical sun flavor-complex-long-island = suspiciously like iced tea flavor-complex-three-mile-island = like tea brewed in nuclear runoff flavor-complex-whiskey-cola = like carbonated molasses diff --git a/Resources/Locale/en-US/ghost/roles/ghost-role-component.ftl b/Resources/Locale/en-US/ghost/roles/ghost-role-component.ftl index d8c88f3c34..23a178d282 100644 --- a/Resources/Locale/en-US/ghost/roles/ghost-role-component.ftl +++ b/Resources/Locale/en-US/ghost/roles/ghost-role-component.ftl @@ -164,6 +164,9 @@ ghost-role-information-cerberus-rules = You are an intelligent, demonic dog. Try ghost-role-information-ert-leader-name = ERT Leader ghost-role-information-ert-leader-description = Lead a team of specialists to resolve the station's issues. +ghost-role-information-ert-chaplain-name = ERT Chaplain +ghost-role-information-ert-chaplain-description = Assist with mourning to resolve the station's crew moral issues. + ghost-role-information-ert-janitor-name = ERT Janitor ghost-role-information-ert-janitor-description = Assist with custodial efforts to resolve the station's issues. diff --git a/Resources/Locale/en-US/guidebook/guides.ftl b/Resources/Locale/en-US/guidebook/guides.ftl index c30b49553c..496e38b9a0 100644 --- a/Resources/Locale/en-US/guidebook/guides.ftl +++ b/Resources/Locale/en-US/guidebook/guides.ftl @@ -22,6 +22,14 @@ guide-entry-cargo-bounties = Cargo Bounties guide-entry-salvage = Salvage guide-entry-survival = Survival guide-entry-chemicals = Chemicals +guide-entry-elements = Elements +guide-entry-narcotics = Narcotics +guide-entry-pyrotechnics = Pyrotechnic +guide-entry-toxins = Toxins +guide-entry-foods = Foods +guide-entry-biological = Biological +guide-entry-others = Others +guide-entry-botanical = Botanicals guide-entry-ss14 = Space Station 14 guide-entry-janitorial = Janitorial guide-entry-bartender = Bartender diff --git a/Resources/Locale/en-US/job/job-description.ftl b/Resources/Locale/en-US/job/job-description.ftl index c9d53bb5b5..e8db804688 100644 --- a/Resources/Locale/en-US/job/job-description.ftl +++ b/Resources/Locale/en-US/job/job-description.ftl @@ -19,6 +19,7 @@ job-description-paramedic = Rescue critically injured patients all over the stat job-description-detective = Investigate crime scenes using forensic tools, ensure that the guilty party is found, and have a couple smokes. job-description-doctor = Diagnose and heal crewmembers through medicinal chemicals, advanced medicine, and defibrillators. Make sure the dead don't rot, and that cadavers are in the morgue. job-description-engineer = Keep the station's main engine & solars active, optimize the power network, and make emergency repairs using your hardsuit in spaced areas. +job-description-ertchaplain = Ensure the station crew's last rights are taken care of. job-description-ertengineer = Ensure that the station has power and clean air. job-description-ertjanitor = Ensure that the station is properly cleaned--for morale. job-description-ertleader = Lead the Emergency Response Team in dealing with threats to Nanotrasen assets. diff --git a/Resources/Locale/en-US/job/job-names.ftl b/Resources/Locale/en-US/job/job-names.ftl index 8cd35cac88..51a81fb06a 100644 --- a/Resources/Locale/en-US/job/job-names.ftl +++ b/Resources/Locale/en-US/job/job-names.ftl @@ -38,6 +38,7 @@ job-name-cargotech = Cargo Technician job-name-chef = Chef job-name-clown = Clown job-name-ertleader = ERT Leader +job-name-ertchaplain = ERT Chaplain job-name-ertengineer = ERT Engineer job-name-ertsecurity = ERT Security job-name-ertmedic = ERT Medic @@ -63,6 +64,7 @@ JobChiefMedicalOfficer = Chief Medical Officer JobClown = Clown JobDetective = Detective JobBrigmedic = Brigmedic +JobERTChaplain = ERT Chaplain JobERTEngineer = ERT Engineer JobERTJanitor = ERT Janitor JobERTLeader = ERT Leader diff --git a/Resources/Locale/en-US/lock/lock-component.ftl b/Resources/Locale/en-US/lock/lock-component.ftl index f9f975c96e..380605697b 100644 --- a/Resources/Locale/en-US/lock/lock-component.ftl +++ b/Resources/Locale/en-US/lock/lock-component.ftl @@ -3,8 +3,9 @@ lock-comp-on-examined-is-unlocked = The {$entityName} seems to be unlocked. lock-comp-do-lock-success = You lock the {$entityName}. lock-comp-do-unlock-success = You unlock the {$entityName}. lock-comp-has-user-access-fail = Access denied +lock-comp-generic-fail = {CAPITALIZE(SUBJECT($target))} {CONJUGATE-BE($target)} locked. ## ToggleLockVerb toggle-lock-verb-unlock = Unlock -toggle-lock-verb-lock = Lock \ No newline at end of file +toggle-lock-verb-lock = Lock diff --git a/Resources/Locale/en-US/machine-linking/receiver_ports.ftl b/Resources/Locale/en-US/machine-linking/receiver_ports.ftl index 4d2dd25af2..dc45677c8d 100644 --- a/Resources/Locale/en-US/machine-linking/receiver_ports.ftl +++ b/Resources/Locale/en-US/machine-linking/receiver_ports.ftl @@ -70,6 +70,9 @@ signal-port-description-set-particle-epsilon = Sets the type of particle this de signal-port-name-set-particle-zeta = Set particle type: zeta signal-port-description-set-particle-zeta = Sets the type of particle this device emits to zeta. +signal-port-name-set-particle-sigma = Set particle type: sigma +signal-port-description-set-particle-sigma = Sets the type of particle this device emits to sigma. + signal-port-name-logic-input-a = Input A signal-port-description-logic-input-a = First input of a logic gate. diff --git a/Resources/Locale/en-US/paint/paint.ftl b/Resources/Locale/en-US/paint/paint.ftl deleted file mode 100644 index 200b1f6e3f..0000000000 --- a/Resources/Locale/en-US/paint/paint.ftl +++ /dev/null @@ -1,8 +0,0 @@ -paint-success = {THE($target)} has been covered in paint! -paint-failure = Can't cover {THE($target)} in paint! -paint-failure-painted = {THE($target)} is already covered in paint! -paint-empty = {THE($used)} is empty! -paint-removed = You clean off the paint! -paint-closed = You must open {THE($used)} first! -paint-verb = Paint -paint-remove-verb = Remove Paint diff --git a/Resources/Locale/en-US/paper/story-generation.ftl b/Resources/Locale/en-US/paper/story-generation.ftl new file mode 100644 index 0000000000..bcd1c8901e --- /dev/null +++ b/Resources/Locale/en-US/paper/story-generation.ftl @@ -0,0 +1,244 @@ +story-gen-book-type1 = book +story-gen-book-type2 = folio +story-gen-book-type3 = collection +story-gen-book-type4 = notes +story-gen-book-type5 = manuscript +story-gen-book-type6 = records +story-gen-book-type7 = tome +story-gen-book-type8 = journal +story-gen-book-type9 = archives +story-gen-book-type10= codex +story-gen-book-type11= memories +story-gen-book-type12= compendium + +story-gen-book-genre1 = work of crime fiction +story-gen-book-genre2 = comedy +story-gen-book-genre3 = horror story +story-gen-book-genre4 = poem +story-gen-book-genre5 = novella +story-gen-book-genre6 = chronicle +story-gen-book-genre7 = work of science-fiction +story-gen-book-genre8 = fantasy story +story-gen-book-genre9 = romance +story-gen-book-genre10= thriller +story-gen-book-genre11= work of historical fiction +story-gen-book-genre12= biography +story-gen-book-genre13= adventure story +story-gen-book-genre14= drama + +story-gen-book-appearance1 = ancient +story-gen-book-appearance2 = shabby +story-gen-book-appearance3 = dirty +story-gen-book-appearance4 = unusual +story-gen-book-appearance5 = faded +story-gen-book-appearance6 = nasty +story-gen-book-appearance7 = dusty +story-gen-book-appearance8 = scary +story-gen-book-appearance9 = bloody +story-gen-book-appearance10= bright +story-gen-book-appearance11= dubious +story-gen-book-appearance12= intriguing +story-gen-book-appearance13= ugly +story-gen-book-appearance14= crooked +story-gen-book-appearance15= crumpled +story-gen-book-appearance16= dirty +story-gen-book-appearance17= elegant +story-gen-book-appearance18= ornate +story-gen-book-appearance19= weathered +story-gen-book-appearance20= chrisp +story-gen-book-appearance21= lavish +story-gen-book-appearance22= tattered +story-gen-book-appearance23= polished +story-gen-book-appearance24= embossed +story-gen-book-appearance25= mismatched +story-gen-book-appearance26= gilded +story-gen-book-appearance27= strange + +story-gen-book-character1 = clown +story-gen-book-character2 = mime +story-gen-book-character3 = reporter +story-gen-book-character4 = butcher +story-gen-book-character5 = bartender +story-gen-book-character6 = janitor +story-gen-book-character7 = engineer +story-gen-book-character8 = scientist +story-gen-book-character9 = guard +story-gen-book-character10 = doctor +story-gen-book-character11 = chemist +story-gen-book-character12 = prisoner +story-gen-book-character13 = researcher +story-gen-book-character14 = trader +story-gen-book-character15 = captain +story-gen-book-character16 = lizard +story-gen-book-character17 = moth +story-gen-book-character18 = diona +story-gen-book-character19 = cat-girl +story-gen-book-character20 = cat +story-gen-book-character21 = corgi +story-gen-book-character22 = dog +story-gen-book-character23 = opossum +story-gen-book-character24 = sloth +story-gen-book-character25 = syndicate agent +story-gen-book-character26 = revenant +story-gen-book-character27 = rat king +story-gen-book-character28 = ninja +story-gen-book-character29 = space dragon +story-gen-book-character30 = revolutionary +story-gen-book-character31 = nuclear operative +story-gen-book-character32 = narsie cultist +story-gen-book-character33 = ratwar cultist +story-gen-book-character34 = greytider +story-gen-book-character35 = arachnid +story-gen-book-character36 = vox +story-gen-book-character37 = dwarf +story-gen-book-character38 = thief +story-gen-book-character39 = wizard +story-gen-book-character40 = slime + +story-gen-book-character-trait1 = stupid +story-gen-book-character-trait2 = smart +story-gen-book-character-trait3 = funny +story-gen-book-character-trait4 = attractive +story-gen-book-character-trait5 = charming +story-gen-book-character-trait6 = nasty +story-gen-book-character-trait7 = dying +story-gen-book-character-trait8 = old +story-gen-book-character-trait9 = young +story-gen-book-character-trait10 = rich +story-gen-book-character-trait11 = poor +story-gen-book-character-trait12 = popular +story-gen-book-character-trait13 = absent-minded +story-gen-book-character-trait14 = stern +story-gen-book-character-trait15 = сharismatic +story-gen-book-character-trait16 = stoic +story-gen-book-character-trait17 = cute +story-gen-book-character-trait18 = dwarven +story-gen-book-character-trait19 = beer-smelling +story-gen-book-character-trait20 = joyful +story-gen-book-character-trait21 = painfully beautiful +story-gen-book-character-trait22 = robotic +story-gen-book-character-trait23 = holographic +story-gen-book-character-trait24 = hysterically laughing + +story-gen-book-event1 = a zombie outbreak +story-gen-book-event2 = a nuclear explosion +story-gen-book-event3 = a mass murder +story-gen-book-event4 = a sudden depressurization +story-gen-book-event5 = a blackout +story-gen-book-event6 = the starvation of the protagonists +story-gen-book-event7 = a wasting illness +story-gen-book-event8 = love at first sight +story-gen-book-event9 = a rush of inspiration +story-gen-book-event10 = the occurrence of some mystical phenomena +story-gen-book-event11 = divine intervention +story-gen-book-event12 = the characters' own selfish motives +story-gen-book-event13 = an unforeseen deception +story-gen-book-event14 = the resurrection of one of these characters from the dead +story-gen-book-event15 = the terrible torture of the protagonist +story-gen-book-event16 = the inadvertent loosing of a gravitational singularity +story-gen-book-event17 = a psychic prediction of future events +story-gen-book-event18 = an antimatter explosion +story-gen-book-event19 = a chance meeting with a cat-girl +story-gen-book-event20 = drinking far too much alcohol +story-gen-book-event21 = eating way too much pizza +story-gen-book-event22 = having a quarrel with a close friend +story-gen-book-event23 = the sudden loss of their home in a fiery blaze +story-gen-book-event24 = the loss of a PDA + +story-gen-book-action1 = share in a kiss with a +story-gen-book-action2 = strangle to death a +story-gen-book-action3 = manage to blow apart a +story-gen-book-action4 = manage to win a game of chess against a +story-gen-book-action5 = narrowly lose a game of chess against a +story-gen-book-action6 = reveal the hidden secrets of a +story-gen-book-action7 = manipulate a +story-gen-book-action8 = sacrifice upon an altar a +story-gen-book-action9 = attend the wedding of a +story-gen-book-action10 = join forces to defeat their common enemy, a +story-gen-book-action11 = are forced to work together to escape a +story-gen-book-action12 = give a valuable gift to + +story-gen-book-action-trait1 = terribly +story-gen-book-action-trait2 = disgustingly +story-gen-book-action-trait3 = marvelously +story-gen-book-action-trait4 = nicely +story-gen-book-action-trait5 = weirdly +story-gen-book-action-trait6 = amusingly +story-gen-book-action-trait7 = fancifully +story-gen-book-action-trait8 = impressively +story-gen-book-action-trait9 = irresponsibly +story-gen-book-action-trait10 = severely +story-gen-book-action-trait11 = ruthlessly +story-gen-book-action-trait12 = playfully +story-gen-book-action-trait13 = thoughtfully + +story-gen-book-location1 = in an underground complex +story-gen-book-location2 = while on an expedition +story-gen-book-location3 = while trapped in outer space +story-gen-book-location4 = while in a news office +story-gen-book-location5 = in a hidden garden +story-gen-book-location6 = in the kitchen of a local restaurant +story-gen-book-location7 = under the counter of the local sports bar +story-gen-book-location8 = in an ancient library +story-gen-book-location9 = while deep in bowels of the space station's maintenance corridors +story-gen-book-location10 = on the bridge of a starship +story-gen-book-location11 = while in a grungy public bathroom +story-gen-book-location12 = while trapped inside a crate +story-gen-book-location13 = while stuck inside a locker +story-gen-book-location14 = while stationed on Barratry +story-gen-book-location15 = while in the hall of rustic church +story-gen-book-location16 = while in a crematorium +story-gen-book-location17 = standing too close to an anomaly +story-gen-book-location18 = while huddling on the evacuation shuttle +story-gen-book-location19 = standing in freshly fallen snow +story-gen-book-location20 = lost in the woods +story-gen-book-location21 = iin the harsh desert +story-gen-book-location22 = worrying about their social media networks +story-gen-book-location23 = atop of a mountain +story-gen-book-location24 = while driving a car +story-gen-book-location25 = in an escape pod +story-gen-book-location26 = while abroad in a fictional country +story-gen-book-location27 = clinging to the wing of an inflight airplane +story-gen-book-location28 = inside a pocket dimension +story-gen-book-location29 = onboard a Wizard Federation shuttle +story-gen-book-location30 = standing atop of a mountain of corpses +story-gen-book-location31 = while psychically projected into their subconscious +story-gen-book-location32 = while trapped in a shadow dimension +story-gen-book-location33 = while trying to escape a destroyed space station +story-gen-book-location34 = while sandwiched between a Tesla ball and a gravitational singularity + +story-gen-book-element1 = The plot +story-gen-book-element2 = The twist +story-gen-book-element3 = The climax +story-gen-book-element4 = The final act +story-gen-book-element5 = The ending +story-gen-book-element6 = The moral of the story +story-gen-book-element7 = The theme of this work +story-gen-book-element8 = The literary style +story-gen-book-element9 = The illustrations + +story-gen-book-element-trait1 = terrifying +story-gen-book-element-trait2 = disgusting +story-gen-book-element-trait3 = wonderful +story-gen-book-element-trait4 = cute +story-gen-book-element-trait5 = boring +story-gen-book-element-trait6 = strange +story-gen-book-element-trait7 = amusing +story-gen-book-element-trait8 = whimsical +story-gen-book-element-trait9 = impressive +story-gen-book-element-trait10 = interesting +story-gen-book-element-trait11 = inadequate +story-gen-book-element-trait12 = sad +story-gen-book-element-trait13 = rather depressing + + + + + + + + + + + + diff --git a/Resources/Locale/en-US/rcd/components/rcd-component.ftl b/Resources/Locale/en-US/rcd/components/rcd-component.ftl index b7920c9ede..bb65e76f3f 100644 --- a/Resources/Locale/en-US/rcd/components/rcd-component.ftl +++ b/Resources/Locale/en-US/rcd/components/rcd-component.ftl @@ -1,18 +1,66 @@ ### UI -# Shown when an RCD is examined in details range -rcd-component-examine-detail = It's currently on {$mode} mode. +rcd-component-examine-mode-details = It's currently set to '{$mode}' mode. +rcd-component-examine-build-details = It's currently set to build {MAKEPLURAL($name)}. + ### Interaction Messages -# Shown when changing RCD Mode -rcd-component-change-mode = The RCD is now set to {$mode} mode. +# Mode change +rcd-component-change-mode = The RCD is now set to '{$mode}' mode. +rcd-component-change-build-mode = The RCD is now set to build {MAKEPLURAL($name)}. -rcd-component-no-ammo-message = The RCD is out of ammo! -rcd-component-tile-obstructed-message = That tile is obstructed! -rcd-component-tile-indestructible-message = That tile can't be destroyed! +# Ammo count +rcd-component-no-ammo-message = The RCD has run out of charges! +rcd-component-insufficient-ammo-message = The RCD doesn't have enough charges left! + +# Deconstruction +rcd-component-tile-indestructible-message = That tile can't be destructed! rcd-component-deconstruct-target-not-on-whitelist-message = You can't deconstruct that! -rcd-component-cannot-build-floor-tile-not-empty-message = You can only build a floor on space! -rcd-component-cannot-build-wall-tile-not-empty-message = You cannot build a wall on space! -rcd-component-cannot-build-airlock-tile-not-empty-message = Cannot build an airlock on space! +rcd-component-nothing-to-deconstruct-message = There's nothing to deconstruct! +rcd-component-tile-obstructed-message = You can't deconstruct tiles when there's something on top of them! + +# Construction +rcd-component-no-valid-grid = You're too far into open space to build here! +rcd-component-must-build-on-empty-tile-message = A foundation already exists here! +rcd-component-cannot-build-on-empty-tile-message = You can't build that without a foundation! +rcd-component-must-build-on-subfloor-message = You can only build that on exposed subfloor! +rcd-component-cannot-build-on-subfloor-message = You can't build that on exposed subfloor! +rcd-component-cannot-build-on-occupied-tile-message = You can't build here, the space is already occupied! +rcd-component-cannot-build-identical-tile = That tile already exists there! + + +### Category names + +rcd-component-walls-and-flooring = Walls and flooring +rcd-component-windows-and-grilles = Windows and grilles +rcd-component-airlocks = Airlocks +rcd-component-electrical = Electrical +rcd-component-lighting = Lighting + + +### Prototype names (note: constructable items will be puralized) + +rcd-component-deconstruct = deconstruct +rcd-component-wall-solid = solid wall +rcd-component-floor-steel = steel tile +rcd-component-plating = hull plate +rcd-component-catwalk = catwalk +rcd-component-wall-reinforced = reinforced wall +rcd-component-grille = grille +rcd-component-window = window +rcd-component-window-directional = directional window +rcd-component-window-reinforced-directional = directional reinforced window +rcd-component-reinforced-window = reinforced window +rcd-component-airlock = standard airlock +rcd-component-airlock-glass = glass airlock +rcd-component-firelock = firelock +rcd-component-computer-frame = computer frame +rcd-component-machine-frame = machine frame +rcd-component-tube-light = light +rcd-component-window-bulb-light = small light +rcd-component-window-lv-cable = LV cable +rcd-component-window-mv-cable = MV cable +rcd-component-window-hv-cable = HV cable +rcd-component-window-cable-terminal = cable terminal diff --git a/Resources/Locale/en-US/reagents/meta/consumable/drink/alcohol.ftl b/Resources/Locale/en-US/reagents/meta/consumable/drink/alcohol.ftl index 099d23c465..4c38e92558 100644 --- a/Resources/Locale/en-US/reagents/meta/consumable/drink/alcohol.ftl +++ b/Resources/Locale/en-US/reagents/meta/consumable/drink/alcohol.ftl @@ -82,6 +82,9 @@ reagent-desc-atomic-bomb = Nuclear proliferation never tasted so good. reagent-name-b52 = b-52 reagent-desc-b52 = Coffee, irish cream, and cognac. You will get bombed. +reagent-name-blue-hawaiian = blue hawaiian +reagent-desc-blue-hawaiian = Aloha! Does that mean hello or goodbye? + reagent-name-bahama-mama = bahama mama reagent-desc-bahama-mama = Tropical cocktail. @@ -106,6 +109,12 @@ reagent-desc-booger = Ewww... reagent-name-brave-bull = brave bull reagent-desc-brave-bull = It's just as effective as Dutch-Courage! +reagent-name-coconut-rum = coconut rum +reagent-desc-coconut-rum = Rum with coconut for that tropical feel. + +reagent-name-cosmopolitan = cosmopolitan +reagent-desc-cosmopolitan = Even in the worst situations, nothing beats a fresh cosmopolitan. + reagent-name-cuba-libre = cuba libre reagent-desc-cuba-libre = Rum, mixed with cola. Viva la revolucion. @@ -190,9 +199,15 @@ reagent-desc-moonshine = Artisanal homemade liquor. What could go wrong? reagent-name-neurotoxin = neurotoxin reagent-desc-neurotoxin = A strong neurotoxin that puts the subject into a death-like state. +reagent-name-painkiller = painkiller +reagent-desc-painkiller = A cure for what ails you. + reagent-name-patron = patron reagent-desc-patron = Tequila with silver in it, a favorite of alcoholic women in the club scene. +reagent-name-pina-colada = piña colada +reagent-desc-pina-colada = For getting lost in the rain. + reagent-name-red-mead = red mead reagent-desc-red-mead = The true Viking's drink! Even though it has a strange red color. diff --git a/Resources/Locale/en-US/reagents/meta/consumable/drink/drinks.ftl b/Resources/Locale/en-US/reagents/meta/consumable/drink/drinks.ftl index ad0ade7c96..359e866fd9 100644 --- a/Resources/Locale/en-US/reagents/meta/consumable/drink/drinks.ftl +++ b/Resources/Locale/en-US/reagents/meta/consumable/drink/drinks.ftl @@ -4,6 +4,12 @@ reagent-desc-coffee = A drink made from brewed coffee beans. Contains a moderate reagent-name-cream = cream reagent-desc-cream = The fatty, still liquid part of milk. Why don't you mix this with sum scotch, eh? +reagent-name-coconut-water = coconut water +reagent-desc-coconut-water = A favorite of survivors on deserted islands. + +reagent-name-cream-of-coconut = cream of coconut +reagent-desc-cream-of-coconut = Sweet, syrupy version of coconut cream with added sugar. + reagent-name-cafe-latte = cafe latte reagent-desc-cafe-latte = A nice, strong and tasty beverage while you are reading. @@ -17,7 +23,7 @@ reagent-name-iced-coffee = iced coffee reagent-desc-iced-coffee = Coffee and ice, refreshing and cool. reagent-name-iced-green-tea = iced green tea -reagent-desc-iced-green-tea = cold green tea. +reagent-desc-iced-green-tea = Cold green tea. reagent-name-iced-tea = iced tea reagent-desc-iced-tea = No relation to a certain rap artist/actor. @@ -25,6 +31,9 @@ reagent-desc-iced-tea = No relation to a certain rap artist/actor. reagent-name-lemonade = lemonade reagent-desc-lemonade = Drink using lemon juice, water, and a sweetener such as cane sugar or honey. +reagent-name-arnold-palmer = arnold palmer +reagent-desc-arnold-palmer = Now watch this drive. + reagent-name-milk = milk reagent-desc-milk = An opaque white liquid produced by the mammary glands of mammals. @@ -86,4 +95,4 @@ reagent-name-white-gilgamesh = white gilgamesh reagent-desc-white-gilgamesh = A sickening mixture of milk and beer. Makes you feel like you're made of wood. reagent-name-mopwata = mopwata -reagent-desc-mopwata = Dirty, stagnant mop water. \ No newline at end of file +reagent-desc-mopwata = Dirty, stagnant mop water. diff --git a/Resources/Locale/en-US/reagents/meta/consumable/drink/soda.ftl b/Resources/Locale/en-US/reagents/meta/consumable/drink/soda.ftl index 08017c265d..300284aee9 100644 --- a/Resources/Locale/en-US/reagents/meta/consumable/drink/soda.ftl +++ b/Resources/Locale/en-US/reagents/meta/consumable/drink/soda.ftl @@ -1,6 +1,9 @@ reagent-name-cola = cola reagent-desc-cola = A sweet, carbonated soft drink. Caffeine free. +reagent-name-shirley-temple = shirley temple +reagent-desc-shirley-temple = A favorite amongst younger members of the crew. + reagent-name-changeling-sting = changeling sting reagent-desc-changeling-sting = You take a tiny sip and feel a burning sensation... @@ -28,6 +31,12 @@ reagent-desc-root-beer = A very sweet, carbonated drink reminiscent of sarsparil reagent-name-root-beer-float = root beer float reagent-desc-root-beer-float = Root beer, but now with ice cream on top. It truly is the magnum opus of Canadian summertime drinks. +reagent-name-sol-dry = sol dry +reagent-desc-sol-dry = Sweet ginger soda from outer space! + +reagent-name-roy-rogers = roy rogers +reagent-desc-roy-rogers = Solid proof that there IS something known as too sweet. + reagent-name-space-mountain-wind = Space Mountain Wind reagent-desc-space-mountain-wind = Blows right through you like a space wind. diff --git a/Resources/Locale/en-US/shell.ftl b/Resources/Locale/en-US/shell.ftl index 7a66fbc794..34460f001a 100644 --- a/Resources/Locale/en-US/shell.ftl +++ b/Resources/Locale/en-US/shell.ftl @@ -47,3 +47,4 @@ shell-argument-number-invalid = Argument {$index} must be a valid number! # Hints shell-argument-username-hint = +shell-argument-username-optional-hint = [username] diff --git a/Resources/Locale/en-US/storage/components/secret-stash-component.ftl b/Resources/Locale/en-US/storage/components/secret-stash-component.ftl index d41933b374..d0dfed2b5d 100644 --- a/Resources/Locale/en-US/storage/components/secret-stash-component.ftl +++ b/Resources/Locale/en-US/storage/components/secret-stash-component.ftl @@ -5,6 +5,7 @@ comp-secret-stash-action-hide-success = You hide { THE($item) } in { $this } comp-secret-stash-action-hide-container-not-empty = There's already something in here?! comp-secret-stash-action-hide-item-too-big = { THE($item) } is too big to fit in {$stash}! comp-secret-stash-action-get-item-found-something = There was something inside {$stash}! +comp-secret-stash-on-examine-found-hidden-item = There is something hidden inside. secret-stash-part-plant = the plant secret-stash-part-toilet = the toilet cistern diff --git a/Resources/Locale/en-US/store/store.ftl b/Resources/Locale/en-US/store/store.ftl index 7af2b05533..d663cc61f7 100644 --- a/Resources/Locale/en-US/store/store.ftl +++ b/Resources/Locale/en-US/store/store.ftl @@ -6,3 +6,5 @@ store-ui-traitor-flavor = Copyright (C) NT -30643 store-ui-traitor-warning = Operatives must lock their uplinks after use to avoid detection. store-withdraw-button-ui = Withdraw {$currency} + +store-not-account-owner = This {$store} is not bound to you! diff --git a/Resources/Locale/en-US/toilet/toilet-component.ftl b/Resources/Locale/en-US/toilet/toilet-component.ftl index 7807759e42..1129f61b4d 100644 --- a/Resources/Locale/en-US/toilet/toilet-component.ftl +++ b/Resources/Locale/en-US/toilet/toilet-component.ftl @@ -7,3 +7,5 @@ toilet-component-suicide-message-others = {CAPITALIZE(THE($victim))} bashes them toilet-component-suicide-message = You bash yourself with {THE($owner)}! toilet-seat-close = Close Seat toilet-seat-open = Open Seat + +plunger-unblock = You unblock the {THE($target)}! diff --git a/Resources/Locale/en-US/traits/traits.ftl b/Resources/Locale/en-US/traits/traits.ftl index b82cb0033a..fa17dc23ec 100644 --- a/Resources/Locale/en-US/traits/traits.ftl +++ b/Resources/Locale/en-US/traits/traits.ftl @@ -33,5 +33,8 @@ trait-frontal-lisp-desc = You thpeak with a lithp trait-socialanxiety-name = Social Anxiety trait-socialanxiety-desc = You are anxious when you speak and stutter. +trait-southern-name = Southern Drawl +trait-southern-desc = You have a different way of speakin'. + trait-snoring-name = Snoring trait-snoring-desc = You will snore while sleeping. diff --git a/Resources/Locale/en-US/ui/general.ftl b/Resources/Locale/en-US/ui/general.ftl new file mode 100644 index 0000000000..1471261dcb --- /dev/null +++ b/Resources/Locale/en-US/ui/general.ftl @@ -0,0 +1,3 @@ +### Loc for the various UI-related verbs +ui-verb-toggle-open = Toggle UI +verb-instrument-openui = Play Music diff --git a/Resources/Maps/Shuttles/emergency_meta.yml b/Resources/Maps/Shuttles/emergency_meta.yml index 57e9f98f40..385f5e3bbf 100644 --- a/Resources/Maps/Shuttles/emergency_meta.yml +++ b/Resources/Maps/Shuttles/emergency_meta.yml @@ -21,7 +21,7 @@ entities: - uid: 1 components: - type: MetaData - name: grid + name: NT Evac Meta - type: Transform pos: -2.4375,0.859375 parent: invalid diff --git a/Resources/Maps/reach.yml b/Resources/Maps/reach.yml index cd1389c31b..9cc0887d17 100644 --- a/Resources/Maps/reach.yml +++ b/Resources/Maps/reach.yml @@ -529,12 +529,14 @@ entities: 7: 4,-14 259: 0,11 - node: + cleanable: True color: '#FFFFFFFF' id: DirtHeavy decals: 222: -18,-4 275: 1,13 - node: + cleanable: True color: '#FFFFFFFF' id: DirtLight decals: @@ -574,6 +576,7 @@ entities: 283: 0,8 284: 1,7 - node: + cleanable: True color: '#FFFFFFFF' id: DirtMedium decals: @@ -11786,12 +11789,14 @@ entities: - uid: 1030 components: - type: Transform - pos: 21.5,-3.5 + pos: 18.5,-3.5 parent: 407 +- proto: SpawnMobFoxRenault + entities: - uid: 1826 components: - type: Transform - pos: 18.5,-3.5 + pos: 21.5,-3.5 parent: 407 - proto: SpawnPointAtmos entities: diff --git a/Resources/Prototypes/Accents/word_replacements.yml b/Resources/Prototypes/Accents/word_replacements.yml index abcfeded22..3fadc69010 100644 --- a/Resources/Prototypes/Accents/word_replacements.yml +++ b/Resources/Prototypes/Accents/word_replacements.yml @@ -367,6 +367,15 @@ accent-cowboy-words-98: accent-cowboy-replacement-98 accent-cowboy-words-99: accent-cowboy-replacement-99 +- type: accent + id: southern + wordReplacements: + accent-southern-words-1: accent-southern-words-replace-1 + accent-southern-words-2: accent-southern-words-replace-2 + accent-southern-words-3: accent-southern-words-replace-3 + accent-southern-words-4: accent-southern-words-replace-4 + accent-southern-words-5: accent-southern-words-replace-5 + accent-southern-words-6: accent-southern-words-replace-6 # For the chat sanitization system - type: accent diff --git a/Resources/Prototypes/Anomaly/behaviours.yml b/Resources/Prototypes/Anomaly/behaviours.yml new file mode 100644 index 0000000000..b46ba97fc2 --- /dev/null +++ b/Resources/Prototypes/Anomaly/behaviours.yml @@ -0,0 +1,208 @@ +- type: weightedRandom + id: AnomalyBehaviorList + weights: + #safe + Slow: 0.5 + Light: 0.5 + FullSafe: 0.1 + #balanced + Balanced: 3 + DelayedForce: 1 + Rapid: 1 + BalancedSecret: 1 + Reflect: 1 + NonSensivity: 1 + Sensivity: 1 + #Hard + Fast: 0.5 + Strenght: 0.5 + Inconstancy: 0.5 + InconstancyParticle: 0.5 + FullUnknown: 0.5 + Jumping: 0.3 + Moving: 0.1 + #Complex + FastUnknown: 0.2 + JumpingUnknown: 0.1 + InconstancyParticleUnknown: 0.1 + + +# Easy x0.5 point production + +- type: anomalyBehavior + id: FullSafe + pulseFrequencyModifier: 3 + pulsePowerModifier: 0.5 + earnPointModifier: 0.05 + description: anomaly-behavior-safe + +- type: anomalyBehavior + id: Slow + pulseFrequencyModifier: 2 + earnPointModifier: 0.5 + description: anomaly-behavior-slow + +- type: anomalyBehavior + id: Light + pulsePowerModifier: 0.5 + earnPointModifier: 0.5 + description: anomaly-behavior-light + +# Balanced x1 point production + +- type: anomalyBehavior + id: Balanced + earnPointModifier: 1 + description: anomaly-behavior-balanced + +- type: anomalyBehavior + id: DelayedForce + earnPointModifier: 1.15 + description: anomaly-behavior-delayed-force + pulseFrequencyModifier: 0.5 + pulsePowerModifier: 2 + +- type: anomalyBehavior + id: Rapid + earnPointModifier: 1.15 + description: anomaly-behavior-rapid + pulseFrequencyModifier: 2 + pulsePowerModifier: 0.5 + +- type: anomalyBehavior + id: BalancedSecret + earnPointModifier: 1.2 + description: anomaly-behavior-secret + components: + - type: SecretDataAnomaly + randomStartSecretMin: 2 + randomStartSecretMax: 3 + +- type: anomalyBehavior + id: Reflect + earnPointModifier: 1.1 + particleSensivity: 0.5 + description: anomaly-behavior-reflect + components: + - type: Reflect + reflectProb: 0.5 + reflects: + - Energy + +- type: anomalyBehavior + id: NonSensivity + earnPointModifier: 0.8 + particleSensivity: 0.5 + description: anomaly-behavior-nonsensivity + +- type: anomalyBehavior + id: Sensivity + earnPointModifier: 1.2 + particleSensivity: 1.5 + description: anomaly-behavior-sensivity + +# Hard x2 point production + +- type: anomalyBehavior + id: Fast + earnPointModifier: 1.9 + pulseFrequencyModifier: 0.5 + description: anomaly-behavior-fast + +- type: anomalyBehavior + id: Strenght + pulsePowerModifier: 1.5 + earnPointModifier: 1.4 + description: anomaly-behavior-strenght + +- type: anomalyBehavior + id: Inconstancy + earnPointModifier: 1.7 + description: anomaly-behavior-inconstancy + components: + - type: ShuffleParticlesAnomaly + shuffleOnPulse: true + prob: 1 + +- type: anomalyBehavior + id: InconstancyParticle + earnPointModifier: 1.8 + description: anomaly-behavior-inconstancy + components: + - type: ShuffleParticlesAnomaly + shuffleOnParticleHit: true + prob: 0.8 + +- type: anomalyBehavior + id: Moving + earnPointModifier: 2.2 + description: anomaly-behavior-moving + components: + - type: RandomWalk + minSpeed: 0 + maxSpeed: 0.3 + - type: CanMoveInAir + - type: Physics + bodyType: Dynamic + bodyStatus: InAir + +- type: anomalyBehavior + id: Jumping + earnPointModifier: 1.8 + description: anomaly-behavior-moving + components: + - type: ChaoticJump + jumpMinInterval: 15 + jumpMaxInterval: 25 + rangeMin: 1 + rangeMax: 4 + effect: PuddleSparkle + +- type: anomalyBehavior + id: FullUnknown + earnPointModifier: 1.9 + description: anomaly-behavior-secret + components: + - type: SecretDataAnomaly + randomStartSecretMin: 4 + randomStartSecretMax: 6 + +# Complex Effects + +- type: anomalyBehavior + id: JumpingUnknown + earnPointModifier: 1.9 + description: anomaly-behavior-moving + components: + - type: ChaoticJump + jumpMinInterval: 15 + jumpMaxInterval: 25 + rangeMin: 1 + rangeMax: 1 + effect: PuddleSparkle + - type: SecretDataAnomaly + randomStartSecretMin: 3 + randomStartSecretMax: 5 + + +- type: anomalyBehavior + id: FastUnknown + earnPointModifier: 1.9 + pulseFrequencyModifier: 0.5 + description: anomaly-behavior-fast + components: + - type: SecretDataAnomaly + randomStartSecretMin: 3 + randomStartSecretMax: 5 + +- type: anomalyBehavior + id: InconstancyParticleUnknown + earnPointModifier: 1.95 + description: anomaly-behavior-inconstancy + components: + - type: ShuffleParticlesAnomaly + shuffleOnParticleHit: true + prob: 0.5 + - type: SecretDataAnomaly + randomStartSecretMin: 3 + randomStartSecretMax: 5 \ No newline at end of file diff --git a/Resources/Prototypes/Catalog/Cargo/cargo_fun.yml b/Resources/Prototypes/Catalog/Cargo/cargo_fun.yml index c29458a1ee..61085f13b9 100644 --- a/Resources/Prototypes/Catalog/Cargo/cargo_fun.yml +++ b/Resources/Prototypes/Catalog/Cargo/cargo_fun.yml @@ -68,16 +68,6 @@ category: cargoproduct-category-name-fun group: market -- type: cargoProduct - id: FunSprayPaints - icon: - sprite: Objects/Fun/spraycans.rsi - state: death2_cap - product: CrateFunSprayPaints - cost: 2000 - category: Fun - group: market - - type: cargoProduct id: FunParty icon: diff --git a/Resources/Prototypes/Catalog/Cargo/cargo_service.yml b/Resources/Prototypes/Catalog/Cargo/cargo_service.yml index f27adb65a4..267f706f3b 100644 --- a/Resources/Prototypes/Catalog/Cargo/cargo_service.yml +++ b/Resources/Prototypes/Catalog/Cargo/cargo_service.yml @@ -82,7 +82,7 @@ id: ServiceBooks icon: sprite: Objects/Misc/books.rsi - state: book0 + state: book_icon product: CrateServiceBooks cost: 1000 category: cargoproduct-category-name-service @@ -92,7 +92,7 @@ id: ServiceGuidebooks icon: sprite: Objects/Misc/books.rsi - state: book_engineering2 + state: book_icon product: CrateServiceGuidebooks cost: 1300 category: cargoproduct-category-name-service diff --git a/Resources/Prototypes/Catalog/Fills/Backpacks/StarterGear/backpack.yml b/Resources/Prototypes/Catalog/Fills/Backpacks/StarterGear/backpack.yml index e4c094ea2b..bbea09e921 100644 --- a/Resources/Prototypes/Catalog/Fills/Backpacks/StarterGear/backpack.yml +++ b/Resources/Prototypes/Catalog/Fills/Backpacks/StarterGear/backpack.yml @@ -328,6 +328,27 @@ - id: CrowbarRed - id: AdvMopItem +- type: entity + noSpawn: true + parent: ClothingBackpackERTChaplain + id: ClothingBackpackERTChaplainFilled + components: + - type: StorageFill + contents: + - id: BoxSurvivalEngineering + - id: BoxCandle + - id: BoxBodyBag + - id: DrinkWaterMelonJuiceJug + - id: Lantern + - id: Lantern + - id: Bible + - id: CrowbarRed + - id: FoodBakedBunHotX + - id: FoodBakedBunHotX + - id: FoodBakedBunHotX + - id: FoodBakedBunHotX + - id: Lighter + # Death Squad - type: entity diff --git a/Resources/Prototypes/Catalog/Fills/Books/bookshelf.yml b/Resources/Prototypes/Catalog/Fills/Books/bookshelf.yml index 48fab5dccc..b52e853008 100644 --- a/Resources/Prototypes/Catalog/Fills/Books/bookshelf.yml +++ b/Resources/Prototypes/Catalog/Fills/Books/bookshelf.yml @@ -5,70 +5,10 @@ components: - type: StorageFill contents: - - id: BookRandom - prob: 0.4 - amount: 1 - maxAmount: 4 - - id: BookNarsieLegend - prob: 0.1 - - id: BookTruth - prob: 0.1 - - id: BookWorld - prob: 0.1 - - id: BookIanAntarctica - prob: 0.1 - - id: BookSlothClownSSS - prob: 0.1 - - id: BookSlothClownPranks - prob: 0.1 - - id: BookSlothClownMMD - prob: 0.1 - - id: BookStruck - prob: 0.1 - - id: BookSun - prob: 0.1 - - id: BookPossum - prob: 0.1 - - id: BookCafe - prob: 0.1 - - id: BookFeather - prob: 0.1 - - id: BookIanLostWolfPup - prob: 0.1 - - id: BookIanRanch - prob: 0.1 - - id: BookIanOcean - prob: 0.1 - - id: BookIanMountain - prob: 0.1 - - id: BookIanCity - prob: 0.1 - - id: BookIanArctic - prob: 0.1 - - id: BookIanDesert - prob: 0.1 - - id: BookNames - prob: 0.1 - - id: BookEarth - prob: 0.1 - - id: BookAurora - prob: 0.1 - - id: BookTemple - prob: 0.1 - - id: BookWatched - prob: 0.1 - - id: BookMedicalOfficer - prob: 0.1 - - id: BookMorgue - prob: 0.1 - - id: BookRufus - prob: 0.1 - - id: BookMap - prob: 0.1 - - id: BookJourney - prob: 0.1 - - id: BookInspiration - prob: 0.1 + - id: BookRandomStory + prob: 0.6 + amount: 2 + maxAmount: 6 - id: BookSpaceEncyclopedia orGroup: BookPool - id: BookTheBookOfControl @@ -95,3 +35,93 @@ orGroup: BookPool - id: BookChemicalCompendium orGroup: BookPool + - id: BookNarsieLegend + prob: 0.1 + orGroup: BookAuthor + - id: BookTruth + prob: 0.1 + orGroup: BookAuthor + - id: BookWorld + prob: 0.1 + orGroup: BookAuthor + - id: BookIanAntarctica + prob: 0.1 + orGroup: BookAuthor + - id: BookSlothClownSSS + prob: 0.1 + orGroup: BookAuthor + - id: BookSlothClownPranks + prob: 0.1 + orGroup: BookAuthor + - id: BookSlothClownMMD + prob: 0.1 + orGroup: BookAuthor + - id: BookStruck + prob: 0.1 + orGroup: BookAuthor + - id: BookSun + prob: 0.1 + orGroup: BookAuthor + - id: BookPossum + prob: 0.1 + orGroup: BookAuthor + - id: BookCafe + prob: 0.1 + orGroup: BookAuthor + - id: BookFeather + prob: 0.1 + orGroup: BookAuthor + - id: BookIanLostWolfPup + prob: 0.1 + orGroup: BookAuthor + - id: BookIanRanch + prob: 0.1 + orGroup: BookAuthor + - id: BookIanOcean + prob: 0.1 + orGroup: BookAuthor + - id: BookIanMountain + prob: 0.1 + orGroup: BookAuthor + - id: BookIanCity + prob: 0.1 + orGroup: BookAuthor + - id: BookIanArctic + prob: 0.1 + orGroup: BookAuthor + - id: BookIanDesert + prob: 0.1 + orGroup: BookAuthor + - id: BookNames + prob: 0.1 + orGroup: BookAuthor + - id: BookEarth + prob: 0.1 + orGroup: BookAuthor + - id: BookAurora + prob: 0.1 + orGroup: BookAuthor + - id: BookTemple + prob: 0.1 + orGroup: BookAuthor + - id: BookWatched + prob: 0.1 + orGroup: BookAuthor + - id: BookMedicalOfficer + prob: 0.1 + orGroup: BookAuthor + - id: BookMorgue + prob: 0.1 + orGroup: BookAuthor + - id: BookRufus + prob: 0.1 + orGroup: BookAuthor + - id: BookMap + prob: 0.1 + orGroup: BookAuthor + - id: BookJourney + prob: 0.1 + orGroup: BookAuthor + - id: BookInspiration + prob: 0.1 + orGroup: BookAuthor diff --git a/Resources/Prototypes/Catalog/Fills/Books/lore.yml b/Resources/Prototypes/Catalog/Fills/Books/lore.yml deleted file mode 100644 index 0fd712d42f..0000000000 --- a/Resources/Prototypes/Catalog/Fills/Books/lore.yml +++ /dev/null @@ -1,122 +0,0 @@ -# ---- Library Salvage Fills ---- - -- type: entity - name: demonomicon - parent: BookBase - id: BookDemonomicon - noSpawn: true - description: 'Who knows what dark spells may be contained in these horrid pages?' - components: - - type: Sprite - sprite: Objects/Misc/books.rsi - layers: - - state: book_demonomicon - -- type: entity - name: demonomicon - parent: BookDemonomicon - id: BookDemonomiconRandom - suffix: random - components: - - type: RandomSpawner - prototypes: - - BookDemonomicon1 - - BookDemonomicon2 - - BookDemonomicon3 - offset: 0.1 - -- type: entity - parent: BookDemonomicon - id: BookDemonomicon1 - suffix: 1 - components: - - type: Paper - content: book-text-demonomicon1 - -- type: entity - parent: BookDemonomicon - id: BookDemonomicon2 - suffix: 2 - components: - - type: Paper - content: book-text-demonomicon2 - -- type: entity - parent: BookDemonomicon - id: BookDemonomicon3 - suffix: 3 - components: - - type: Paper - content: book-text-demonomicon3 - -- type: entity - name: pharmaceutical manuscript - parent: BookBase - id: BookChemistryInsane - suffix: library salvage - description: 'You can tell whoever wrote this was off the desoxy HARD.' - components: - - type: Sprite - sprite: Objects/Misc/books.rsi - layers: - - state: book_chemistry - - type: Paper - content: book-text-chemistry-insane - -- type: entity - name: botanical textbook - parent: BookBase - id: BookBotanicalTextbook - suffix: library salvage - description: 'Only a couple pages are left.' - components: - - type: Sprite - sprite: Objects/Misc/books.rsi - layers: - - state: book_hydroponics_pod_people - - type: Paper - content: book-text-botanics - -- type: entity - parent: BookBase - id: BookGnominomicon - name: gnominomicon - suffix: library salvage - description: You don't like the look of this. Looks - components: - - type: Sprite - sprite: Objects/Misc/books.rsi - layers: - - state: book5 - - type: Paper - content: book-text-gnome - -- type: entity - parent: BookBase - id: BookFishing - name: Tales from the Fishbowl - suffix: library salvage - description: This book sucks. - components: - - type: Sprite - sprite: Objects/Misc/books.rsi - layers: - - state: book_fish - - type: Paper - content: book-text-fishing - -- type: entity - parent: BookBase - id: BookDetective - name: Strokgraeth Holmes, Dwarf Detective - suffix: library salvage - description: Exciting! Invigorating! This author died after his book career failed. - components: - - type: Sprite - sprite: Objects/Misc/books.rsi - layers: - - state: book_detective - - type: Paper - content: book-text-detective - -# ---- End Library Salvage Fills ---- diff --git a/Resources/Prototypes/Catalog/Fills/Crates/engineering.yml b/Resources/Prototypes/Catalog/Fills/Crates/engineering.yml index 668f3776dd..03c870fa58 100644 --- a/Resources/Prototypes/Catalog/Fills/Crates/engineering.yml +++ b/Resources/Prototypes/Catalog/Fills/Crates/engineering.yml @@ -166,8 +166,8 @@ - type: entity id: CrateRCDAmmo parent: CrateEngineering - name: RCD ammo crate - description: 3 RCD ammo, each restoring 5 charges. + name: compressed matter crate + description: Contains three compressed matter cartridges. components: - type: StorageFill contents: @@ -178,7 +178,7 @@ id: CrateRCD parent: CrateEngineeringSecure name: RCD crate - description: A crate containing a single Rapid Construction Device. + description: A crate containing a single rapid construction device. components: - type: StorageFill contents: diff --git a/Resources/Prototypes/Catalog/Fills/Crates/fun.yml b/Resources/Prototypes/Catalog/Fills/Crates/fun.yml index 17018cb9e6..72cf6c447c 100644 --- a/Resources/Prototypes/Catalog/Fills/Crates/fun.yml +++ b/Resources/Prototypes/Catalog/Fills/Crates/fun.yml @@ -290,21 +290,14 @@ contents: - id: SnapPopBox - id: CrazyGlue + amount: 2 - id: PlasticBanana - - id: FunnyPaint - orGroup: Paint - prob: 0.5 - - id: FunnyPaintYellow - orGroup: Paint - prob: 0.5 - id: WhoopieCushion - id: ToyHammer - id: MrChips - prob: 0.5 - orGroup: Dummy + orGroup: GiftPool - id: MrDips - prob: 0.5 - orGroup: Dummy + orGroup: Giftpool - id: RevolverCapGun - id: BalloonNT - id: ClothingShoesClownLarge @@ -337,41 +330,6 @@ amount: 15 prob: 0.05 -- type: entity - id: CrateFunSprayPaints - name: spray paint crate - description: a crate filled with spray paint. - parent: CratePlastic - suffix: Spray Paint - components: - - type: StorageFill - contents: - - id: SprayPaintBlue - amount: 2 - prob: 0.33 - - id: SprayPaintRed - amount: 2 - prob: 0.33 - - id: SprayPaintOrange - amount: 2 - prob: 0.33 - - id: SprayPaintBlack - amount: 2 - prob: 0.33 - - id: SprayPaintGreen - amount: 2 - prob: 0.33 - - id: SprayPaintPurple - amount: 2 - prob: 0.33 - - id: SprayPaintWhite - amount: 2 - prob: 0.33 - - id: DeathPaint - amount: 2 - - id: DeathPaintTwo - amount: 2 - - type: entity name: dartboard box set description: A box with everything you need for a fun game of darts. diff --git a/Resources/Prototypes/Catalog/Fills/Items/briefcases.yml b/Resources/Prototypes/Catalog/Fills/Items/briefcases.yml index 6be5ae0d30..58a49aa6e9 100644 --- a/Resources/Prototypes/Catalog/Fills/Items/briefcases.yml +++ b/Resources/Prototypes/Catalog/Fills/Items/briefcases.yml @@ -1,6 +1,5 @@ - type: entity id: BriefcaseBrownFilled - name: brown briefcase parent: BriefcaseBrown suffix: Filled, Paper components: @@ -11,9 +10,8 @@ - type: entity id: BriefcaseSyndieSniperBundleFilled - name: brown briefcase parent: BriefcaseSyndie - suffix: SniperBundle + suffix: Syndicate, Sniper Bundle components: - type: Item size: Ginormous @@ -32,7 +30,6 @@ - type: entity id: BriefcaseSyndieLobbyingBundleFilled - name: brown briefcase parent: BriefcaseSyndie suffix: Syndicate, Spesos components: @@ -52,7 +49,6 @@ - type: entity id: BriefcaseThiefBribingBundleFilled - name: brown briefcase parent: BriefcaseSyndie suffix: Thief, Spesos components: diff --git a/Resources/Prototypes/Catalog/Fills/Lockers/heads.yml b/Resources/Prototypes/Catalog/Fills/Lockers/heads.yml index 25c3fde0bd..ae5917bc51 100644 --- a/Resources/Prototypes/Catalog/Fills/Lockers/heads.yml +++ b/Resources/Prototypes/Catalog/Fills/Lockers/heads.yml @@ -255,7 +255,6 @@ components: - type: StorageFill contents: - - id: ClothingEyesHudSecurity - id: WeaponDisabler - id: ClothingOuterCoatHoSTrench - id: ClothingMaskNeckGaiter @@ -263,7 +262,7 @@ - id: ClothingMaskGasSwat - id: ClothingBeltSecurityFilled - id: ClothingHeadsetAltSecurity - - id: ClothingEyesGlassesSunglasses + - id: ClothingEyesGlassesSecurity - id: ClothingShoesBootsJack - id: CigarGoldCase prob: 0.50 @@ -282,13 +281,12 @@ components: - type: StorageFill contents: - - id: ClothingEyesHudSecurity - id: WeaponDisabler - id: ClothingOuterCoatHoSTrench - id: ClothingMaskNeckGaiter - id: ClothingBeltSecurityFilled - id: ClothingHeadsetAltSecurity - - id: ClothingEyesGlassesSunglasses + - id: ClothingEyesGlassesSecurity - id: ClothingShoesBootsJack - id: CigarGoldCase prob: 0.50 diff --git a/Resources/Prototypes/Catalog/Fills/Lockers/misc.yml b/Resources/Prototypes/Catalog/Fills/Lockers/misc.yml index 850fb91273..d8b6004ec3 100644 --- a/Resources/Prototypes/Catalog/Fills/Lockers/misc.yml +++ b/Resources/Prototypes/Catalog/Fills/Lockers/misc.yml @@ -145,10 +145,6 @@ prob: 0.25 - id: StrangePill prob: 0.20 - - id: DeathPaint - prob: 0.05 - - id: DeathPaintTwo - prob: 0.05 - id: DrinkMopwataBottleRandom prob: 0.20 - id: ModularReceiver @@ -159,6 +155,8 @@ prob: 0.20 - id: BarberScissors prob: 0.05 + - id: BookRandomStory + prob: 0.1 # Syndicate loot - id: null prob: 0.95 diff --git a/Resources/Prototypes/Catalog/Fills/Lockers/security.yml b/Resources/Prototypes/Catalog/Fills/Lockers/security.yml index 4bb300b158..2896494978 100644 --- a/Resources/Prototypes/Catalog/Fills/Lockers/security.yml +++ b/Resources/Prototypes/Catalog/Fills/Lockers/security.yml @@ -9,7 +9,7 @@ - id: WeaponDisabler - id: ClothingBeltSecurityFilled - id: Flash - - id: ClothingEyesGlassesSunglasses + - id: ClothingEyesGlassesSecurity - id: ClothingHeadsetAltSecurity - id: ClothingHandsGlovesCombat - id: ClothingShoesBootsJack @@ -19,7 +19,6 @@ - id: DoorRemoteArmory - id: ClothingOuterHardsuitWarden - id: HoloprojectorSecurity - - id: ClothingEyesHudSecurity - type: entity id: LockerWardenFilled @@ -32,7 +31,7 @@ - id: WeaponDisabler - id: ClothingBeltSecurityFilled - id: Flash - - id: ClothingEyesGlassesSunglasses + - id: ClothingEyesGlassesSecurity - id: ClothingHeadsetAltSecurity - id: ClothingHandsGlovesCombat - id: ClothingShoesBootsJack @@ -41,7 +40,6 @@ - id: RubberStampWarden - id: DoorRemoteArmory - id: HoloprojectorSecurity - - id: ClothingEyesHudSecurity - type: entity id: LockerSecurityFilled @@ -60,13 +58,12 @@ - id: ClothingBeltSecurityFilled - id: Flash prob: 0.5 - - id: ClothingEyesGlassesSunglasses + - id: ClothingEyesGlassesSecurity - id: ClothingHeadsetSecurity - id: ClothingHandsGlovesColorBlack - id: ClothingShoesBootsJack - id: WeaponMeleeNeedle prob: 0.1 - - id: ClothingEyesHudSecurity - id: HoloprojectorSecurity prob: 0.6 @@ -77,7 +74,7 @@ components: - type: StorageFill contents: - - id: ClothingEyesHudSecurity + - id: ClothingEyesGlassesSecurity - id: WeaponDisabler - id: TrackingImplanter amount: 2 @@ -112,7 +109,7 @@ components: - type: StorageFill contents: - - id: ClothingEyesHudSecurity + - id: ClothingEyesGlassesSecurity prob: 0.3 - id: ClothingHeadHatFedoraBrown - id: ClothingNeckTieDet diff --git a/Resources/Prototypes/Catalog/ReagentDispensers/beverage.yml b/Resources/Prototypes/Catalog/ReagentDispensers/beverage.yml index d337d23f2a..975541a502 100644 --- a/Resources/Prototypes/Catalog/ReagentDispensers/beverage.yml +++ b/Resources/Prototypes/Catalog/ReagentDispensers/beverage.yml @@ -1,11 +1,11 @@ - type: reagentDispenserInventory id: SodaDispenserInventory inventory: + - DrinkCoconutWaterJug - DrinkCoffeeJug - DrinkColaBottleFull - DrinkCreamCartonXL - DrinkDrGibbJug - - DrinkEnergyDrinkJug - DrinkGreenTeaJug - DrinkIceJug - DrinkJuiceLimeCartonXL diff --git a/Resources/Prototypes/Catalog/VendingMachines/Inventories/boozeomat.yml b/Resources/Prototypes/Catalog/VendingMachines/Inventories/boozeomat.yml index 793121e2f2..eaa4c839af 100644 --- a/Resources/Prototypes/Catalog/VendingMachines/Inventories/boozeomat.yml +++ b/Resources/Prototypes/Catalog/VendingMachines/Inventories/boozeomat.yml @@ -13,7 +13,9 @@ DrinkBeerBottleFull: 5 DrinkBlueCuracaoBottleFull: 2 DrinkCognacBottleFull: 4 + DrinkCoconutWaterCarton: 3 DrinkColaBottleFull: 4 + DrinkMilkCarton: 2 DrinkCreamCarton: 5 DrinkGinBottleFull: 3 DrinkGildlagerBottleFull: 2 #if champagne gets less because its premium, then gildlager should match this and have two @@ -26,6 +28,7 @@ DrinkPatronBottleFull: 2 DrinkRumBottleFull: 4 DrinkSodaWaterCan: 8 + DrinkSolDryCan: 8 DrinkSpaceMountainWindBottleFull: 3 DrinkSpaceUpBottleFull: 3 DrinkTequilaBottleFull: 3 diff --git a/Resources/Prototypes/Catalog/VendingMachines/Inventories/cola.yml b/Resources/Prototypes/Catalog/VendingMachines/Inventories/cola.yml index 2f9ce3d3ae..ace9102562 100644 --- a/Resources/Prototypes/Catalog/VendingMachines/Inventories/cola.yml +++ b/Resources/Prototypes/Catalog/VendingMachines/Inventories/cola.yml @@ -5,6 +5,7 @@ DrinkGrapeCan: 2 DrinkRootBeerCan: 2 DrinkIcedTeaCan: 2 + DrinkSolDryCan: 2 DrinkLemonLimeCan: 2 DrinkFourteenLokoCan: 2 emaggedInventory: diff --git a/Resources/Prototypes/Catalog/VendingMachines/Inventories/curadrobe.yml b/Resources/Prototypes/Catalog/VendingMachines/Inventories/curadrobe.yml index 07e957a5e0..aac1cbb3f4 100644 --- a/Resources/Prototypes/Catalog/VendingMachines/Inventories/curadrobe.yml +++ b/Resources/Prototypes/Catalog/VendingMachines/Inventories/curadrobe.yml @@ -2,6 +2,7 @@ id: CuraDrobeInventory startingInventory: BooksBag: 2 + BriefcaseBrown: 2 HandLabeler: 2 ClothingEyesGlasses: 2 ClothingEyesGlassesJamjar: 2 @@ -12,4 +13,4 @@ ClothingUniformJumpskirtLibrarian: 3 ClothingShoesBootsLaceup: 2 ClothingHeadsetService: 2 - + diff --git a/Resources/Prototypes/Catalog/VendingMachines/Inventories/gib.yml b/Resources/Prototypes/Catalog/VendingMachines/Inventories/gib.yml index 38ea3a0012..98513a48a4 100644 --- a/Resources/Prototypes/Catalog/VendingMachines/Inventories/gib.yml +++ b/Resources/Prototypes/Catalog/VendingMachines/Inventories/gib.yml @@ -5,6 +5,7 @@ DrinkGrapeCan: 2 DrinkRootBeerCan: 2 DrinkIcedTeaCan: 2 + DrinkSolDryCan: 2 DrinkLemonLimeCan: 2 DrinkFourteenLokoCan: 2 emaggedInventory: diff --git a/Resources/Prototypes/Catalog/VendingMachines/Inventories/lawdrobe.yml b/Resources/Prototypes/Catalog/VendingMachines/Inventories/lawdrobe.yml index b1478a7cfc..28f63e44e2 100644 --- a/Resources/Prototypes/Catalog/VendingMachines/Inventories/lawdrobe.yml +++ b/Resources/Prototypes/Catalog/VendingMachines/Inventories/lawdrobe.yml @@ -14,6 +14,7 @@ ClothingShoesBootsLaceup: 2 ClothingHeadsetService: 2 ClothingNeckLawyerbadge: 2 + BriefcaseBrown: 2 LuxuryPen: 2 contrabandInventory: ClothingOuterRobesJudge: 1 diff --git a/Resources/Prototypes/Catalog/VendingMachines/Inventories/pwrgame.yml b/Resources/Prototypes/Catalog/VendingMachines/Inventories/pwrgame.yml index 96513fca8a..cb5a4f5c4b 100644 --- a/Resources/Prototypes/Catalog/VendingMachines/Inventories/pwrgame.yml +++ b/Resources/Prototypes/Catalog/VendingMachines/Inventories/pwrgame.yml @@ -6,6 +6,7 @@ DrinkGrapeCan: 2 DrinkRootBeerCan: 2 DrinkIcedTeaCan: 2 + DrinkSolDryCan: 2 DrinkLemonLimeCan: 2 DrinkFourteenLokoCan: 2 emaggedInventory: diff --git a/Resources/Prototypes/Catalog/VendingMachines/Inventories/shamblersjuice.yml b/Resources/Prototypes/Catalog/VendingMachines/Inventories/shamblersjuice.yml index 08c0162c08..6ac70b26db 100644 --- a/Resources/Prototypes/Catalog/VendingMachines/Inventories/shamblersjuice.yml +++ b/Resources/Prototypes/Catalog/VendingMachines/Inventories/shamblersjuice.yml @@ -5,6 +5,7 @@ DrinkGrapeCan: 2 DrinkRootBeerCan: 2 DrinkIcedTeaCan: 2 + DrinkSolDryCan: 2 DrinkLemonLimeCan: 2 DrinkFourteenLokoCan: 2 emaggedInventory: diff --git a/Resources/Prototypes/Catalog/VendingMachines/Inventories/soda.yml b/Resources/Prototypes/Catalog/VendingMachines/Inventories/soda.yml index 494f05f6a3..339683d2c9 100644 --- a/Resources/Prototypes/Catalog/VendingMachines/Inventories/soda.yml +++ b/Resources/Prototypes/Catalog/VendingMachines/Inventories/soda.yml @@ -5,6 +5,7 @@ DrinkGrapeCan: 3 DrinkRootBeerCan: 3 DrinkIcedTeaCan: 3 + DrinkSolDryCan: 3 DrinkLemonLimeCan: 3 DrinkFourteenLokoCan: 3 emaggedInventory: diff --git a/Resources/Prototypes/Catalog/VendingMachines/Inventories/spaceup.yml b/Resources/Prototypes/Catalog/VendingMachines/Inventories/spaceup.yml index 0dc33cf07f..a5f570bd46 100644 --- a/Resources/Prototypes/Catalog/VendingMachines/Inventories/spaceup.yml +++ b/Resources/Prototypes/Catalog/VendingMachines/Inventories/spaceup.yml @@ -6,6 +6,7 @@ DrinkGrapeCan: 2 DrinkRootBeerCan: 2 DrinkIcedTeaCan: 2 + DrinkSolDryCan: 2 DrinkLemonLimeCan: 2 DrinkFourteenLokoCan: 2 emaggedInventory: diff --git a/Resources/Prototypes/Catalog/VendingMachines/Inventories/starkist.yml b/Resources/Prototypes/Catalog/VendingMachines/Inventories/starkist.yml index 6afbe1eae6..b1a74fc13e 100644 --- a/Resources/Prototypes/Catalog/VendingMachines/Inventories/starkist.yml +++ b/Resources/Prototypes/Catalog/VendingMachines/Inventories/starkist.yml @@ -5,6 +5,7 @@ DrinkGrapeCan: 2 DrinkRootBeerCan: 2 DrinkIcedTeaCan: 2 + DrinkSolDryCan: 2 DrinkLemonLimeCan: 2 DrinkFourteenLokoCan: 2 emaggedInventory: diff --git a/Resources/Prototypes/Catalog/VendingMachines/Inventories/theater.yml b/Resources/Prototypes/Catalog/VendingMachines/Inventories/theater.yml index 960a8f8797..5e3c7d9401 100644 --- a/Resources/Prototypes/Catalog/VendingMachines/Inventories/theater.yml +++ b/Resources/Prototypes/Catalog/VendingMachines/Inventories/theater.yml @@ -43,7 +43,7 @@ ClothingMaskScaredMime: 1 ClothingUniformJumpsuitKimono: 1 ClothingHeadHatCasa: 1 - ClothingHeadHatHairflower: 1 + FoodPoppy: 1 ClothingHeadHatGladiator: 1 ClothingUniformJumpsuitGladiator: 1 ClothingHeadHatCowboyBrown: 1 diff --git a/Resources/Prototypes/Datasets/story_generation.yml b/Resources/Prototypes/Datasets/story_generation.yml new file mode 100644 index 0000000000..1083a6acdb --- /dev/null +++ b/Resources/Prototypes/Datasets/story_generation.yml @@ -0,0 +1,266 @@ +- type: dataset + id: book_type + values: + - story-gen-book-type1 + - story-gen-book-type2 + - story-gen-book-type3 + - story-gen-book-type4 + - story-gen-book-type5 + - story-gen-book-type6 + - story-gen-book-type7 + - story-gen-book-type8 + - story-gen-book-type9 + - story-gen-book-type10 + - story-gen-book-type11 + - story-gen-book-type12 + +- type: dataset + id: book_genre + values: + - story-gen-book-genre1 + - story-gen-book-genre2 + - story-gen-book-genre3 + - story-gen-book-genre4 + - story-gen-book-genre5 + - story-gen-book-genre6 + - story-gen-book-genre7 + - story-gen-book-genre8 + - story-gen-book-genre9 + - story-gen-book-genre10 + - story-gen-book-genre11 + - story-gen-book-genre12 + - story-gen-book-genre13 + - story-gen-book-genre14 + +- type: dataset + id: book_hint_appearance + values: + - story-gen-book-appearance1 + - story-gen-book-appearance2 + - story-gen-book-appearance3 + - story-gen-book-appearance4 + - story-gen-book-appearance5 + - story-gen-book-appearance6 + - story-gen-book-appearance7 + - story-gen-book-appearance8 + - story-gen-book-appearance9 + - story-gen-book-appearance10 + - story-gen-book-appearance11 + - story-gen-book-appearance12 + - story-gen-book-appearance13 + - story-gen-book-appearance14 + - story-gen-book-appearance15 + - story-gen-book-appearance16 + - story-gen-book-appearance17 + - story-gen-book-appearance18 + - story-gen-book-appearance19 + - story-gen-book-appearance20 + - story-gen-book-appearance21 + - story-gen-book-appearance22 + - story-gen-book-appearance23 + - story-gen-book-appearance24 + - story-gen-book-appearance25 + - story-gen-book-appearance26 + - story-gen-book-appearance27 + +- type: dataset + id: book_character + values: + - story-gen-book-character1 + - story-gen-book-character2 + - story-gen-book-character3 + - story-gen-book-character4 + - story-gen-book-character5 + - story-gen-book-character6 + - story-gen-book-character7 + - story-gen-book-character8 + - story-gen-book-character9 + - story-gen-book-character10 + - story-gen-book-character11 + - story-gen-book-character12 + - story-gen-book-character13 + - story-gen-book-character14 + - story-gen-book-character15 + - story-gen-book-character16 + - story-gen-book-character17 + - story-gen-book-character18 + - story-gen-book-character19 + - story-gen-book-character20 + - story-gen-book-character21 + - story-gen-book-character22 + - story-gen-book-character23 + - story-gen-book-character24 + - story-gen-book-character25 + - story-gen-book-character26 + - story-gen-book-character27 + - story-gen-book-character28 + - story-gen-book-character29 + - story-gen-book-character30 + - story-gen-book-character31 + - story-gen-book-character32 + - story-gen-book-character33 + - story-gen-book-character34 + - story-gen-book-character35 + - story-gen-book-character36 + - story-gen-book-character37 + - story-gen-book-character38 + - story-gen-book-character39 + - story-gen-book-character40 + +- type: dataset + id: book_character_trait + values: + - story-gen-book-character-trait1 + - story-gen-book-character-trait2 + - story-gen-book-character-trait3 + - story-gen-book-character-trait4 + - story-gen-book-character-trait5 + - story-gen-book-character-trait6 + - story-gen-book-character-trait7 + - story-gen-book-character-trait8 + - story-gen-book-character-trait9 + - story-gen-book-character-trait10 + - story-gen-book-character-trait11 + - story-gen-book-character-trait12 + - story-gen-book-character-trait13 + - story-gen-book-character-trait14 + - story-gen-book-character-trait15 + - story-gen-book-character-trait16 + - story-gen-book-character-trait17 + - story-gen-book-character-trait18 + - story-gen-book-character-trait19 + - story-gen-book-character-trait20 + - story-gen-book-character-trait21 + - story-gen-book-character-trait22 + - story-gen-book-character-trait23 + - story-gen-book-character-trait24 + + +- type: dataset + id: book_event + values: + - story-gen-book-event1 + - story-gen-book-event2 + - story-gen-book-event3 + - story-gen-book-event4 + - story-gen-book-event5 + - story-gen-book-event6 + - story-gen-book-event7 + - story-gen-book-event8 + - story-gen-book-event9 + - story-gen-book-event10 + - story-gen-book-event11 + - story-gen-book-event12 + - story-gen-book-event13 + - story-gen-book-event14 + - story-gen-book-event15 + - story-gen-book-event16 + - story-gen-book-event17 + - story-gen-book-event18 + - story-gen-book-event19 + - story-gen-book-event20 + - story-gen-book-event21 + - story-gen-book-event22 + - story-gen-book-event23 + - story-gen-book-event24 + +- type: dataset + id: book_action + values: + - story-gen-book-action1 + - story-gen-book-action2 + - story-gen-book-action3 + - story-gen-book-action4 + - story-gen-book-action5 + - story-gen-book-action6 + - story-gen-book-action7 + - story-gen-book-action8 + - story-gen-book-action9 + - story-gen-book-action10 + - story-gen-book-action11 + - story-gen-book-action12 + +- type: dataset + id: book_action_trait + values: + - story-gen-book-action-trait1 + - story-gen-book-action-trait2 + - story-gen-book-action-trait3 + - story-gen-book-action-trait4 + - story-gen-book-action-trait5 + - story-gen-book-action-trait6 + - story-gen-book-action-trait7 + - story-gen-book-action-trait8 + - story-gen-book-action-trait9 + - story-gen-book-action-trait10 + - story-gen-book-action-trait11 + - story-gen-book-action-trait12 + - story-gen-book-action-trait13 + +- type: dataset + id: book_location + values: + - story-gen-book-location1 + - story-gen-book-location2 + - story-gen-book-location3 + - story-gen-book-location4 + - story-gen-book-location5 + - story-gen-book-location6 + - story-gen-book-location7 + - story-gen-book-location8 + - story-gen-book-location9 + - story-gen-book-location10 + - story-gen-book-location11 + - story-gen-book-location12 + - story-gen-book-location13 + - story-gen-book-location14 + - story-gen-book-location15 + - story-gen-book-location16 + - story-gen-book-location17 + - story-gen-book-location18 + - story-gen-book-location19 + - story-gen-book-location20 + - story-gen-book-location21 + - story-gen-book-location22 + - story-gen-book-location23 + - story-gen-book-location24 + - story-gen-book-location25 + - story-gen-book-location26 + - story-gen-book-location27 + - story-gen-book-location28 + - story-gen-book-location29 + - story-gen-book-location30 + - story-gen-book-location31 + - story-gen-book-location32 + - story-gen-book-location33 + - story-gen-book-location34 + +- type: dataset + id: book_story_element + values: + - story-gen-book-element1 + - story-gen-book-element2 + - story-gen-book-element3 + - story-gen-book-element4 + - story-gen-book-element5 + - story-gen-book-element6 + - story-gen-book-element7 + - story-gen-book-element8 + - story-gen-book-element9 + +- type: dataset + id: book_story_element_trait + values: + - story-gen-book-element-trait1 + - story-gen-book-element-trait2 + - story-gen-book-element-trait3 + - story-gen-book-element-trait4 + - story-gen-book-element-trait5 + - story-gen-book-element-trait6 + - story-gen-book-element-trait7 + - story-gen-book-element-trait8 + - story-gen-book-element-trait9 + - story-gen-book-element-trait10 + - story-gen-book-element-trait11 + - story-gen-book-element-trait12 + - story-gen-book-element-trait13 \ No newline at end of file diff --git a/Resources/Prototypes/DeviceLinking/sink_ports.yml b/Resources/Prototypes/DeviceLinking/sink_ports.yml index f05934f3ba..56b10ec4fc 100644 --- a/Resources/Prototypes/DeviceLinking/sink_ports.yml +++ b/Resources/Prototypes/DeviceLinking/sink_ports.yml @@ -107,3 +107,8 @@ id: SetParticleZeta name: signal-port-name-set-particle-zeta description: signal-port-description-set-particle-zeta + +- type: sinkPort + id: SetParticleSigma + name: signal-port-name-set-particle-sigma + description: signal-port-description-set-particle-sigma diff --git a/Resources/Prototypes/Entities/Clothing/Back/backpacks.yml b/Resources/Prototypes/Entities/Clothing/Back/backpacks.yml index ca926ba18c..a69c770f40 100644 --- a/Resources/Prototypes/Entities/Clothing/Back/backpacks.yml +++ b/Resources/Prototypes/Entities/Clothing/Back/backpacks.yml @@ -248,6 +248,15 @@ - type: Sprite sprite: Clothing/Back/Backpacks/ertclown.rsi +- type: entity + parent: ClothingBackpackERTLeader + id: ClothingBackpackERTChaplain + name: ERT chaplain backpack + description: A spacious backpack with lots of pockets, worn by Chaplains of an Emergency Response Team. + components: + - type: Sprite + sprite: Clothing/Back/Backpacks/ertchaplain.rsi + #Syndicate - type: entity parent: ClothingBackpack diff --git a/Resources/Prototypes/Entities/Clothing/Back/duffel.yml b/Resources/Prototypes/Entities/Clothing/Back/duffel.yml index 2ac53effe6..101599d5ad 100644 --- a/Resources/Prototypes/Entities/Clothing/Back/duffel.yml +++ b/Resources/Prototypes/Entities/Clothing/Back/duffel.yml @@ -167,6 +167,9 @@ sprite: Clothing/Back/Duffels/syndicate.rsi - type: ExplosionResistance damageCoefficient: 0.1 + - type: Storage + grid: + - 0,0,8,4 - type: entity parent: ClothingBackpackDuffelSyndicate diff --git a/Resources/Prototypes/Entities/Clothing/Eyes/glasses.yml b/Resources/Prototypes/Entities/Clothing/Eyes/glasses.yml index e8cf01cb10..24944f02dd 100644 --- a/Resources/Prototypes/Entities/Clothing/Eyes/glasses.yml +++ b/Resources/Prototypes/Entities/Clothing/Eyes/glasses.yml @@ -149,6 +149,11 @@ - type: FlashImmunity - type: EyeProtection protectionTime: 5 + - type: Tag + tags: + - Sunglasses + - HamsterWearable + - WhitelistChameleon - type: entity parent: ClothingEyesBase @@ -163,6 +168,9 @@ - type: FlashImmunity - type: EyeProtection protectionTime: 5 + - type: Construction + graph: GlassesSecHUD + node: glassesSec - type: Tag tags: - HamsterWearable diff --git a/Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml b/Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml index 25f641b1c4..a35cf498f6 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml @@ -571,6 +571,21 @@ Piercing: 0.9 Heat: 0.9 +#ERT Chaplain Hardsuit +- type: entity + parent: ClothingHeadHelmetHardsuitSyndie + id: ClothingHeadHelmetHardsuitERTChaplain + name: ERT chaplain hardsuit helmet + description: A special hardsuit helmet worn by members of an emergency response team. + components: + - type: BreathMask + - type: Sprite + sprite: Clothing/Head/Hardsuits/ERThelmets/ertchaplain.rsi + - type: Clothing + sprite: Clothing/Head/Hardsuits/ERThelmets/ertchaplain.rsi + - type: PointLight + color: "#ffffff" + #ERT Engineer Hardsuit - type: entity parent: ClothingHeadHelmetHardsuitSyndie diff --git a/Resources/Prototypes/Entities/Clothing/Head/helmets.yml b/Resources/Prototypes/Entities/Clothing/Head/helmets.yml index 48aa43fa55..2c5cb54094 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/helmets.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/helmets.yml @@ -147,29 +147,6 @@ Piercing: 0.9 Heat: 0.9 -#SCAF Helmet -- type: entity - parent: ClothingHeadBase - id: ClothingHeadHelmetScaf - name: scaf helmet - description: A robust, strong helmet. - components: - - type: Sprite - sprite: Clothing/Head/Helmets/scaf.rsi - - type: Clothing - sprite: Clothing/Head/Helmets/scaf.rsi - - type: IngestionBlocker - - type: Armor - modifiers: - coefficients: - Blunt: 0.9 - Slash: 0.9 - Piercing: 0.8 - - type: Tag - tags: - - HidesHair - - WhitelistChameleon - #Space Ninja Helmet - type: entity parent: ClothingHeadEVAHelmetBase diff --git a/Resources/Prototypes/Entities/Clothing/Head/misc.yml b/Resources/Prototypes/Entities/Clothing/Head/misc.yml index 3fd55faf26..c7ba6e0b32 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/misc.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/misc.yml @@ -35,31 +35,20 @@ - type: entity parent: ClothingHeadBase - id: ClothingHeadHatFlowerCrown - name: flower crown - description: A coronet of fresh and fragrant flowers. + id: ClothingHeadHatFlowerWreath + name: flower wreath + description: A wreath of colourful flowers. Can be worn both on head and neck. components: - type: Sprite - sprite: Clothing/Head/Misc/flower-crown.rsi + sprite: Clothing/Head/Misc/flower-wreath.rsi - type: Clothing - sprite: Clothing/Head/Misc/flower-crown.rsi + sprite: Clothing/Head/Misc/flower-wreath.rsi + slots: + - HEAD + - neck - type: Construction - graph: flowercrown - node: flowercrown - -- type: entity - parent: ClothingHeadBase - id: ClothingHeadHatHairflower - name: hairflower - description: A red flower for beautiful ladies. - components: - - type: Sprite - sprite: Clothing/Head/Misc/hairflower.rsi - - type: Clothing - sprite: Clothing/Head/Misc/hairflower.rsi - - type: Construction - graph: hairflower - node: hairflower + graph: flowerwreath + node: flowerwreath - type: entity parent: ClothingHeadLightBase diff --git a/Resources/Prototypes/Entities/Clothing/Neck/misc.yml b/Resources/Prototypes/Entities/Clothing/Neck/misc.yml index 6b4be3c9f8..51325c0bbb 100644 --- a/Resources/Prototypes/Entities/Clothing/Neck/misc.yml +++ b/Resources/Prototypes/Entities/Clothing/Neck/misc.yml @@ -79,17 +79,3 @@ event: !type:StethoscopeActionEvent checkCanInteract: false priority: -1 - -- type: entity - parent: ClothingNeckBase - id: ClothingNeckFlowerWreath - name: flower wreath - description: A wreath of colourful flowers. - components: - - type: Sprite - sprite: Clothing/Neck/Misc/flower-wreath.rsi - - type: Clothing - sprite: Clothing/Neck/Misc/flower-wreath.rsi - - type: Construction - graph: flowerwreath - node: flowerwreath diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml index fdaee45ccc..9a1f142740 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml @@ -183,32 +183,6 @@ - type: Clothing sprite: Clothing/OuterClothing/Armor/magusred.rsi -- type: entity - parent: ClothingOuterBaseLarge - id: ClothingOuterArmorScaf - name: scaf suit - description: A green and brown tactical suit for combat situations. - components: - - type: Sprite - sprite: Clothing/OuterClothing/Armor/scaf.rsi - - type: Clothing - sprite: Clothing/OuterClothing/Armor/scaf.rsi - - type: Armor - modifiers: - coefficients: - Blunt: 0.7 - Slash: 0.7 - Piercing: 0.4 - Heat: 0.9 - Caustic: 0.9 - - type: ExplosionResistance - damageCoefficient: 0.8 - - type: GroupExamine - - type: Tag - tags: - - Hardsuit - - WhitelistChameleon - - type: entity parent: ClothingOuterBaseLarge id: ClothingOuterArmorCaptainCarapace diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml index b6aaf23376..e74ace47c8 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml @@ -767,6 +767,20 @@ - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitERTLeader +#ERT Chaplain Hardsuit +- type: entity + parent: ClothingOuterHardsuitJuggernaut + id: ClothingOuterHardsuitERTChaplain + name: ERT chaplain's hardsuit + description: A protective hardsuit worn by the chaplains of an Emergency Response Team. + components: + - type: Sprite + sprite: Clothing/OuterClothing/Hardsuits/ERTSuits/ertchaplain.rsi #if you change this, please update the humanoid.yml with a better markers sprite. + - type: Clothing + sprite: Clothing/OuterClothing/Hardsuits/ERTSuits/ertchaplain.rsi + - type: ToggleableClothing + clothingPrototype: ClothingHeadHelmetHardsuitERTChaplain + #ERT Engineer Hardsuit - type: entity parent: ClothingOuterHardsuitCBURN diff --git a/Resources/Prototypes/Entities/Clothing/Uniforms/jumpsuits.yml b/Resources/Prototypes/Entities/Clothing/Uniforms/jumpsuits.yml index a7ab4d3e23..5eba391786 100644 --- a/Resources/Prototypes/Entities/Clothing/Uniforms/jumpsuits.yml +++ b/Resources/Prototypes/Entities/Clothing/Uniforms/jumpsuits.yml @@ -1093,6 +1093,17 @@ - type: Clothing sprite: Clothing/Uniforms/Jumpsuit/musician.rsi +- type: entity + parent: ClothingUniformBase + id: ClothingUniformJumpsuitERTChaplain + name: ERT chaplain uniform + description: A special suit made for Central Command's elite chaplain corps. + components: + - type: Sprite + sprite: Clothing/Uniforms/Jumpsuit/ert_chaplain.rsi + - type: Clothing + sprite: Clothing/Uniforms/Jumpsuit/ert_chaplain.rsi + - type: entity parent: ClothingUniformBase id: ClothingUniformJumpsuitERTEngineer diff --git a/Resources/Prototypes/Entities/Effects/chemistry_effects.yml b/Resources/Prototypes/Entities/Effects/chemistry_effects.yml index a8e28a1ef7..5b7ee46946 100644 --- a/Resources/Prototypes/Entities/Effects/chemistry_effects.yml +++ b/Resources/Prototypes/Entities/Effects/chemistry_effects.yml @@ -9,6 +9,7 @@ - type: SmokeVisuals - type: Transform anchored: true + - type: Clickable - type: Physics - type: Fixtures fixtures: @@ -76,6 +77,8 @@ animationState: foam-dissolve - type: Slippery - type: StepTrigger + - type: ScoopableSolution + solution: solutionArea - type: entity id: MetalFoam @@ -128,9 +131,10 @@ snap: - Wall components: - - type: Tag - tags: - - RCDDeconstructWhitelist + - type: RCDDeconstructable + cost: 2 + delay: 2 + fx: EffectRCDDeconstruct2 - type: Clickable - type: InteractionOutline - type: Sprite diff --git a/Resources/Prototypes/Entities/Effects/rcd.yml b/Resources/Prototypes/Entities/Effects/rcd.yml index adc6aa593c..902429818e 100644 --- a/Resources/Prototypes/Entities/Effects/rcd.yml +++ b/Resources/Prototypes/Entities/Effects/rcd.yml @@ -1,16 +1,115 @@ - type: entity - id: EffectRCDConstruction + id: EffectRCDBase + abstract: true noSpawn: true components: - type: Transform anchored: True - type: Sprite + snapCardinals: true + noRot: true drawdepth: Effects sprite: /Textures/Effects/rcd.rsi - state: construct - - type: TimedDespawn - lifetime: 3.2 + state: construct0 - type: Tag tags: - HideContextMenu - type: AnimationPlayer + +- type: entity + parent: EffectRCDBase + id: EffectRCDDeconstructPreview + noSpawn: true + components: + - type: Sprite + state: deconstructPreview + +- type: entity + parent: EffectRCDBase + id: EffectRCDConstruct0 + noSpawn: true + components: + - type: Sprite + state: construct0 + - type: TimedDespawn + lifetime: 1.2 + +- type: entity + parent: EffectRCDBase + id: EffectRCDConstruct1 + noSpawn: true + components: + - type: Sprite + state: construct1 + - type: TimedDespawn + lifetime: 2.2 + +- type: entity + parent: EffectRCDBase + id: EffectRCDConstruct2 + noSpawn: true + components: + - type: Sprite + state: construct2 + - type: TimedDespawn + lifetime: 3.2 + +- type: entity + parent: EffectRCDBase + id: EffectRCDConstruct3 + noSpawn: true + components: + - type: Sprite + state: construct3 + - type: TimedDespawn + lifetime: 4.2 + +- type: entity + parent: EffectRCDBase + id: EffectRCDConstruct4 + noSpawn: true + components: + - type: Sprite + state: construct4 + - type: TimedDespawn + lifetime: 5.2 + +- type: entity + parent: EffectRCDBase + id: EffectRCDDeconstruct2 + noSpawn: true + components: + - type: Sprite + state: deconstruct2 + - type: TimedDespawn + lifetime: 3.2 + +- type: entity + parent: EffectRCDBase + id: EffectRCDDeconstruct4 + noSpawn: true + components: + - type: Sprite + state: deconstruct4 + - type: TimedDespawn + lifetime: 5.2 + +- type: entity + parent: EffectRCDBase + id: EffectRCDDeconstruct6 + noSpawn: true + components: + - type: Sprite + state: deconstruct6 + - type: TimedDespawn + lifetime: 7.2 + +- type: entity + parent: EffectRCDBase + id: EffectRCDDeconstruct8 + noSpawn: true + components: + - type: Sprite + state: deconstruct8 + - type: TimedDespawn + lifetime: 9.2 \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Markers/Spawners/Random/Food_Drinks/drinks_glass.yml b/Resources/Prototypes/Entities/Markers/Spawners/Random/Food_Drinks/drinks_glass.yml index 1104214668..ff9e512432 100644 --- a/Resources/Prototypes/Entities/Markers/Spawners/Random/Food_Drinks/drinks_glass.yml +++ b/Resources/Prototypes/Entities/Markers/Spawners/Random/Food_Drinks/drinks_glass.yml @@ -19,6 +19,7 @@ - DrinkAloe - DrinkAndalusia - DrinkAntifreeze + - DrinkArnoldPalmer - DrinkB52Glass - DrinkBahamaMama - DrinkBananaHonkGlass @@ -27,12 +28,15 @@ - DrinkBerryJuice - DrinkBlackRussianGlass - DrinkBlueCuracaoGlass + - DrinkBlueHawaiianGlass - DrinkBloodyMaryGlass - DrinkBooger - DrinkBraveBullGlass - DrinkCarrotJuice + - DrinkCoconutRum - DrinkChocolateGlass - DrinkCognacGlass + - DrinkCosmopolitan - DrinkCubaLibreGlass - DrinkDeadRumGlass - DrinkDevilsKiss @@ -66,15 +70,19 @@ - DrinkMilkshake - DrinkMojito - DrinkNTCahors + - DrinkPainkillerGlass - DrinkPatronGlass + - DrinkPinaColadaGlass - DrinkPoscaGlass - DrinkRedMeadGlass - DrinkRewriter + - DrinkRoyRogersGlass - DrinkRootBeerFloatGlass - DrinkRumGlass - DrinkSakeGlass - DrinkSbitenGlass - DrinkScrewdriverCocktailGlass + - DrinkShirleyTempleGlass - DrinkSuiDreamGlass - DrinkSingulo - DrinkSoyLatte diff --git a/Resources/Prototypes/Entities/Markers/Spawners/Random/Food_Drinks/drinks_soda.yml b/Resources/Prototypes/Entities/Markers/Spawners/Random/Food_Drinks/drinks_soda.yml index c8a941c128..e3339082b3 100644 --- a/Resources/Prototypes/Entities/Markers/Spawners/Random/Food_Drinks/drinks_soda.yml +++ b/Resources/Prototypes/Entities/Markers/Spawners/Random/Food_Drinks/drinks_soda.yml @@ -31,6 +31,7 @@ - DrinkDrGibbCan - DrinkEnergyDrinkCan - DrinkShamblersJuiceCan + - DrinkSolDryCan - DrinkPwrGameCan - DrinkHotCoco - DrinkHotCoffee diff --git a/Resources/Prototypes/Entities/Markers/Spawners/Random/crates.yml b/Resources/Prototypes/Entities/Markers/Spawners/Random/crates.yml index 883182aae8..ae7e5bcf76 100644 --- a/Resources/Prototypes/Entities/Markers/Spawners/Random/crates.yml +++ b/Resources/Prototypes/Entities/Markers/Spawners/Random/crates.yml @@ -44,7 +44,6 @@ - CrateMaterialPlastic - CrateMaterialWood - CrateMaterialPlasteel - - CrateFunSprayPaints - CrateFunArtSupplies - CrateEngineeringCableLV - CrateEngineeringCableMV diff --git a/Resources/Prototypes/Entities/Markers/Spawners/Random/maintenance.yml b/Resources/Prototypes/Entities/Markers/Spawners/Random/maintenance.yml index df61726a99..6419c1aaa1 100644 --- a/Resources/Prototypes/Entities/Markers/Spawners/Random/maintenance.yml +++ b/Resources/Prototypes/Entities/Markers/Spawners/Random/maintenance.yml @@ -77,7 +77,7 @@ - ClothingHeadHatCone - ClothingNeckBling - ClothingHeadHelmetCosmonaut - - ClothingHeadHelmetScaf + - ClothingHeadHelmetBasic - ClothingShoeSlippersDuck - ClothingUnderSocksBee - ClothingUnderSocksCoder @@ -173,12 +173,7 @@ - MaterialCloth10 - MaterialWoodPlank10 - ResearchDisk - - DeathPaint - Plunger - - SprayPaintBlue - - SprayPaintRed - - SprayPaintGreen - - SprayPaintOrange - TechnologyDisk - PowerCellMedium - PowerCellSmall diff --git a/Resources/Prototypes/Entities/Markers/Spawners/jobs.yml b/Resources/Prototypes/Entities/Markers/Spawners/jobs.yml index 012ee18487..7ad8c61956 100644 --- a/Resources/Prototypes/Entities/Markers/Spawners/jobs.yml +++ b/Resources/Prototypes/Entities/Markers/Spawners/jobs.yml @@ -510,6 +510,18 @@ - state: green - state: ertleader +- type: entity + id: SpawnPointERTChaplain + parent: SpawnPointJobBase + name: ERTchaplain + components: + - type: SpawnPoint + job_id: ERTChaplain + - type: Sprite + layers: + - state: green + - state: chaplain + - type: entity id: SpawnPointERTEngineer parent: SpawnPointJobBase diff --git a/Resources/Prototypes/Entities/Markers/construction_ghost.yml b/Resources/Prototypes/Entities/Markers/construction_ghost.yml index d198ebdd51..be9cc915d9 100644 --- a/Resources/Prototypes/Entities/Markers/construction_ghost.yml +++ b/Resources/Prototypes/Entities/Markers/construction_ghost.yml @@ -7,4 +7,4 @@ color: '#3F38' - type: ConstructionGhost - type: Clickable - - type: InteractionOutline + - type: InteractionOutline \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml b/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml index dc6e718290..9ca99f9982 100644 --- a/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml +++ b/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml @@ -1,4 +1,4 @@ -- type: entity +- type: entity parent: BaseMob id: BaseBorgChassis name: cyborg @@ -83,6 +83,7 @@ templateId: borg - type: Hands showInHands: false + disableExplosionRecursion: true - type: IntrinsicRadioReceiver - type: IntrinsicRadioTransmitter channels: @@ -101,8 +102,6 @@ - type: BorgChassis - type: WiresPanel - type: ActivatableUIRequiresPanel - - type: Wires - layoutId: Borg - type: NameIdentifier group: Silicon - type: ContainerContainer @@ -131,6 +130,9 @@ - type: Speech speechVerb: Robotic speechSounds: Pai + - type: Vocal + sounds: + Unsexed: UnisexSilicon - type: UnblockableSpeech - type: Construction graph: Cyborg @@ -140,6 +142,7 @@ - type: Lock locked: true - type: ActivatableUIRequiresLock + - type: LockedWiresPanel - type: Flashable - type: Damageable damageContainer: Silicon diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml b/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml index 3e6c603626..7308267473 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml @@ -70,7 +70,6 @@ tags: - Carp - DoorBumpOpener - - NoPaint - type: ReplacementAccent accent: genericAggressive - type: Speech diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/revenant.yml b/Resources/Prototypes/Entities/Mobs/NPCs/revenant.yml index 4a35f71ac0..68ebf52dc0 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/revenant.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/revenant.yml @@ -93,6 +93,3 @@ - RevenantTheme - type: Speech speechVerb: Ghost - - type: Tag - tags: - - NoPaint diff --git a/Resources/Prototypes/Entities/Mobs/Player/guardian.yml b/Resources/Prototypes/Entities/Mobs/Player/guardian.yml index 9f0d54ee64..c7cd40988d 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/guardian.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/guardian.yml @@ -104,7 +104,6 @@ - type: Tag tags: - CannotSuicide - - NoPaint # From the uplink injector - type: entity @@ -213,7 +212,6 @@ tags: - CannotSuicide - FootstepSound - - NoPaint - type: Inventory templateId: holoclown - type: Hands diff --git a/Resources/Prototypes/Entities/Mobs/Player/humanoid.yml b/Resources/Prototypes/Entities/Mobs/Player/humanoid.yml index b0a2571875..20a6403ae3 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/humanoid.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/humanoid.yml @@ -119,6 +119,66 @@ prototypes: [ ERTLeaderGearEVALecter ] - type: InitialInfectedExempt +## ERT Chaplain + +- type: entity + id: RandomHumanoidSpawnerERTChaplain + parent: RandomHumanoidSpawnerERTLeader + name: ERT chaplain + suffix: ERTRole, Basic + components: + - type: Sprite + sprite: Markers/jobs.rsi + state: chaplain #needs an ERT variant once a good suit it made. + - type: RandomMetadata + nameSegments: + - NamesFirstMilitary + - NamesLastMilitary + - type: RandomHumanoidSpawner + settings: ERTChaplain + +- type: randomHumanoidSettings + id: ERTChaplain + parent: ERTLeader + components: + - type: MindShield + - type: GhostRole + name: ghost-role-information-ert-chaplain-name + description: ghost-role-information-ert-chaplain-description + - type: GhostTakeoverAvailable + - type: RandomMetadata + nameSegments: + - NamesFirstMilitary + - NamesLastMilitary + - type: Loadout + prototypes: [ ERTChaplainGear ] + - type: InitialInfectedExempt + +- type: entity + id: RandomHumanoidSpawnerERTChaplainEVA + parent: RandomHumanoidSpawnerERTChaplain + name: ERT chaplain + suffix: ERTRole, Enviro EVA + components: + - type: Sprite + sprite: Markers/jobs.rsi + state: chaplain #needs an ERT variant once a good suit it made. + - type: RandomHumanoidSpawner + settings: ERTChaplainEVA + +- type: randomHumanoidSettings + id: ERTChaplainEVA + parent: ERTChaplain + components: + - type: MindShield + - type: GhostRole + name: ghost-role-information-ert-chaplain-name + description: ghost-role-information-ert-chaplain-description + - type: GhostTakeoverAvailable + - type: Loadout + prototypes: [ ERTChaplainGearEVA ] + - type: InitialInfectedExempt + ## ERT Janitor - type: entity diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks-cartons.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks-cartons.yml index 67d7954038..84639c9af0 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks-cartons.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks-cartons.yml @@ -112,6 +112,24 @@ - type: Sprite sprite: Objects/Consumable/Drinks/tomatojuice.rsi +- type: entity + parent: [DrinkBottleVisualsOpenable, DrinkBottlePlasticBaseFull] + id: DrinkCoconutWaterCarton + name: coconut water + description: It's the inside of the coconut that counts. + components: + - type: SolutionContainerManager + solutions: + drink: + reagents: + - ReagentId: CoconutWater + Quantity: 50 + - type: Drink + - type: Label + currentLabel: coconut water + - type: Sprite + sprite: Objects/Consumable/Drinks/coconutwater.rsi + - type: entity parent: [DrinkCartonVisualsOpenable, DrinkCartonBaseFull] id: DrinkCreamCarton diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks.yml index bf00dd6327..aac2803dd2 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks.yml @@ -258,6 +258,22 @@ - ReagentId: Antifreeze Quantity: 30 +- type: entity + parent: DrinkGlass + id: DrinkArnoldPalmer + suffix: arnold palmer + components: + - type: SolutionContainerManager + solutions: + drink: + maxVol: 30 + reagents: + - ReagentId: ArnoldPalmer + Quantity: 30 + - type: Icon + sprite: Objects/Consumable/Drinks/arnoldpalmer.rsi + state: icon + - type: entity parent: DrinkGlass id: DrinkAtomicBombGlass @@ -437,6 +453,22 @@ sprite: Objects/Consumable/Drinks/bloodymaryglass.rsi state: icon +- type: entity + parent: DrinkGlass + id: DrinkBlueHawaiianGlass + suffix: blue hawaiian + components: + - type: SolutionContainerManager + solutions: + drink: + maxVol: 30 + reagents: + - ReagentId: BlueHawaiian + Quantity: 30 + - type: Icon + sprite: Objects/Consumable/Drinks/bluehawaiian.rsi + state: icon + - type: entity parent: DrinkGlass id: DrinkBooger @@ -501,6 +533,35 @@ sprite: Objects/Consumable/Drinks/chocolateglass.rsi state: icon +- type: entity + parent: DrinkGlass + id: DrinkCoconutRum + suffix: coconut rum + components: + - type: SolutionContainerManager + solutions: + drink: + maxVol: 30 + reagents: + - ReagentId: CoconutRum + Quantity: 30 + - type: Icon + sprite: Objects/Consumable/Drinks/coconutrum.rsi + state: icon + +- type: entity + parent: DrinkGlass + id: DrinkCoconutWaterGlass + suffix: coconut water + components: + - type: SolutionContainerManager + solutions: + drink: + maxVol: 30 + reagents: + - ReagentId: CoconutWater + Quantity: 30 + - type: entity parent: DrinkGlass id: DrinkCoffee @@ -533,6 +594,22 @@ sprite: Objects/Consumable/Drinks/cognacglass.rsi state: icon +- type: entity + parent: DrinkGlass + id: DrinkCosmopolitan + suffix: cosmopolitan + components: + - type: SolutionContainerManager + solutions: + drink: + maxVol: 30 + reagents: + - ReagentId: Cosmopolitan + Quantity: 30 + - type: Icon + sprite: Objects/Consumable/Drinks/cosmopolitan.rsi + state: icon + - type: entity parent: DrinkGlass id: DrinkCream @@ -1340,6 +1417,22 @@ sprite: Objects/Consumable/Drinks/orangejuice.rsi state: icon +- type: entity + parent: DrinkGlass + id: DrinkPainkillerGlass + suffix: painkiller + components: + - type: SolutionContainerManager + solutions: + drink: + maxVol: 30 + reagents: + - ReagentId: Painkiller + Quantity: 30 + - type: Icon + sprite: Objects/Consumable/Drinks/painkiller.rsi + state: icon + - type: entity parent: DrinkGlass id: DrinkPatronGlass @@ -1356,6 +1449,22 @@ sprite: Objects/Consumable/Drinks/patronglass.rsi state: icon +- type: entity + parent: DrinkGlass + id: DrinkPinaColadaGlass + suffix: piña colada + components: + - type: SolutionContainerManager + solutions: + drink: + maxVol: 30 + reagents: + - ReagentId: PinaColada + Quantity: 30 + - type: Icon + sprite: Objects/Consumable/Drinks/pinacolada.rsi + state: icon + - type: entity parent: DrinkGlass id: DrinkPoisonBerryJuice @@ -1484,6 +1593,22 @@ sprite: Objects/Consumable/Drinks/rumglass.rsi state: icon +- type: entity + parent: DrinkGlass + id: DrinkRoyRogersGlass + suffix: roy rogers + components: + - type: SolutionContainerManager + solutions: + drink: + maxVol: 30 + reagents: + - ReagentId: RoyRogers + Quantity: 30 + - type: Icon + sprite: Objects/Consumable/Drinks/royrogers.rsi + state: icon + - type: entity parent: DrinkGlass id: DrinkSakeGlass @@ -1609,6 +1734,22 @@ sprite: Objects/Consumable/Drinks/glass_white.rsi state: icon +- type: entity + parent: DrinkGlass + id: DrinkShirleyTempleGlass + suffix: shirley temple + components: + - type: SolutionContainerManager + solutions: + drink: + maxVol: 30 + reagents: + - ReagentId: ShirleyTemple + Quantity: 30 + - type: Icon + sprite: Objects/Consumable/Drinks/shirleytemple.rsi + state: icon + - type: entity parent: DrinkGlass id: DrinkSilencerGlass @@ -1641,6 +1782,22 @@ sprite: Objects/Consumable/Drinks/singulo.rsi state: icon +- type: entity + parent: DrinkGlass + id: DrinkSolDryGlass + suffix: sol dry + components: + - type: SolutionContainerManager + solutions: + drink: + maxVol: 30 + reagents: + - ReagentId: SolDry + Quantity: 30 + - type: Icon + sprite: Objects/Consumable/Drinks/sol_dry_glass.rsi + state: icon + - type: entity parent: DrinkGlass id: DrinkSnowWhite diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_bottles.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_bottles.yml index face999df8..e2361cfa6e 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_bottles.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_bottles.yml @@ -789,6 +789,23 @@ - type: Label currentLabel: ice +- type: entity + parent: DrinkBottlePlasticBaseFull + id: DrinkCoconutWaterJug + name: coconut water jug + description: It's on the inside of the coconut that counts. + components: + - type: SolutionContainerManager + solutions: + drink: + maxVol: 300 + reagents: + - ReagentId: CoconutWater + Quantity: 300 + - type: Drink + - type: Label + currentLabel: coconut water + - type: entity parent: DrinkBottlePlasticBaseFull id: DrinkCoffeeJug diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cans.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cans.yml index 2aec576177..585e5ed14d 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cans.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cans.yml @@ -239,6 +239,24 @@ - type: Item sprite: Objects/Consumable/Drinks/space-up.rsi +- type: entity + parent: DrinkCanBaseFull + id: DrinkSolDryCan + name: sol dry + description: Sweet ginger soda from outer space! + components: + - type: SolutionContainerManager + solutions: + drink: + maxVol: 30 + reagents: + - ReagentId: SolDry + Quantity: 30 + - type: Sprite + sprite: Objects/Consumable/Drinks/sol_dry.rsi + - type: Item + sprite: Objects/Consumable/Drinks/sol_dry.rsi + - type: entity parent: DrinkCanBaseFull id: DrinkStarkistCan diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml index 21eb0fb942..3f0277e1bc 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml @@ -1220,6 +1220,10 @@ id: FoodPoppy description: A flower with extracts often used in the production of medicine components: + - type: Clothing + slots: + - HEAD + quickEquip: false - type: FlavorProfile flavors: - medicine diff --git a/Resources/Prototypes/Entities/Objects/Decoration/present.yml b/Resources/Prototypes/Entities/Objects/Decoration/present.yml index 8fdc479351..3fb5675f83 100644 --- a/Resources/Prototypes/Entities/Objects/Decoration/present.yml +++ b/Resources/Prototypes/Entities/Objects/Decoration/present.yml @@ -292,9 +292,9 @@ orGroup: GiftPool - id: ClothingHeadHatBunny orGroup: GiftPool - - id: ClothingHeadHatFlowerCrown + - id: ClothingHeadHatFlowerWreath orGroup: GiftPool - - id: ClothingHeadHatHairflower + - id: FoodPoppy orGroup: GiftPool - id: ClothingMaskClown orGroup: GiftPool diff --git a/Resources/Prototypes/Entities/Objects/Devices/Electronics/door.yml b/Resources/Prototypes/Entities/Objects/Devices/Electronics/door.yml index 275a61d821..16713a6692 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/Electronics/door.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/Electronics/door.yml @@ -7,9 +7,19 @@ - type: Sprite sprite: Objects/Misc/module.rsi state: door_electronics - - type: AccessReader - type: Tag tags: - DoorElectronics + - type: DoorElectronics - type: StaticPrice price: 55 + - type: AccessReader + - type: ActivatableUI + key: enum.DoorElectronicsConfigurationUiKey.Key + allowedItems: + tags: + - Multitool + - type: UserInterface + interfaces: + - key: enum.DoorElectronicsConfigurationUiKey.Key + type: DoorElectronicsBoundUserInterface diff --git a/Resources/Prototypes/Entities/Objects/Devices/Electronics/door_access.yml b/Resources/Prototypes/Entities/Objects/Devices/Electronics/door_access.yml new file mode 100644 index 0000000000..fc6d8e2697 --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/Devices/Electronics/door_access.yml @@ -0,0 +1,264 @@ + +- type: entity + parent: DoorElectronics + id: DoorElectronicsService + suffix: Service, Locked + components: + - type: AccessReader + access: [["Service"]] + +- type: entity + parent: DoorElectronics + id: DoorElectronicsTheatre + suffix: Theatre, Locked + components: + - type: AccessReader + access: [["Theatre"]] + +- type: entity + parent: DoorElectronics + id: DoorElectronicsChapel + suffix: Chapel, Locked + components: + - type: AccessReader + access: [["Chapel"]] + +- type: entity + parent: DoorElectronics + id: DoorElectronicsJanitor + suffix: Janitor, Locked + components: + - type: AccessReader + access: [["Janitor"]] + +- type: entity + parent: DoorElectronics + id: DoorElectronicsKitchen + suffix: Kitchen, Locked + components: + - type: AccessReader + access: [["Kitchen"]] + +- type: entity + parent: DoorElectronics + id: DoorElectronicsBar + suffix: Bar, Locked + components: + - type: AccessReader + access: [["Bar"]] + +- type: entity + parent: DoorElectronics + id: DoorElectronicsHydroponics + suffix: Hydroponics, Locked + components: + - type: AccessReader + access: [["Hydroponics"]] + +- type: entity + parent: DoorElectronics + id: DoorElectronicsCaptain + suffix: Captain, Locked + components: + - type: AccessReader + access: [["Captain"]] + +- type: entity + parent: DoorElectronics + id: DoorElectronicsExternal + suffix: External, Locked + components: + - type: AccessReader + access: [["External"]] + +- type: entity + parent: DoorElectronics + id: DoorElectronicsCargo + suffix: Cargo, Locked + components: + - type: AccessReader + access: [["Cargo"]] + +- type: entity + parent: DoorElectronics + id: DoorElectronicsEngineering + suffix: Engineering, Locked + components: + - type: AccessReader + access: [["Engineering"]] + +- type: entity + parent: DoorElectronics + id: DoorElectronicsAtmospherics + suffix: Atmospherics, Locked + components: + - type: AccessReader + access: [["Atmospherics"]] + +- type: entity + parent: DoorElectronics + id: DoorElectronicsFreezer + suffix: Freezer, Locked + components: + - type: AccessReader + access: [["Kitchen"], ["Hydroponics"]] + +- type: entity + parent: DoorElectronics + id: DoorElectronicsSalvage + suffix: Salvage, Locked + components: + - type: AccessReader + access: [["Salvage"]] + +- type: entity + parent: DoorElectronics + id: DoorElectronicsMedical + suffix: Medical, Locked + components: + - type: AccessReader + access: [["Medical"]] + +- type: entity + parent: DoorElectronics + id: DoorElectronicsChemistry + suffix: Chemistry, Locked + components: + - type: AccessReader + access: [["Chemistry"]] + +- type: entity + parent: DoorElectronics + id: DoorElectronicsResearch + suffix: Research, Locked + components: + - type: AccessReader + access: [["Research"]] + +- type: entity + parent: DoorElectronics + id: DoorElectronicsScience + suffix: Science, Locked + components: + - type: AccessReader + access: [["Research"], ["Medical"]] + +- type: entity + parent: DoorElectronics + id: DoorElectronicsCommand + suffix: Command, Locked + components: + - type: AccessReader + access: [["Command"]] + +- type: entity + parent: DoorElectronics + id: DoorElectronicsChiefMedicalOfficer + suffix: ChiefMedicalOfficer, Locked + components: + - type: AccessReader + access: [["ChiefMedicalOfficer"]] + +- type: entity + parent: DoorElectronics + id: DoorElectronicsChiefEngineer + suffix: ChiefEngineer, Locked + components: + - type: AccessReader + access: [["ChiefEngineer"]] + +- type: entity + parent: DoorElectronics + id: DoorElectronicsHeadOfSecurity + suffix: HeadOfSecurity, Locked + components: + - type: AccessReader + access: [["HeadOfSecurity"]] + +- type: entity + parent: DoorElectronics + id: DoorElectronicsResearchDirector + suffix: ResearchDirector, Locked + components: + - type: AccessReader + access: [["ResearchDirector"]] + +- type: entity + parent: DoorElectronics + id: DoorElectronicsHeadOfPersonnel + suffix: HeadOfPersonnel, Locked + components: + - type: AccessReader + access: [["HeadOfPersonnel"]] + +- type: entity + parent: DoorElectronics + id: DoorElectronicsQuartermaster + suffix: Quartermaster, Locked + components: + - type: AccessReader + access: [["Quartermaster"]] + +- type: entity + parent: DoorElectronics + id: DoorElectronicsSecurity + suffix: Security, Locked + components: + - type: AccessReader + access: [["Security"]] + +- type: entity + parent: DoorElectronics + id: DoorElectronicsDetective + suffix: Detective, Locked + components: + - type: AccessReader + access: [["Detective"]] + +- type: entity + parent: DoorElectronics + id: DoorElectronicsBrig + suffix: Brig, Locked + components: + - type: AccessReader + access: [["Brig"]] + +- type: entity + parent: DoorElectronics + id: DoorElectronicsArmory + suffix: Armory, Locked + components: + - type: AccessReader + access: [["Armory"]] + +- type: entity + parent: DoorElectronics + id: DoorElectronicsVault + suffix: Vault, Locked + components: + - type: AccessReader + access: [["Security", "Command"]] + +- type: entity + parent: DoorElectronics + id: DoorElectronicsMaintenance + suffix: Maintenance, Locked + components: + - type: AccessReader + access: [["Maintenance"]] + +- type: entity + parent: DoorElectronics + id: DoorElectronicsSyndicateAgent + suffix: SyndicateAgent, Locked + components: + - type: AccessReader + access: [["SyndicateAgent"]] + +- type: entity + parent: DoorElectronics + id: DoorElectronicsRnDMed + suffix: Medical/Science, Locked + components: + - type: AccessReader + access: [["Research"], ["Medical"]] diff --git a/Resources/Prototypes/Entities/Objects/Devices/cartridges.yml b/Resources/Prototypes/Entities/Objects/Devices/cartridges.yml index ae454e43a2..e523bbe16e 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/cartridges.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/cartridges.yml @@ -13,7 +13,7 @@ programName: notekeeper-program-name icon: sprite: Objects/Misc/books.rsi - state: book6 + state: book_icon - type: NotekeeperCartridge - type: entity diff --git a/Resources/Prototypes/Entities/Objects/Devices/pda.yml b/Resources/Prototypes/Entities/Objects/Devices/pda.yml index 0056f965a5..73976b48e0 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/pda.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/pda.yml @@ -108,6 +108,7 @@ - type: entity parent: BasePDA id: BaseMedicalPDA + abstract: true components: - type: HealthAnalyzer scanDelay: 1 diff --git a/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_structures.yml b/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_structures.yml index ad4d2eac8a..191bb75e50 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_structures.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_structures.yml @@ -163,9 +163,6 @@ - type: Appearance - type: WiresVisuals - type: WiresPanel - - type: Wires - boardName: wires-board-name-dawinstrument - layoutId: DawInstrument - type: Machine board: DawInstrumentMachineCircuitboard - type: Instrument diff --git a/Resources/Prototypes/Entities/Objects/Fun/darts.yml b/Resources/Prototypes/Entities/Objects/Fun/darts.yml index 391823dc52..4c7ae68420 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/darts.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/darts.yml @@ -53,10 +53,10 @@ solution: melee - type: InjectableSolution solution: melee - - type: SolutionInjectOnCollide + - type: SolutionInjectOnEmbed transferAmount: 2 + solution: melee blockSlots: OUTERCLOTHING - fixtureId: "throw-fixture" - type: SolutionTransfer maxTransferAmount: 2 - type: Damageable @@ -124,10 +124,9 @@ solutions: melee: maxVol: 7 - - type: SolutionInjectOnCollide + - type: SolutionInjectOnEmbed transferAmount: 7 - blockSlots: NONE - fixtureId: "throw-fixture" + solution: melee - type: SolutionTransfer maxTransferAmount: 7 diff --git a/Resources/Prototypes/Entities/Objects/Fun/spray_paint.yml b/Resources/Prototypes/Entities/Objects/Fun/spray_paint.yml deleted file mode 100644 index 1b417f6cde..0000000000 --- a/Resources/Prototypes/Entities/Objects/Fun/spray_paint.yml +++ /dev/null @@ -1,292 +0,0 @@ -# Base Paints -- type: entity - parent: BaseItem - id: PaintBase - name: spray paint - description: A tin of spray paint. - noSpawn: true - components: - - type: Appearance - - type: Sprite - sprite: Objects/Fun/spraycans.rsi - state: clown_cap - layers: - - state: clown_cap - map: ["enum.OpenableVisuals.Layer"] - - type: Paint - consumptionUnit: 10 - blacklist: - tags: - - NoPaint - - type: Item - sprite: Objects/Fun/spraycans.rsi - heldPrefix: spray - - type: SolutionContainerManager - solutions: - drink: - maxVol: 50 - reagents: - - ReagentId: SpaceGlue - Quantity: 50 - - type: TrashOnSolutionEmpty - solution: drink - - type: Sealable - - type: Openable - sound: - path: /Audio/Effects/pop_high.ogg - closeable: true - closeSound: - path: /Audio/Effects/pop_high.ogg - -# Paints - -# funnypaint -- type: entity - parent: PaintBase - id: FunnyPaint - name: funny paint - description: A tin of funny paint, manufactured by Honk! Co. - components: - - type: Paint - color: "#fa74df" - - type: Item - sprite: Objects/Fun/spraycans.rsi - heldPrefix: clown - - type: GenericVisualizer - visuals: - enum.OpenableVisuals.Opened: - enum.OpenableVisuals.Layer: - True: {state: "clown"} - False: {state: "clown_cap"} - -- type: entity - parent: PaintBase - id: FunnyPaintYellow - name: funny paint - description: A tin of funny paint, manufactured by Honk! Co. - components: - - type: Paint - color: "#d5e028" - - type: Item - sprite: Objects/Fun/spraycans.rsi - heldPrefix: clown - - type: Sprite - sprite: Objects/Fun/spraycans.rsi - state: clown2_cap - layers: - - state: clown2_cap - map: ["enum.OpenableVisuals.Layer"] - - type: GenericVisualizer - visuals: - enum.OpenableVisuals.Opened: - enum.OpenableVisuals.Layer: - True: {state: "clown2"} - False: {state: "clown2_cap"} - -#death paint -- type: entity - parent: PaintBase - id: DeathPaint - components: - - type: Paint - color: "#ff20c8" - - type: Item - sprite: Objects/Fun/spraycans.rsi - heldPrefix: spray - - type: Sprite - sprite: Objects/Fun/spraycans.rsi - state: death_cap - layers: - - state: death_cap - map: ["enum.OpenableVisuals.Layer"] - - type: GenericVisualizer - visuals: - enum.OpenableVisuals.Opened: - enum.OpenableVisuals.Layer: - True: {state: "death"} - False: {state: "death_cap"} - -- type: entity - parent: PaintBase - id: DeathPaintTwo - components: - - type: Paint - color: "#ff2020" - - type: Item - sprite: Objects/Fun/spraycans.rsi - heldPrefix: spray - - type: Sprite - sprite: Objects/Fun/spraycans.rsi - state: death2_cap - layers: - - state: death2_cap - map: ["enum.OpenableVisuals.Layer"] - - type: GenericVisualizer - visuals: - enum.OpenableVisuals.Opened: - enum.OpenableVisuals.Layer: - True: {state: "death2"} - False: {state: "death2_cap"} - -#Sprays - -#Blue -- type: entity - parent: PaintBase - id: SprayPaintBlue - suffix: Blue - components: - - type: Sprite - sprite: Objects/Fun/spraycans.rsi - layers: - - state: spray - map: ["Base"] - - state: spray_cap_colors - map: ["enum.OpenableVisuals.Layer"] - color: "#5890f7" - - type: Paint - color: "#5890f7" - - type: GenericVisualizer - visuals: - enum.OpenableVisuals.Opened: - enum.OpenableVisuals.Layer: - True: {state: "spray_colors" , color: "#5890f7"} - False: {state: "spray_cap_colors" , color: "#5890f7"} - -#Red -- type: entity - parent: PaintBase - id: SprayPaintRed - suffix: Red - components: - - type: Sprite - sprite: Objects/Fun/spraycans.rsi - layers: - - state: spray - map: ["Base"] - - state: spray_cap_colors - map: ["enum.OpenableVisuals.Layer"] - color: "#ff3b3b" - - type: Paint - color: "#ff3b3b" - - type: GenericVisualizer - visuals: - enum.OpenableVisuals.Opened: - enum.OpenableVisuals.Layer: - True: {state: "spray_colors" , color: "#ff3b3b"} - False: {state: "spray_cap_colors" , color: "#ff3b3b"} - -#Green -- type: entity - parent: PaintBase - id: SprayPaintGreen - suffix: Green - components: - - type: Sprite - sprite: Objects/Fun/spraycans.rsi - layers: - - state: spray - map: ["Base"] - - state: spray_cap_colors - map: ["enum.OpenableVisuals.Layer"] - color: "#73f170" - - type: Paint - color: "#73f170" - - type: GenericVisualizer - visuals: - enum.OpenableVisuals.Opened: - enum.OpenableVisuals.Layer: - True: {state: "spray_colors" , color: "#73f170"} - False: {state: "spray_cap_colors" , color: "#73f170"} - -#Black -- type: entity - parent: PaintBase - id: SprayPaintBlack - suffix: Black - components: - - type: Sprite - sprite: Objects/Fun/spraycans.rsi - layers: - - state: spray - map: ["Base"] - - state: spray_cap_colors - map: ["enum.OpenableVisuals.Layer"] - color: "#3a3a3a" - - type: Paint - color: "#3a3a3a" - - type: GenericVisualizer - visuals: - enum.OpenableVisuals.Opened: - enum.OpenableVisuals.Layer: - True: {state: "spray_colors" , color: "#3a3a3a"} - False: {state: "spray_cap_colors" , color: "#3a3a3a"} - -#Orange -- type: entity - parent: PaintBase - id: SprayPaintOrange - suffix: Orange - components: - - type: Sprite - sprite: Objects/Fun/spraycans.rsi - layers: - - state: spray - map: ["Base"] - - state: spray_cap_colors - map: ["enum.OpenableVisuals.Layer"] - color: "#f6a44b" - - type: Paint - color: "#f6a44b" - - type: GenericVisualizer - visuals: - enum.OpenableVisuals.Opened: - enum.OpenableVisuals.Layer: - True: {state: "spray_colors" , color: "#f6a44b"} - False: {state: "spray_cap_colors" , color: "#f6a44b"} - -#Purple -- type: entity - parent: PaintBase - id: SprayPaintPurple - suffix: Purple - components: - - type: Sprite - sprite: Objects/Fun/spraycans.rsi - layers: - - state: spray - map: ["Base"] - - state: spray_cap_colors - map: ["enum.OpenableVisuals.Layer"] - color: "#c063f5" - - type: Paint - color: "#c063f5" - - type: GenericVisualizer - visuals: - enum.OpenableVisuals.Opened: - enum.OpenableVisuals.Layer: - True: {state: "spray_colors" , color: "#c063f5"} - False: {state: "spray_cap_colors" , color: "#c063f5"} - -#White -- type: entity - parent: PaintBase - id: SprayPaintWhite - suffix: White - components: - - type: Sprite - sprite: Objects/Fun/spraycans.rsi - layers: - - state: spray - map: ["Base"] - - state: spray_cap_colors - map: ["enum.OpenableVisuals.Layer"] - color: "#f2f2f2" - - type: Paint - color: "#f2f2f2" - - type: GenericVisualizer - visuals: - enum.OpenableVisuals.Opened: - enum.OpenableVisuals.Layer: - True: {state: "spray_colors" , color: "#f2f2f2"} - False: {state: "spray_cap_colors" , color: "#f2f2f2"} diff --git a/Resources/Prototypes/Entities/Objects/Magic/books.yml b/Resources/Prototypes/Entities/Objects/Magic/books.yml index 89acd9e7da..dfb875f677 100644 --- a/Resources/Prototypes/Entities/Objects/Magic/books.yml +++ b/Resources/Prototypes/Entities/Objects/Magic/books.yml @@ -7,7 +7,13 @@ - type: Sprite sprite: Objects/Misc/books.rsi layers: - - state: book_demonomicon + - state: paper_blood + - state: cover_strong + color: "#645a5a" + - state: decor_wingette_flat + color: "#4d0303" + - state: icon_pentagramm + color: "#f7e19f" - type: Spellbook - type: Tag tags: @@ -28,9 +34,19 @@ parent: BaseSpellbook components: - type: Sprite - sprite: Objects/Magic/spellbooks.rsi + sprite: Objects/Misc/books.rsi layers: - - state: bookforcewall + - state: paper + - state: cover_strong + color: "#366ed6" + - state: decor_vertical_middle + color: "#95ffff" + - state: decor_wingette_circle + color: "#95ffff" + - state: icon_magic_forcewall + shader: unshaded + - state: detail_rivets + color: gold - type: Spellbook spells: ActionForceWall: -1 @@ -41,9 +57,17 @@ parent: BaseSpellbook components: - type: Sprite - sprite: Objects/Magic/spellbooks.rsi + sprite: Objects/Misc/books.rsi layers: - - state: spellbook + - state: paper + - state: cover_old + color: "#657e9c" + - state: icon_text3 + - state: decor_wingette_circle + color: gold + - state: icon_magic + - state: detail_rivets + color: gold - type: Spellbook spells: ActionBlink: -1 @@ -53,13 +77,23 @@ name: smite spellbook parent: BaseSpellbook components: - - type: Sprite - sprite: Objects/Magic/spellbooks.rsi - layers: - - state: spellbook - - type: Spellbook - spells: - ActionSmite: -1 + - type: Sprite + sprite: Objects/Misc/books.rsi + layers: + - state: paper + - state: cover_old + color: "#c42b40" + - state: decor_wingette_circle + color: gold + - state: icon_magic + - state: detail_rivets + color: gold + - state: detail_bookmark + color: red + - state: overlay_blood + - type: Spellbook + spells: + ActionSmite: -1 - type: entity id: KnockSpellbook @@ -67,9 +101,18 @@ parent: BaseSpellbook components: - type: Sprite - sprite: Objects/Magic/spellbooks.rsi + sprite: Objects/Misc/books.rsi layers: - - state: bookknock + - state: paper + - state: cover_strong + color: "#117045" + - state: decor_wingette_circle + color: gold + - state: icon_magic_knock + - state: detail_rivets + color: gold + - state: detail_bookmark + color: "#98c495" - type: Spellbook spells: ActionKnock: -1 @@ -79,13 +122,24 @@ name: fireball spellbook parent: BaseSpellbook components: - - type: Sprite - sprite: Objects/Magic/spellbooks.rsi - layers: - - state: bookfireball - - type: Spellbook - spells: - ActionFireball: -1 + - type: Sprite + sprite: Objects/Misc/books.rsi + layers: + - state: paper + - state: cover_old + color: "#ba5a14" + - state: decor_wingette_circle + color: gold + - state: detail_rivets + color: gold + - state: detail_bookmark + color: "#e89b3c" + - state: overlay_blood + - state: icon_magic_fireball + shader: unshaded + - type: Spellbook + spells: + ActionFireball: -1 - type: entity id: ScrollRunes diff --git a/Resources/Prototypes/Entities/Objects/Materials/Sheets/glass.yml b/Resources/Prototypes/Entities/Objects/Materials/Sheets/glass.yml index 2e0eec7a65..59d8ed1922 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/Sheets/glass.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/Sheets/glass.yml @@ -15,7 +15,6 @@ - type: Tag tags: - Sheet - - NoPaint - type: Material - type: Damageable damageContainer: Inorganic diff --git a/Resources/Prototypes/Entities/Objects/Materials/Sheets/metal.yml b/Resources/Prototypes/Entities/Objects/Materials/Sheets/metal.yml index 3a887848bf..82b9f62837 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/Sheets/metal.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/Sheets/metal.yml @@ -15,7 +15,6 @@ tags: - Sheet - Metal - - NoPaint - type: Damageable damageContainer: Inorganic damageModifierSet: Metallic diff --git a/Resources/Prototypes/Entities/Objects/Materials/Sheets/other.yml b/Resources/Prototypes/Entities/Objects/Materials/Sheets/other.yml index 9dc87a9117..dfb5133628 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/Sheets/other.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/Sheets/other.yml @@ -12,7 +12,6 @@ - type: Tag tags: - Sheet - - NoPaint - type: Damageable damageContainer: Inorganic - type: Destructible @@ -111,7 +110,6 @@ - type: Tag tags: - Sheet - - NoPaint - type: entity parent: SheetPlasma @@ -134,7 +132,6 @@ tags: - Plastic - Sheet - - NoPaint - type: Material - type: PhysicalComposition materialComposition: diff --git a/Resources/Prototypes/Entities/Objects/Materials/materials.yml b/Resources/Prototypes/Entities/Objects/Materials/materials.yml index 2bfd409c30..d11df5d94e 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/materials.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/materials.yml @@ -12,7 +12,6 @@ - type: Tag tags: - RawMaterial - - NoPaint - type: Damageable damageContainer: Inorganic - type: Destructible diff --git a/Resources/Prototypes/Entities/Objects/Misc/books.yml b/Resources/Prototypes/Entities/Objects/Misc/books.yml index ab6beb70af..78f9edc9c5 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/books.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/books.yml @@ -7,8 +7,17 @@ - type: Sprite sprite: Objects/Misc/books.rsi layers: - - state: book0 - map: [ "enum.DamageStateVisualLayers.Base" ] + - state: paper + - state: cover_base + color: "#332d27" + map: [ "cover" ] + - state: decor_wingette + color: "#453f3a" + map: [ "decor" ] + - state: icon_text + map: [ "icon" ] + - state: overlay_null + map: [ "overlay" ] - type: Paper contentSize: 12000 - type: ActivatableUI @@ -35,7 +44,15 @@ - type: Sprite sprite: Objects/Misc/books.rsi layers: - - state: book0 # placeholder(?). if only we have a better sprite that fits this. + - state: paper + - state: cover_base + color: "#0a2a6b" + - state: decor_wingette + color: "#082561" + - state: icon_text + color: gold + - state: icon_planet + color: "#42b6f5" - type: Tag tags: - Book @@ -53,7 +70,15 @@ - type: Sprite sprite: Objects/Misc/books.rsi layers: - - state: book7 + - state: paper + - state: cover_base + color: black + - state: decor_wingette + color: "#bbbbbb" + - state: icon_glow + color: red + - state: icon_corner + color: red - type: Tag tags: - Book @@ -71,7 +96,12 @@ - type: Sprite sprite: Objects/Misc/books.rsi layers: - - state: book_bar + - state: paper + - state: cover_base + color: "#004848" + - state: decor_wingette + color: "#006666" + - state: icon_bar - type: Tag tags: - Book @@ -89,7 +119,11 @@ - type: Sprite sprite: Objects/Misc/books.rsi layers: - - state: book_cooking + - state: paper + - state: cover_base + color: "#e22541" + - state: decor_wingette + - state: icon_apple - type: Tag tags: - Book @@ -107,7 +141,14 @@ - type: Sprite sprite: Objects/Misc/books.rsi layers: - - state: book_hydroponics_pod_people + - state: paper + - state: cover_base + color: "#0e5a24" + - state: decor_wingette + color: "#2fa151" + - state: icon_cabbage + - state: icon_corner + color: gold - type: Tag tags: - Book @@ -125,7 +166,14 @@ - type: Sprite sprite: Objects/Misc/books.rsi layers: - - state: book_engineering + - state: paper + - state: cover_base + color: "#6c4718" + - state: decor_wingette + color: "#b5913c" + - state: icon_wrench + - state: icon_corner + color: gold - type: Tag tags: - Book @@ -143,7 +191,12 @@ - type: Sprite sprite: Objects/Misc/books.rsi layers: - - state: book_science + - state: paper + - state: cover_base + color: "#542485" + - state: decor_wingette_circle + color: "#be69f0" + - state: icon_dna - type: Tag tags: - Book @@ -161,7 +214,12 @@ - type: Sprite sprite: Objects/Misc/books.rsi layers: - - state: book_security + - state: paper + - state: cover_base + color: "#ab1515" + - state: decor_wingette + color: "#e05334" + - state: icon_stunbaton - type: Tag tags: - Book @@ -184,7 +242,11 @@ - type: Sprite sprite: Objects/Misc/books.rsi layers: - - state: book0 # no janitorial book sprite so this is a placeholder + - state: paper + - state: cover_base + color: "#550c82" + - state: decor_wingette + - state: icon_bucket - type: Tag tags: - Book @@ -202,7 +264,15 @@ - type: Sprite sprite: Objects/Misc/books.rsi layers: - - state: book0 # no salvage book sprite so this is a placeholder + - state: paper + - state: cover_base + color: "#52320b" + - state: decor_wingette + color: "#e69a3e" + - state: icon_glow + - state: icon_diamond + - state: icon_text + color: "#fcdf74" - type: Tag tags: - Book @@ -220,7 +290,13 @@ - type: Sprite sprite: Objects/Misc/books.rsi layers: - - state: book_medical + - state: paper + - state: cover_base + color: "#cccccc" + - state: decor_wingette + color: "#f7f7f7" + - state: icon_medical + color: "#58abcc" - type: Tag tags: - Book @@ -238,7 +314,15 @@ - type: Sprite sprite: Objects/Misc/books.rsi layers: - - state: book_engineering + - state: paper + - state: cover_old + color: "#6c4718" + - state: decor_wingette + color: "#b5913c" + - state: icon_glow + color: red + - state: icon_wrench + - state: overlay_blood - type: Tag tags: - Book @@ -256,7 +340,12 @@ - type: Sprite sprite: Objects/Misc/books.rsi layers: - - state: book_chemistry + - state: paper + - state: cover_base + color: "#2a7b74" + - state: decor_wingette + color: "#2a7b74" + - state: icon_chemical - type: Tag tags: - Book @@ -268,69 +357,120 @@ - type: entity parent: BookBase id: BookRandom - suffix: random + suffix: random visual + description: Each book is unique! What is hidden in this one? components: + - type: RandomMetadata + nameSegments: + - book_hint_appearance + - book_type - type: RandomSprite available: - - enum.DamageStateVisualLayers.Base: - book0: "" - book1: "" - book2: "" - book3: "" - book4: "" - book5: "" - book6: "" - book7: "" - book8: "" + - cover: + cover_base: Sixteen + cover_old: Sixteen + cover_strong: Sixteen + decor: + decor_wingette: Sixteen + decor_wingette_circle: Sixteen + decor_bottom: Sixteen + decor_middle: Sixteen + decor_spine: Sixteen + decor_diagonal: Sixteen + decor_vertical_middle: Sixteen + icon_corner: Sixteen + icon_mount: "" + icon: + icon_biohazard: Sixteen + icon_borg: "" + icon_banana: "" + icon_glow: Sixteen + icon_hacking: "" + icon_law: Sixteen + icon_magnifier: "" + icon_nuclear: "" + icon_time: Sixteen + icon_aurora: Sixteen + icon_briefcase: "" + icon_eye: "" + icon_letter_N: "" + icon_letter_P: "" + icon_lightning: "" + icon_planet: "" + icon_possum: "" + icon_question: Sixteen + icon_scmmd: "" + icon_stars: Sixteen + icon_stars2: Sixteen + icon_temple: Sixteen + icon_tree: "" + icon_pentagramm: Sixteen + icon_fish: "" + icon_origami: "" + icon_skull: "" + icon_text: "" + icon_text2: "" + icon_text3: "" + overlay: + overlay_blood: "" + overlay_dirt: Sixteen + detail_bookmark: Sixteen + detail_rivets: Sixteen + overlay_null: "" - type: entity - parent: BookBase - id: BookEscalation - name: Robert's Rules of Escalation - description: The book is stained with blood. It seems to have been used more as a weapon than reading material. + parent: BookRandom + id: BookRandomStory + suffix: random visual, random story components: - - type: Sprite - sprite: Objects/Misc/books.rsi - layers: - - state: book2 - - type: MeleeWeapon - wideAnimationRotation: 180 - damage: - types: - Blunt: 6 - - type: Paper - content: book-text-escalation - -- type: entity - parent: BookBase - id: BookEscalationSecurity - name: "Robert's Rules of Escalation: Security Edition" - description: The book is stained with blood. It seems to have been used more as a weapon than reading material. - components: - - type: Sprite - sprite: Objects/Misc/books.rsi - layers: - - state: book2 - - type: MeleeWeapon - wideAnimationRotation: 180 - damage: - types: - Blunt: 6 - - type: Paper - content: book-text-escalation-security - + - type: PaperRandomStory + storySegments: + - "This is a " + - book_genre + - " about a " + - book_character_trait + - " " + - book_character + - " and " + - book_character_trait + - " " + - book_character + - ". Due to " + - book_event + - ", they " + - book_action_trait + - " " + - book_action + - " " + - book_character + - " " + - book_location + - ". \n\n" + - book_story_element + - " is " + - book_story_element_trait + - "." + storySeparator: "" + - type: entity parent: BookBase id: BookAtmosDistro name: "Newton's Guide to Atmos: The Distro" description: There are endless illegible notes scribbled in the margins. Most of the text is covered in handwritten question marks. components: - - type: Sprite - sprite: Objects/Misc/books.rsi - layers: - - state: book5 - - type: Paper - content: book-text-atmos-distro + - type: Sprite + sprite: Objects/Misc/books.rsi + layers: + - state: paper + - state: cover_base + color: "#366ed6" + - state: decor_wingette + color: "#2739b0" + - state: icon_atmos + - state: icon_corner + color: gold + - type: Paper + content: book-text-atmos-distro - type: entity parent: BookBase @@ -338,12 +478,19 @@ name: "Newton's Guide to Atmos: Waste" description: There are endless illegible notes scribbled in the margins. Most of the text is covered in handwritten question marks. components: - - type: Sprite - sprite: Objects/Misc/books.rsi - layers: - - state: book5 - - type: Paper - content: book-text-atmos-waste + - type: Sprite + sprite: Objects/Misc/books.rsi + layers: + - state: paper + - state: cover_base + color: "#db233f" + - state: decor_wingette + color: "#ab0730" + - state: icon_atmos + - state: icon_corner + color: gold + - type: Paper + content: book-text-atmos-waste - type: entity parent: BookBase @@ -351,12 +498,19 @@ name: "Newton's Guide to Atmos: Air Alarms" description: There are endless illegible notes scribbled in the margins. Most of the text is covered in handwritten question marks. components: - - type: Sprite - sprite: Objects/Misc/books.rsi - layers: - - state: book5 - - type: Paper - content: book-text-atmos-alarms + - type: Sprite + sprite: Objects/Misc/books.rsi + layers: + - state: paper + - state: cover_base + color: "#bfb328" + - state: decor_wingette + color: "#9c7c14" + - state: icon_atmos + - state: icon_corner + color: gold + - type: Paper + content: book-text-atmos-alarms - type: entity parent: BookBase @@ -364,9 +518,16 @@ name: "Newton's Guide to Atmos: Vents and More" description: There are endless illegible notes scribbled in the margins. Most of the text is covered in handwritten question marks. components: - - type: Sprite - sprite: Objects/Misc/books.rsi - layers: - - state: book5 - - type: Paper - content: book-text-atmos-vents + - type: Sprite + sprite: Objects/Misc/books.rsi + layers: + - state: paper + - state: cover_base + color: "#3ec78e" + - state: decor_wingette + color: "#28a15a" + - state: icon_atmos + - state: icon_corner + color: gold + - type: Paper + content: book-text-atmos-vents \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Objects/Misc/authorbooks.yml b/Resources/Prototypes/Entities/Objects/Misc/books_author.yml similarity index 68% rename from Resources/Prototypes/Entities/Objects/Misc/authorbooks.yml rename to Resources/Prototypes/Entities/Objects/Misc/books_author.yml index 70d984240e..9adb14f4eb 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/authorbooks.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/books_author.yml @@ -5,9 +5,19 @@ description: The book is an old, leather-bound tome with intricate engravings on the cover. The pages are yellowed and fragile with age, with the ink of the text faded in some places. It appears to have been well-read and well-loved, with dog-eared pages and marginalia scrawled in the margins. Despite its aged appearance, the book still exudes a sense of mystical power and wonder, hinting at the secrets and knowledge contained within its pages. components: - type: Sprite - sprite: Objects/Misc/authorbooks.rsi + sprite: Objects/Misc/books.rsi layers: - - state: book_narsie_legend + - state: paper + - state: cover_old + color: "#a6161d" + - state: decor_bottom + color: "#6e1022" + - state: decor_wingette + color: "#4a101b" + - state: icon_pentagramm + color: "#911129" + - state: detail_bookmark + color: red - type: Paper content: book-text-narsielegend @@ -18,9 +28,18 @@ description: A book exploring the different philosophical perspectives on truth and lying has a worn cover, with creases and marks indicating frequent use and thoughtful contemplation. The spine shows signs of wear from being pulled off the shelf again and again. The pages themselves are filled with underlines, notes in the margins, and highlighted passages as readers grapple with the nuances and complexities of the topic. components: - type: Sprite - sprite: Objects/Misc/authorbooks.rsi + sprite: Objects/Misc/books.rsi layers: - - state: book_truth + - state: paper + - state: cover_strong + color: "#c9752a" + - state: decor_diagonal + color: "#cf792d" + - state: decor_wingette_circle + color: gold + - state: icon_question + - state: detail_bookmark + color: "#cf792d" - type: Paper content: book-text-truth @@ -31,9 +50,15 @@ description: The book is a well-preserved hardcover with a simple, elegant design on the cover, depicting the image of a world in motion. The pages are crisp and clean, with no signs of wear or tear, suggesting that it has been well-cared for and valued by its previous owner. The text is printed in a clear, legible font, and the chapters are organized in a logical and easy-to-follow manner, making it accessible to readers of all levels of expertise. components: - type: Sprite - sprite: Objects/Misc/authorbooks.rsi + sprite: Objects/Misc/books.rsi layers: - - state: book_world + - state: paper + - state: cover_base + color: "#215e9e" + - state: icon_planet + - state: icon_text + - state: detail_bookmark + color: "#2dab24" - type: Paper content: book-text-world @@ -44,9 +69,16 @@ description: The book is a small paperback in good condition, with an illustration of Ian the corgi and the colony of penguins on the cover. The title, "Ian and Robert's Antarctic Adventure", is written in bold white letters against a blue background. The back cover features a brief summary of the story, highlighting the themes of humility, resilience, and the beauty of nature. components: - type: Sprite - sprite: Objects/Misc/authorbooks.rsi + sprite: Objects/Misc/books.rsi layers: - - state: book_ian_antarctica + - state: paper + - state: cover_base + color: "#5779c9" + - state: icon_stars2 + - state: decor_bottom + - state: icon_ian + - state: detail_bookmark + color: "#ab5e24" - type: Paper content: book-text-ian-antarctica @@ -57,9 +89,18 @@ description: The book looks new, with a glossy cover featuring Chuckles the clown and Snuggles the sloth floating in space with a backdrop of stars and planets. Chuckles is dressed in his banana costume and Snuggles is sleeping on a hammock made of space ropes. The title "The Sloth and the Clown - Space Station Shenanigans" is written in bold and colorful letters. components: - type: Sprite - sprite: Objects/Misc/authorbooks.rsi + sprite: Objects/Misc/books.rsi layers: - - state: book_scsss + - state: paper + - state: cover_base + color: "#e838b9" + - state: decor_wingette + color: "#ab22ba" + - state: decor_spine + color: "#f7cc2f" + - state: icon_banana + - state: detail_bookmark + color: "#f7cc2f" - type: Paper content: book-text-sloth-clown-sss @@ -70,9 +111,18 @@ description: The book is in excellent condition, with crisp pages and a bright cover. The cover of the book features Chuckles and Snuggles, surrounded by the different species they encountered during their adventures in space. In the background, the Zorgs can be seen peeking out from behind a spaceship. components: - type: Sprite - sprite: Objects/Misc/authorbooks.rsi + sprite: Objects/Misc/books.rsi layers: - - state: book_scpz + - state: paper + - state: cover_base + color: "#f7cc2f" + - state: decor_wingette + color: "#ab22ba" + - state: decor_spine + color: "#e838b9" + - state: icon_banana + - state: detail_bookmark + color: "#ab22ba" - type: Paper content: book-text-sloth-clown-pz @@ -83,9 +133,18 @@ description: The book looks new and vibrant, with an image of Chuckles and Snuggles standing in front of the changing maze on the cover. The title "The Sloth and the Clown - Maze Maze Danger" is written in bold, colorful letters that pop against a background of space and stars. components: - type: Sprite - sprite: Objects/Misc/authorbooks.rsi + sprite: Objects/Misc/books.rsi layers: - - state: book_scmmd + - state: paper + - state: cover_base + color: "#e838b9" + - state: decor_wingette + color: "#ab22ba" + - state: decor_spine + color: "#f7cc2f" + - state: icon_scmmd + - state: detail_bookmark + color: "#ab22ba" - type: Paper content: book-text-sloth-clown-mmd @@ -96,9 +155,21 @@ description: The cover of the book is an electrifying image of lightning striking the ground, with a silhouette of a person standing in the midst of it. The title is written in bold letters in white against a black background, conveying the power and intensity of the experience. The subtitle is written in smaller letters below the title, providing a hint of the philosophical and spiritual themes explored within. components: - type: Sprite - sprite: Objects/Misc/authorbooks.rsi + sprite: Objects/Misc/books.rsi layers: - - state: book_struck + - state: paper + - state: cover_strong + color: "#2c384d" + - state: decor_wingette + color: "#3a4a66" + - state: decor_wingette_circle + color: "#6d7c9c" + - state: icon_glow + color: "#f7bb2f" + - state: icon_lightning + color: "#f7bb2f" + - state: detail_bookmark + color: "#f7bb2f" - type: Paper content: book-text-struck @@ -109,9 +180,20 @@ description: The book is new, with a bright and vibrant cover featuring a plant stretching its leaves towards the sun. The title, "Reaching for the Sun - A Plant's Quest for Life," is written in bold, green letters, with an image of the sun rising behind the plant. The cover evokes a sense of growth, energy, and the beauty of nature. components: - type: Sprite - sprite: Objects/Misc/authorbooks.rsi + sprite: Objects/Misc/books.rsi layers: - - state: book_sun + - state: paper + - state: cover_base + color: "#255c8a" + - state: decor_bottom + color: "#2d2e12" + - state: icon_glow + color: "#f7bb2f" + - state: icon_cabbage + - state: detail_bookmark + color: "#f7bb2f" + - state: detail_rivets + color: "#f7bb2f" - type: Paper content: book-text-sun @@ -122,9 +204,15 @@ description: The book is in good condition, with a hardcover and a dark green forest background. In the center of the cover, there is a sad looking possum sitting on a branch, with a distant and lonely expression on its face. The title, "Fallen Ambitions - The Tragic Tale of Morty the Possum," is written in bold, gold letters above the possum. components: - type: Sprite - sprite: Objects/Misc/authorbooks.rsi + sprite: Objects/Misc/books.rsi layers: - - state: book_possum + - state: paper + - state: cover_old + color: "#a3bfae" + - state: icon_possum + - state: detail_bookmark + color: "#2b593d" + - state: overlay_blood - type: Paper content: book-text-possum @@ -135,9 +223,14 @@ description: The book is in new condition, with a vibrant and whimsical cover that features a charming illustration of a tiny possum peeking out from behind a coffee cup, with a colorful and bustling cafe scene in the background. The title "The Cafe Possum" is written in bold, playful lettering, and the author's name is printed in a smaller font below it. components: - type: Sprite - sprite: Objects/Misc/authorbooks.rsi + sprite: Objects/Misc/books.rsi layers: - - state: book_cafe + - state: paper + - state: cover_strong + color: "#e8ab6d" + - state: icon_possum + - state: detail_bookmark + color: "#2b593d" - type: Paper content: book-text-cafe @@ -150,7 +243,15 @@ - type: Sprite sprite: Objects/Misc/books.rsi layers: - - state: book4 + - state: paper + - state: cover_strong + color: "#abebed" + - state: decor_wingette + color: "#a081cc" + - state: icon_atmos + - state: icon_magic + - state: detail_bookmark + color: "#7396f5" - type: Paper content: book-text-feather @@ -161,9 +262,16 @@ description: The book is a new condition with a colorful cover, depicting Ian the corgi and Renault the fox on a journey through the forest, with the lost wolf pup to their feet. The title "The Adventures of Ian and Renault - Finding the Lost Wolf Pup" is prominently displayed at the top, with the author's name below. The cover has a whimsical and adventurous feel to it, attracting readers of all ages. components: - type: Sprite - sprite: Objects/Misc/authorbooks.rsi + sprite: Objects/Misc/books.rsi layers: - - state: book_ian_wolfpup + - state: paper + - state: cover_base + color: "#3a9e57" + - state: decor_bottom + color: "#1c6330" + - state: icon_ian + - state: detail_bookmark + color: "#ab5e24" - type: Paper content: book-text-ian-wolfpup @@ -174,9 +282,16 @@ description: The book appears to be new, with crisp pages and an unblemished cover. The cover features a colorful illustration of Ian and Renault, surrounded by various animals they encountered on the ranch, including horses, cows, and chickens. The title, "The Adventures of Ian and Renault - Ranch Expedition," is written in bold letters above the image, with the subtitle, "Helping Animals in Need," written below. components: - type: Sprite - sprite: Objects/Misc/authorbooks.rsi + sprite: Objects/Misc/books.rsi layers: - - state: book_ian_ranch + - state: paper + - state: cover_base + color: "#ccab64" + - state: decor_bottom + color: "#946e38" + - state: icon_ian + - state: detail_bookmark + color: "#ab5e24" - type: Paper content: book-text-ian-ranch @@ -187,9 +302,16 @@ description: The book is new and in excellent condition. The cover shows Ian and Renault running and playing on the beach, with the blue ocean and golden sand in the background. The title is written in bold, playful letters, and the subtitle reads "An Ocean Adventure." components: - type: Sprite - sprite: Objects/Misc/authorbooks.rsi + sprite: Objects/Misc/books.rsi layers: - - state: book_ian_ocean + - state: paper + - state: cover_base + color: "#567cd6" + - state: decor_bottom + color: "#272782" + - state: icon_ian + - state: detail_bookmark + color: "#ab5e24" - type: Paper content: book-text-ian-ocean @@ -200,9 +322,15 @@ description: The book is in new condition. The cover is a stunning mountain landscape with Ian and Renault in the foreground, looking out over the vista of the surrounding peaks and valleys. The title is written in bold, block letters at the top, with the subtitle, "A Mountain Expedition," written underneath. components: - type: Sprite - sprite: Objects/Misc/authorbooks.rsi + sprite: Objects/Misc/books.rsi layers: - - state: book_ian_mountain + - state: paper + - state: cover_base + color: "#86b4d9" + - state: icon_mount + - state: icon_ian + - state: detail_bookmark + color: "#ab5e24" - type: Paper content: book-text-ian-mountain @@ -213,9 +341,16 @@ description: The book is in new condition, with crisp pages and a glossy cover. The cover features a colorful illustration of Ian and Renault exploring the city, with tall buildings and bustling streets in the background. Ian is leading the way, with his tail wagging excitedly, while Renault follows close behind, her ears perked up and her eyes wide with wonder. The title, "The Adventures of Ian and Renault," is written in bold, playful letters, with the subtitle, "Exploring the City," written below in smaller font. components: - type: Sprite - sprite: Objects/Misc/authorbooks.rsi + sprite: Objects/Misc/books.rsi layers: - - state: book_ian_city + - state: paper + - state: cover_base + color: "#9a9b9c" + - state: decor_bottom + color: "#5f6061" + - state: icon_ian + - state: detail_bookmark + color: "#ab5e24" - type: Paper content: book-text-ian-city @@ -226,9 +361,16 @@ description: The book looks new and adventurous, with a picture of Ian and Renault standing in front of an icy landscape with snowflakes falling all around them. The title, "The Adventures of Ian and Renault," is written in bold letters at the top, with a subtitle that reads, "An Arctic Journey of Courage and Friendship." components: - type: Sprite - sprite: Objects/Misc/authorbooks.rsi + sprite: Objects/Misc/books.rsi layers: - - state: book_ian_arctic + - state: paper + - state: cover_base + color: "#5779c9" + - state: icon_stars2 + - state: decor_bottom + - state: icon_ian + - state: detail_bookmark + color: "#ab5e24" - type: Paper content: book-text-ian-arctic @@ -239,9 +381,16 @@ description: The book is in new condition and would have a colorful cover depicting Ian and Renault against a desert backdrop. The cover would feature images of various animals and plants that the two encountered on their adventure, such as a rattlesnake, coyotes, sand dunes, and an oasis. The title, "The Adventures of Ian and Renault" is prominently displayed on the cover in bold letters, while the subtitle "Exploring the Mysterious Desert" is written in smaller letters underneath. components: - type: Sprite - sprite: Objects/Misc/authorbooks.rsi + sprite: Objects/Misc/books.rsi layers: - - state: book_ian_desert + - state: paper + - state: cover_base + color: "#507bad" + - state: decor_bottom + color: "#bd9a55" + - state: icon_ian + - state: detail_bookmark + color: "#ab5e24" - type: Paper content: book-text-ian-desert @@ -252,9 +401,15 @@ description: The book is a gently used philosophy text, with a cover that features a close-up of a person's mouth, with the word "names" written on their lips. The title is "The Power of Names - A Philosophical Exploration," and the author's name is prominently displayed underneath. The overall design is simple and elegant, with the focus on the text rather than any flashy graphics or images. components: - type: Sprite - sprite: Objects/Misc/authorbooks.rsi + sprite: Objects/Misc/books.rsi layers: - - state: book_names + - state: paper + - state: cover_base + color: "#8c8c8c" + - state: decor_wingette_circle + - state: icon_letter_N + - state: detail_bookmark + - state: overlay_dirt - type: Paper content: book-text-names @@ -265,9 +420,19 @@ description: The book is in good condition, with a slightly faded cover due to exposure to sunlight. The cover of the book depicts a panoramic view of the Earth from space, with a bright blue ocean and green landmasses. In the foreground, a lone astronaut is seen sitting in front of a window, gazing wistfully at the Earth. The title of the book, "Earthly Longing," is written in bold white letters against a black background at the top of the cover. components: - type: Sprite - sprite: Objects/Misc/authorbooks.rsi + sprite: Objects/Misc/books.rsi layers: - - state: book_earth + - state: paper + - state: cover_strong + color: "#0f204f" + - state: decor_wingette_circle + color: "#2c5491" + - state: decor_vertical_middle + color: "#3c6ab0" + - state: icon_planet + - state: icon_text3 + - state: detail_bookmark + color: "#2c5491" - type: Paper content: book-text-earth @@ -278,9 +443,21 @@ description: The book is in excellent condition, with a shiny cover depicting a spaceship hovering above a planet, perhaps with the Earth in the background. The title "Journey Beyond - The Starship Aurora Mission" is written in bold, silver letters. The cover also features a quote from a review, "A breathtaking tale of human achievement and exploration" to entice potential readers. components: - type: Sprite - sprite: Objects/Misc/authorbooks.rsi + sprite: Objects/Misc/books.rsi layers: - - state: book_aurora + - state: paper + - state: cover_base + color: "#0f204f" + - state: decor_vertical_middle + color: "#3c6ab0" + - state: decor_spine + color: "#3c6ab0" + - state: icon_stars2 + - state: icon_aurora + - state: detail_bookmark + color: "#2c5491" + - state: detail_rivets + color: "#799dd4" - type: Paper content: book-text-aurora @@ -291,9 +468,18 @@ description: The book appears new with crisp pages and an uncreased spine. The cover features an image of a temple with a glowing, multicolored aura around it, symbolizing the various gods discussed in the book. The title is displayed prominently in gold lettering, with the author's name and a brief summary of the book written in smaller text below. components: - type: Sprite - sprite: Objects/Misc/authorbooks.rsi + sprite: Objects/Misc/books.rsi layers: - - state: book_temple + - state: paper + - state: cover_base + color: "#542e80" + - state: decor_vertical_middle + color: "#39205e" + - state: decor_wingette_circle + color: "#914fb8" + - state: icon_temple + - state: detail_bookmark + color: "#bfbfbf" - type: Paper content: book-text-temple @@ -304,9 +490,18 @@ description: The book is in good condition, with a slightly worn cover that features a dark and ominous space station looming in the background. The title "Watched" is written in bold letters that seem to be staring back at the reader, conveying the feeling of being constantly observed. The blurb on the back cover hints at a thrilling and suspenseful tale of paranoia and danger in a confined setting. components: - type: Sprite - sprite: Objects/Misc/authorbooks.rsi + sprite: Objects/Misc/books.rsi layers: - - state: book_watched + - state: paper + - state: cover_base + color: "#611e10" + - state: overlay_dirt + color: "#4f1206" + - state: decor_wingette_circle + color: "#241e1d" + - state: icon_eye + - state: detail_bookmark + color: "#bfbfbf" - type: Paper content: book-text-watched @@ -317,9 +512,17 @@ description: The cover features Smith, the medical officer, in his uniform, looking determined and ready to face any challenge. The backdrop shows the SS Horizon under attack, with explosions and smoke filling the space station. In the foreground, a wizard with a staff can be seen, adding an element of mystery and intrigue to the scene. The title is prominently displayed in bold letters, with the author's name and a tagline indicating the book's action-packed and suspenseful nature. components: - type: Sprite - sprite: Objects/Misc/authorbooks.rsi + sprite: Objects/Misc/books.rsi layers: - - state: book_medical + - state: paper + - state: cover_base + color: "#d7dadb" + - state: decor_wingette_circle + color: "#55b0d4" + - state: icon_medical_cross + color: "#55b0d4" + - state: detail_bookmark + color: "#55b0d4" - type: Paper content: book-text-medical-officer @@ -330,9 +533,16 @@ description: The book looks old and worn, with faded lettering on the cover. The cover depicts a dark and eerie morgue, with a full moon casting an ominous glow over the scene. In the foreground are Morty the possum and Morticia the raccoon, with mischievous expressions on their faces, peeking out from behind a metal shelf. The title is written in bold, spooky letters, with the subtitle "A Tale of Animal Spirits" written in smaller font below. components: - type: Sprite - sprite: Objects/Misc/authorbooks.rsi + sprite: Objects/Misc/books.rsi layers: - - state: book_morgue + - state: paper + - state: cover_old + color: "#d7dadb" + - state: icon_text2 + color: "#61363d" + - state: overlay_dirt + - state: detail_bookmark + color: "#61363d" - type: Paper content: book-text-morgue @@ -343,9 +553,21 @@ description: The book is in new condition, with vibrant colors and illustrations on the cover. The cover shows Rufus on his bicycle, with Blossom flying beside him in a playful manner. The title is written in bold, whimsical font, with the characters' names highlighted in a contrasting color. The overall aesthetic is charming and inviting, appealing to children and adults alike. components: - type: Sprite - sprite: Objects/Misc/authorbooks.rsi + sprite: Objects/Misc/books.rsi layers: - - state: book_rufus + - state: paper + - state: cover_base + color: "#6597c9" + - state: decor_bottom + color: "#113a63" + - state: decor_diagonal + color: "#113a63" + - state: icon_text3 + color: "#ffde7d" + - state: detail_bookmark + color: "#61363d" + - state: detail_rivets + color: "#ffde7d" - type: Paper content: book-text-rufus @@ -356,9 +578,19 @@ description: The book is in a good condition, with a glossy cover depicting a jungle scene with vibrant colors and intricate details. The title "The Map of Adventure," is written in bold, gold lettering. The cover also features an image of a mysterious suitcase with the map spilling out of it. components: - type: Sprite - sprite: Objects/Misc/authorbooks.rsi + sprite: Objects/Misc/books.rsi layers: - - state: book_map + - state: paper + - state: cover_base + color: "#56c463" + - state: icon_briefcase + - state: decor_wingette + color: "#298033" + - state: icon_briefcase + - state: detail_bookmark + color: "#61363d" + - state: detail_rivets + color: "#ffde7d" - type: Paper content: book-text-map @@ -369,9 +601,17 @@ description: The book is in excellent condition, with crisp pages and a glossy cover. The cover features a striking image of a mountain range, with a silhouette of a climber with a guitar on their back in the foreground. The title is bold and eye-catching, with the subtitle "A Journey of Music, Mountains, and Self-Discovery." components: - type: Sprite - sprite: Objects/Misc/authorbooks.rsi + sprite: Objects/Misc/books.rsi layers: - - state: book_journ_mount + - state: paper + - state: cover_base + color: "#9bc1c9" + - state: icon_briefcase + - state: icon_mount + - state: detail_bookmark + color: "#61363d" + - state: detail_rivets + color: "#ffde7d" - type: Paper content: book-text-journ-mount @@ -384,7 +624,16 @@ - type: Sprite sprite: Objects/Misc/books.rsi layers: - - state: book6 + - state: paper + - state: cover_base + color: "#1d662c" + - state: decor_spine + color: "#2a8c58" + - state: icon_glow + color: "#b9edc4" + - state: icon_tree + - state: detail_bookmark + color: "#61363d" - type: Paper content: book-text-inspiration @@ -397,7 +646,14 @@ - type: Sprite sprite: Objects/Misc/books.rsi layers: - - state: book0 + - state: paper + - state: cover_old + color: "#c526de" + - state: decor_wingette + - state: icon_bucket + - state: detail_bookmark + color: "#61363d" + - state: overlay_dirt - type: Paper content: book-text-janitor diff --git a/Resources/Prototypes/Entities/Objects/Misc/briefcases.yml b/Resources/Prototypes/Entities/Objects/Misc/briefcases.yml index aa8823d70d..762204701c 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/briefcases.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/briefcases.yml @@ -1,8 +1,8 @@ - type: entity parent: BaseStorageItem - abstract: true id: BriefcaseBase description: Useful for carrying items in your hands. + abstract: true components: - type: Item size: Ginormous @@ -14,10 +14,9 @@ - Briefcase - type: entity - name: brown briefcase parent: BriefcaseBase id: BriefcaseBrown - description: A handy briefcase. + name: brown briefcase components: - type: Sprite sprite: Objects/Storage/Briefcases/briefcase_brown.rsi @@ -26,23 +25,9 @@ sprite: Objects/Storage/Briefcases/briefcase_brown.rsi - type: entity - parent: BriefcaseBase - abstract: true - id: BriefcaseSyndieBase + parent: BriefcaseBrown + id: BriefcaseSyndie suffix: Syndicate, Empty - description: Useful for carrying items in your hands. components: - type: Item size: Huge - -- type: entity - name: brown briefcase - parent: BriefcaseSyndieBase - id: BriefcaseSyndie - description: A handy briefcase. - components: - - type: Sprite - sprite: Objects/Storage/Briefcases/briefcase_brown.rsi - state: icon - - type: Item - sprite: Objects/Storage/Briefcases/briefcase_brown.rsi diff --git a/Resources/Prototypes/Entities/Objects/Misc/cds.yml b/Resources/Prototypes/Entities/Objects/Misc/cds.yml new file mode 100644 index 0000000000..a80a7d1d58 --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/Misc/cds.yml @@ -0,0 +1,19 @@ +- type: entity + name: coordinates disk + parent: BaseItem + id: CoordinatesDisk + description: A disk containing the coordinates to a location in space. Necessary for any FTL-traversing vessel to reach their destination. Fits inside shuttle consoles. + components: + - type: Sprite + sprite: Objects/Misc/cd.rsi + state: icon + - type: StaticPrice + price: 100 + - type: Tag + tags: + - CoordinatesDisk + - type: DamageOtherOnHit + damage: + types: + Slash: 1 + - type: ShuttleDestinationCoordinates diff --git a/Resources/Prototypes/Entities/Objects/Misc/diskcases.yml b/Resources/Prototypes/Entities/Objects/Misc/diskcases.yml new file mode 100644 index 0000000000..da86d7a00d --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/Misc/diskcases.yml @@ -0,0 +1,21 @@ +- type: entity + name: diskcase + parent: BaseStorageItem + id: DiskCase + description: Case for storing a coordinates disk. + components: + - type: Sprite + sprite: Objects/Misc/diskcases.rsi + state: icon_base + - type: Storage + grid: + - 0,0,0,1 + maxItemSize: Normal + whitelist: + tags: + - Document + - CoordinatesDisk + storageOpenSound: /Audio/Machines/screwdriveropen.ogg + storageCloseSound: /Audio/Machines/screwdriverclose.ogg + storageInsertSound: /Audio/Items/crowbar.ogg + storageRemoveSound: /Audio/Items/crowbar.ogg diff --git a/Resources/Prototypes/Entities/Objects/Misc/tiles.yml b/Resources/Prototypes/Entities/Objects/Misc/tiles.yml index 6f351ee9db..3b2e4cd8f1 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/tiles.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/tiles.yml @@ -15,9 +15,6 @@ Blunt: 5 - type: Stack count: 1 - - type: Tag - tags: - - NoPaint - type: Damageable damageContainer: Inorganic - type: Destructible diff --git a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml index db08481dc5..b192401c8b 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml @@ -87,123 +87,6 @@ - Mop - MopAdv -- type: entity - name: mop bucket - id: MopBucket - description: Holds water and the tears of the janitor. - components: - - type: Clickable - - type: Sprite - sprite: Objects/Specific/Janitorial/janitorial.rsi - noRot: true - layers: - - state: mopbucket - - state: mopbucket_water-1 - map: ["enum.SolutionContainerLayers.Fill"] - visible: false - drawdepth: Objects - - type: InteractionOutline - - type: SolutionContainerManager - solutions: - bucket: - maxVol: 600 - - type: Spillable - solution: bucket - spillDelay: 3.0 - - type: DrainableSolution - solution: bucket - - type: RefillableSolution - solution: bucket - - type: ExaminableSolution - solution: bucket - - type: Tag - tags: - - Wringer - - type: ItemMapper - mapLayers: - mopbucket_shark_blue: - whitelist: - tags: - - PlushieSharkBlue - mopbucket_shark_pink: - whitelist: - tags: - - PlushieSharkPink - mopbucket_shark_grey: - whitelist: - tags: - - PlushieSharkGrey - sprite: Objects/Fun/sharkplush.rsi - - type: Physics - bodyType: Dynamic - - type: Transform - noRot: true - - type: ItemSlots - slots: - shark_slot: - name: mop-bucket-slot-component-slot-name-shark - whitelist: - tags: - - PlushieSharkBlue - - PlushieSharkPink - - PlushieSharkGrey - priority: 3 # Higher than drinking priority - - type: Fixtures - fixtures: - fix1: - shape: - !type:PhysShapeAabb - bounds: "-0.25,-0.40,0.25,0.25" - density: 60 - mask: - - MobMask - layer: - - MobLayer - - type: Pullable - - type: Drink - solution: bucket - - type: Appearance - - type: SolutionContainerVisuals - maxFillLevels: 3 - fillBaseName: mopbucket_water- - - type: ContainerContainer - containers: - storagebase: !type:Container - ents: [] - shark_slot: !type:ContainerSlot {} - - type: GuideHelp - guides: - - Janitorial - - type: Damageable - damageContainer: Inorganic - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 70 - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - -- type: entity - name: mop bucket - id: MopBucketFull - parent: MopBucket - suffix: full - components: - - type: Sprite - layers: - - state: mopbucket - - state: mopbucket_water-3 - map: [ "enum.SolutionContainerLayers.Fill" ] - - type: SolutionContainerManager - solutions: - bucket: - maxVol: 600 - reagents: - - ReagentId: Water - Quantity: 600 - - type: entity name: wet floor sign id: WetFloorSign @@ -279,291 +162,6 @@ tags: # ignore "WhitelistChameleon" tag - WetFloorSign -- type: entity - name: janitorial trolley - id: JanitorialTrolley - parent: BaseStructureDynamic - description: This is the alpha and omega of sanitation. - components: - - type: Sprite - noRot: true - sprite: Objects/Specific/Janitorial/janitorial_cart.rsi - layers: - - state: cart - - state: cart_water-1 - map: ["enum.SolutionContainerLayers.Fill"] - visible: false - - type: Rotatable - - type: InteractionOutline - # Removing storage until OnInteractUsing logic resolved - #- type: Storage - # popup: false - # capacity: 80 - # blacklist: # there is exclusive item slots for that - # tags: - # - Mop - # - TrashBag - # - Bucket - - type: ItemSlots - slots: - mop_slot: - name: janitorial-trolley-slot-component-slot-name-mop - whitelist: - tags: - - Mop - insertOnInteract: false # or it conflicts with bucket logic - priority: 9 # Higher than bucket slot - plunger_slot: - name: janitorial-trolley-slot-component-slot-name-plunger - whitelist: - tags: - - Plunger - priority: 8 - wetfloorsign_slot4: - name: janitorial-trolley-slot-component-slot-name-sign - whitelist: - tags: - - WetFloorSign - priority: 7 - wetfloorsign_slot3: - name: janitorial-trolley-slot-component-slot-name-sign - whitelist: - tags: - - WetFloorSign - priority: 7 - wetfloorsign_slot2: - name: janitorial-trolley-slot-component-slot-name-sign - whitelist: - tags: - - WetFloorSign - priority: 7 - wetfloorsign_slot1: - name: janitorial-trolley-slot-component-slot-name-sign - whitelist: - tags: - - WetFloorSign - priority: 7 - lightreplacer_slot: - name: janitorial-trolley-slot-component-slot-name-lightreplacer - whitelist: - components: - - LightReplacer - priority: 6 - spraybottle_slot: - name: janitorial-trolley-slot-component-slot-name-spray - whitelist: - tags: - - Spray - insertOnInteract: false # or it conflicts with bucket logic - priority: 5 # Higher than bucket slot - bucket_slot: - name: janitorial-trolley-slot-component-slot-name-bucket - whitelist: - tags: - - Bucket - insertOnInteract: false # or it also conflicts with bucket logic - priority: 4 # Higher than trash bag slot - trashbag_slot: - name: janitorial-trolley-slot-component-slot-name-trashbag - whitelist: - tags: - - TrashBag - priority: 3 # Higher than drinking priority - - type: Fixtures - fixtures: - fix1: - shape: - !type:PhysShapeCircle - radius: 0.3 - density: 250 - layer: - - MobLayer - mask: - - MobMask - - type: Spillable - solution: bucket - spillDelay: 3.0 - - type: SolutionContainerManager - solutions: - bucket: - maxVol: 800 - reagents: - - ReagentId: Water - Quantity: 600 # 3 quarters full at roundstart to make it more appealing - - type: DrainableSolution - solution: bucket - - type: RefillableSolution - solution: bucket - - type: ExaminableSolution - solution: bucket - - type: Tag - tags: - - Wringer - - type: Damageable - damageContainer: Inorganic - damageModifierSet: Metallic - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 400 - behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - - trigger: - !type:DamageTrigger - damage: 200 - behaviors: - - !type:EmptyAllContainersBehaviour - - !type:DoActsBehavior - acts: ["Destruction"] - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - - type: ItemMapper - mapLayers: - cart_plunger: - whitelist: - tags: - - Plunger - cart_mop: - whitelist: - tags: - - MopBasic - cart_advmop: - whitelist: - tags: - - MopAdv - cart_garbage: - whitelist: - tags: - - TrashBag - cart_replacer: - whitelist: - components: - - LightReplacer - cart_spray: - whitelist: - tags: - - Spray - cart_sign1: # this is like stack of floor signs - minCount: 1 - whitelist: - tags: - - WetFloorSign - cart_sign2: - minCount: 2 - whitelist: - tags: - - WetFloorSign - cart_sign3: - minCount: 3 - whitelist: - tags: - - WetFloorSign - cart_sign4: - minCount: 4 - whitelist: - tags: - - WetFloorSign - cart_bucket: - whitelist: - tags: - - Bucket - sprite: Objects/Specific/Janitorial/janitorial_cart.rsi - - type: Appearance - - type: SolutionContainerVisuals - maxFillLevels: 3 - fillBaseName: cart_water- - - type: UserInterface - interfaces: - - key: enum.StorageUiKey.Key - type: StorageBoundUserInterface - - type: Drink - solution: bucket - - type: ContainerContainer - containers: - storagebase: !type:Container - ents: [] - mop_slot: !type:ContainerSlot {} - trashbag_slot: !type:ContainerSlot {} - bucket_slot: !type:ContainerSlot {} - plunger_slot: !type:ContainerSlot {} - wetfloorsign_slot4: !type:ContainerSlot {} - wetfloorsign_slot3: !type:ContainerSlot {} - wetfloorsign_slot2: !type:ContainerSlot {} - wetfloorsign_slot1: !type:ContainerSlot {} - lightreplacer_slot: !type:ContainerSlot {} - spraybottle_slot: !type:ContainerSlot {} - - type: GuideHelp - guides: - - Janitorial - - type: TileFrictionModifier - modifier: 0.4 # makes it slide - -- type: entity - id: FloorDrain - name: drain - description: Drains puddles around it. Useful for dumping mop buckets or keeping certain rooms clean. - placement: - mode: SnapgridCenter - components: - - type: Sprite - drawdepth: FloorObjects - sprite: Objects/Specific/Janitorial/drain.rsi - layers: - - state: icon - - map: [ "enum.SolutionContainerLayers.Fill" ] - state: fill-1 - visible: false - - type: InteractionOutline - - type: Clickable - - type: Transform - anchored: true - - type: Physics - bodyType: Static - canCollide: false - - type: AmbientSound - enabled: false - volume: -8 - range: 8 - sound: - path: /Audio/Ambience/Objects/drain.ogg - - type: Drain - - type: DumpableSolution - solution: drainBuffer - - type: Appearance - - type: SolutionContainerVisuals - maxFillLevels: 1 - fillBaseName: fill- - solutionName: drainBuffer - - type: SolutionContainerManager - solutions: - drainBuffer: - maxVol: 1000 - - type: DrainableSolution - solution: drainBuffer - - type: Damageable - damageContainer: Inorganic - damageModifierSet: Metallic - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 200 - behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - - trigger: - !type:DamageTrigger - damage: 100 - behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - - type: entity name: plunger id: Plunger @@ -622,6 +220,15 @@ damage: types: Blunt: 3 + - type: Plunger + +- type: weightedRandomEntity + id: PlungerLoot + weights: + RandomSpawner100: 56 + SpacemenFigureSpawner: 28 + SpawnMobCockroach: 5 + MaintenanceToolSpawner: 5 - type: entity parent: BaseItem diff --git a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/soap.yml b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/soap.yml index 56786057d5..5678de6baf 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/soap.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/soap.yml @@ -62,7 +62,6 @@ solution: soap - type: DeleteOnSolutionEmpty solution: soap - - type: PaintRemover - type: FlavorProfile flavors: - clean diff --git a/Resources/Prototypes/Entities/Objects/Specific/Mech/mechs.yml b/Resources/Prototypes/Entities/Objects/Specific/Mech/mechs.yml index 5a2587ff71..6e5362d9bb 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Mech/mechs.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Mech/mechs.yml @@ -66,9 +66,6 @@ bodyType: KinematicController - type: Clickable - type: WiresPanel - - type: Wires #we just want the panel - boardName: wires-board-name-mech - layoutId: Mech - type: Fixtures fixtures: fix1: diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/healing.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/healing.yml index 79ce03f700..71e0cf6450 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Medical/healing.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/healing.yml @@ -710,6 +710,10 @@ parent: Pill id: PillAmbuzolPlus components: + - type: Pill + pillType: 2 + - type: Sprite + state: pill3 - type: SolutionContainerManager solutions: food: diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/hypospray.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/hypospray.yml index abcabd7481..d6f3ee75fa 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Medical/hypospray.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/hypospray.yml @@ -115,6 +115,7 @@ solutionName: pen transferAmount: 15 onlyAffectsMobs: false + injectOnly: true - type: Appearance - type: SolutionContainerVisuals maxFillLevels: 1 @@ -205,6 +206,7 @@ solutionName: pen transferAmount: 20 onlyAffectsMobs: false + injectOnly: true - type: SolutionContainerManager solutions: pen: @@ -236,6 +238,7 @@ solutionName: pen transferAmount: 20 onlyAffectsMobs: false + injectOnly: true - type: SolutionContainerManager solutions: pen: @@ -267,6 +270,8 @@ solutionName: pen transferAmount: 20 onlyAffectsMobs: false + injectOnly: true + - type: SolutionContainerManager solutions: pen: @@ -299,6 +304,7 @@ solutionName: pen transferAmount: 30 onlyAffectsMobs: false + injectOnly: true - type: SolutionContainerManager solutions: pen: @@ -337,6 +343,7 @@ solutionName: pen transferAmount: 30 onlyAffectsMobs: false + injectOnly: true - type: StaticPrice price: 500 - type: Tag @@ -397,6 +404,7 @@ solutionName: pen transferAmount: 30 onlyAffectsMobs: false + injectOnly: true - type: StaticPrice price: 500 - type: Tag @@ -417,6 +425,7 @@ solution: hypospray - type: ExaminableSolution solution: hypospray + heldOnly: true # Allow examination only when held in hand. - type: Hypospray onlyAffectsMobs: false - type: UseDelay diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/morgue.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/morgue.yml index fba12bebec..32aa114429 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Medical/morgue.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/morgue.yml @@ -120,6 +120,8 @@ - type: SolutionSpiker sourceSolution: food ignoreEmpty: true + - type: ScoopableSolution + solution: food - type: Extractable grindableSolutionName: food diff --git a/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml b/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml index e14f29746d..cbfec8c9cf 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml @@ -517,13 +517,13 @@ components: - type: Sprite layers: - - state: syndicate - - state: icon-tools + - state: syndicate + - state: icon-syndicate - type: ItemBorgModule items: - - Crowbar - - Emag - - PinpointerSyndicateNuclear + - Crowbar + - Emag + - PinpointerSyndicateNuclear - type: entity id: BorgModuleEsword @@ -533,12 +533,12 @@ components: - type: Sprite layers: - - state: syndicate - - state: icon-tools + - state: syndicate + - state: icon-syndicate - type: ItemBorgModule items: - - EnergySwordDouble - - PinpointerSyndicateNuclear + - EnergySwordDouble + - PinpointerSyndicateNuclear - type: entity id: BorgModuleL6C @@ -548,9 +548,9 @@ components: - type: Sprite layers: - - state: syndicate - - state: icon-tools + - state: syndicate + - state: icon-syndicate - type: ItemBorgModule items: - - WeaponLightMachineGunL6C - - PinpointerSyndicateNuclear + - WeaponLightMachineGunL6C + - PinpointerSyndicateNuclear diff --git a/Resources/Prototypes/Entities/Objects/Tools/tools.yml b/Resources/Prototypes/Entities/Objects/Tools/tools.yml index b46eded7d8..2b11c211e8 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/tools.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/tools.yml @@ -337,15 +337,35 @@ path: "/Audio/Items/drill_hit.ogg" - type: entity - name: RCD - parent: BaseItem id: RCD - description: An advanced construction device which can place/remove walls, floors, and airlocks quickly. + parent: BaseItem + name: RCD + description: The rapid construction device can be used to quickly place and remove various station structures and fixtures. Requires compressed matter to function. components: - type: RCD + availablePrototypes: + - WallSolid + - FloorSteel + - Plating + - Catwalk + - Grille + - Window + - WindowDirectional + - WindowReinforcedDirectional + - ReinforcedWindow + - Airlock + - AirlockGlass + - Firelock + - TubeLight + - BulbLight + - LVCable + - MVCable + - HVCable + - CableTerminal + - Deconstruct - type: LimitedCharges - maxCharges: 5 - charges: 5 + maxCharges: 30 + charges: 30 - type: UseDelay - type: Sprite sprite: Objects/Tools/rcd.rsi @@ -363,6 +383,12 @@ Plastic: 100 - type: StaticPrice price: 100 + - type: UserInterface + interfaces: + - key: enum.RcdUiKey.Key + type: RCDMenuBoundUserInterface + - type: ActivatableUI + key: enum.RcdUiKey.Key - type: entity id: RCDEmpty @@ -370,37 +396,50 @@ suffix: Empty components: - type: LimitedCharges - maxCharges: 5 charges: 0 + - type: RCD + availablePrototypes: + - WallSolid + - FloorSteel + - Plating + - Catwalk + - Grille + - Window + - WindowDirectional + - WindowReinforcedDirectional + - ReinforcedWindow + - Airlock + - AirlockGlass + - Firelock - type: entity id: RCDRecharging parent: RCD - name: experimental rcd - description: A bluespace-enhanced RCD that regenerates charges passively. + name: experimental RCD + description: A bluespace-enhanced rapid construction device that passively generates its own compressed matter. suffix: AutoRecharge components: - type: LimitedCharges - maxCharges: 3 - charges: 3 + maxCharges: 20 + charges: 20 - type: AutoRecharge - rechargeDuration: 30 + rechargeDuration: 10 - type: entity id: RCDExperimental parent: RCD suffix: Admeme - name: experimental rcd - description: A bluespace-enhanced RCD that regenerates charges passively. + name: experimental RCD + description: A bluespace-enhanced rapid construction device that passively generates its own compressed matter. components: - type: AutoRecharge - rechargeDuration: 5 + rechargeDuration: 1 - type: entity - name: RCD Ammo + name: compressed matter parent: BaseItem id: RCDAmmo - description: Ammo cartridge for an RCD. + description: A cartridge of raw matter compacted by bluespace technology. Used in rapid construction devices. components: - type: RCDAmmo - type: Sprite diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/shotgun.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/shotgun.yml index 757b8934d4..e119a846c9 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/shotgun.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/shotgun.yml @@ -86,8 +86,8 @@ damage: types: Piercing: 3 - Slash: 3 - + Slash: 3 + - type: entity id: PelletShotgunTranquilizer @@ -110,9 +110,9 @@ solution: ammo - type: DrainableSolution solution: ammo - - type: SolutionInjectOnCollide + - type: SolutionInjectOnProjectileHit transferAmount: 15 - blockSlots: NONE #tranquillizer darts shouldn't be blocked by a mask + solution: ammo - type: InjectableSolution solution: ammo diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml index 202604b8bf..c4736ad356 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml @@ -643,6 +643,7 @@ - type: Clothing sprite: Objects/Weapons/Guns/Revolvers/chimp.rsi - type: Gun + projectileSpeed: 4 fireRate: 1.5 soundGunshot: path: /Audio/Weapons/Guns/Gunshots/taser2.ogg @@ -657,6 +658,8 @@ fireCost: 100 - proto: AnomalousParticleZetaStrong fireCost: 100 + - proto: AnomalousParticleSigmaStrong + fireCost: 100 - type: Construction graph: UpgradeWeaponPistolCHIMP node: start @@ -679,6 +682,8 @@ fireCost: 100 - proto: AnomalousParticleZetaStrong fireCost: 100 + - proto: AnomalousParticleSigmaStrong + fireCost: 100 - type: entity name: eye of a behonker diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/arrows.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/arrows.yml index 8dbcf2b303..52c5dc8a9d 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/arrows.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/arrows.yml @@ -50,9 +50,9 @@ solution: ammo - type: InjectableSolution solution: ammo - - type: SolutionInjectOnCollide + - type: SolutionInjectOnEmbed transferAmount: 2 - blockSlots: NONE + solution: ammo - type: SolutionTransfer maxTransferAmount: 2 - type: Appearance diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml index 9445a3cfe1..a28d527535 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml @@ -487,6 +487,11 @@ name: delta particles noSpawn: true components: + - type: PointLight + enabled: true + color: "#c2385d" + radius: 2.0 + energy: 7.0 - type: AnomalousParticle particleType: Delta - type: Sprite @@ -513,6 +518,9 @@ Heat: 5 - type: TimedDespawn lifetime: 3 + - type: Reflective + reflective: + - Energy - type: entity @@ -533,6 +541,11 @@ name: epsilon particles noSpawn: true components: + - type: PointLight + enabled: true + color: "#38c296" + radius: 2.0 + energy: 7.0 - type: Sprite layers: - state: magicm_cyan @@ -558,6 +571,11 @@ name: zeta particles noSpawn: true components: + - type: PointLight + enabled: true + color: "#b9c238" + radius: 2.0 + energy: 7.0 - type: Sprite layers: - state: magicm_yellow @@ -583,6 +601,11 @@ name: omega particles noSpawn: true components: + - type: PointLight + enabled: true + color: "#38c24f" + radius: 2.0 + energy: 7.0 - type: Sprite sprite: Objects/Weapons/Guns/Projectiles/magic.rsi layers: @@ -601,6 +624,33 @@ types: Heat: 20 +- type: entity + parent: AnomalousParticleDelta + id: AnomalousParticleSigma + name: sigma particles + noSpawn: true + components: + - type: PointLight + enabled: true + color: "#8d38c2" + radius: 2.0 + energy: 7.0 + - type: Sprite + layers: + - state: magicm + shader: unshaded + - type: AnomalousParticle + particleType: Sigma + +- type: entity + parent: AnomalousParticleSigma + id: AnomalousParticleSigmaStrong + name: sigma particles + noSpawn: true + components: + - type: AnomalousParticle + particleType: Sigma + # Launcher projectiles (grenade / rocket) - type: entity id: BulletRocket diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml index c5ea359540..13c8b9cb25 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml @@ -78,9 +78,6 @@ malus: 0 - type: Reflect enabled: false - - type: Tag - tags: - - NoPaint - type: IgnitionSource temperature: 700 @@ -159,7 +156,6 @@ - type: Tag tags: - Write - - NoPaint - type: DisarmMalus malus: 0 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/knife.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/knife.yml index 03654061ce..9cd1bb2940 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/knife.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/knife.yml @@ -263,6 +263,7 @@ tags: - CombatKnife - Knife + - CannonRestrict - type: Sprite sprite: Objects/Weapons/Melee/throwing_knife.rsi state: icon @@ -275,6 +276,7 @@ - type: EmbeddableProjectile sound: /Audio/Weapons/star_hit.ogg - type: DamageOtherOnHit + ignoreResistances: true damage: types: Slash: 10 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml index 279fed8043..3758487bd4 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml @@ -65,10 +65,9 @@ solution: melee - type: InjectableSolution solution: melee - - type: SolutionInjectOnCollide + - type: SolutionInjectOnEmbed transferAmount: 2 - fixtureId: "throw-fixture" - blockSlots: NONE + solution: melee - type: SolutionTransfer maxTransferAmount: 2 - type: Wieldable diff --git a/Resources/Prototypes/Entities/Stations/base.yml b/Resources/Prototypes/Entities/Stations/base.yml index e71b3ce46d..c3fbb998b2 100644 --- a/Resources/Prototypes/Entities/Stations/base.yml +++ b/Resources/Prototypes/Entities/Stations/base.yml @@ -120,4 +120,4 @@ id: BaseStationAllEventsEligible abstract: true components: - - type: StationEventEligible # For when someone makes this more granular in the future. + - type: StationEventEligible # For when someone makes this more granular in the future. \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Structures/Decoration/bonfire.yml b/Resources/Prototypes/Entities/Structures/Decoration/bonfire.yml index d46e992f8a..e02867c3a8 100644 --- a/Resources/Prototypes/Entities/Structures/Decoration/bonfire.yml +++ b/Resources/Prototypes/Entities/Structures/Decoration/bonfire.yml @@ -32,9 +32,6 @@ sound: path: /Audio/Ambience/Objects/fireplace.ogg - type: AlwaysHot - - type: Tag - tags: - - NoPaint - type: entity id: LegionnaireBonfire diff --git a/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml b/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml index d87c5e700a..d661009b6d 100644 --- a/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml +++ b/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml @@ -71,5 +71,4 @@ beakerSlot: !type:ContainerSlot - type: StaticPrice price: 1000 - - type: Wires - type: WiresPanel diff --git a/Resources/Prototypes/Entities/Structures/Dispensers/booze.yml b/Resources/Prototypes/Entities/Structures/Dispensers/booze.yml index 1583bc451d..7bc12ca966 100644 --- a/Resources/Prototypes/Entities/Structures/Dispensers/booze.yml +++ b/Resources/Prototypes/Entities/Structures/Dispensers/booze.yml @@ -19,9 +19,6 @@ noRot: false - type: Machine board: BoozeDispenserMachineCircuitboard - - type: Wires - boardName: wires-board-name-booze - layoutId: BoozeDispenser - type: GuideHelp guides: - Bartender diff --git a/Resources/Prototypes/Entities/Structures/Dispensers/chem.yml b/Resources/Prototypes/Entities/Structures/Dispensers/chem.yml index 6c70cf9bca..681f0a390c 100644 --- a/Resources/Prototypes/Entities/Structures/Dispensers/chem.yml +++ b/Resources/Prototypes/Entities/Structures/Dispensers/chem.yml @@ -31,9 +31,6 @@ acts: ["Destruction"] - type: Machine board: ChemDispenserMachineCircuitboard - - type: Wires - boardName: wires-board-name-chemdispenser - layoutId: ChemDispenser - type: GuideHelp guides: - Chemicals diff --git a/Resources/Prototypes/Entities/Structures/Dispensers/soda.yml b/Resources/Prototypes/Entities/Structures/Dispensers/soda.yml index 323480506f..72468973ee 100644 --- a/Resources/Prototypes/Entities/Structures/Dispensers/soda.yml +++ b/Resources/Prototypes/Entities/Structures/Dispensers/soda.yml @@ -19,9 +19,6 @@ noRot: false - type: Machine board: SodaDispenserMachineCircuitboard - - type: Wires - boardName: wires-board-name-soda - layoutId: SodaDispenser - type: GuideHelp guides: - Bartender diff --git a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/access.yml b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/access.yml index 7eed29ad56..8ffd18e7e2 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/access.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/access.yml @@ -4,10 +4,9 @@ id: AirlockServiceLocked suffix: Service, Locked components: - - type: AccessReader - access: [["Service"]] - - type: Wires - layoutId: AirlockService + - type: ContainerFill + containers: + board: [ DoorElectronicsService ] - type: entity parent: Airlock @@ -24,108 +23,99 @@ id: AirlockTheatreLocked suffix: Theatre, Locked components: - - type: AccessReader - access: [["Theatre"]] - - type: Wires - layoutId: AirlockService + - type: ContainerFill + containers: + board: [ DoorElectronicsTheatre ] - type: entity parent: Airlock id: AirlockChapelLocked suffix: Chapel, Locked components: - - type: AccessReader - access: [["Chapel"]] - - type: Wires - layoutId: AirlockService + - type: ContainerFill + containers: + board: [ DoorElectronicsChapel ] - type: entity parent: Airlock id: AirlockJanitorLocked suffix: Janitor, Locked components: - - type: AccessReader - access: [["Janitor"]] - - type: Wires - layoutId: AirlockService + - type: ContainerFill + containers: + board: [ DoorElectronicsJanitor ] - type: entity parent: Airlock id: AirlockKitchenLocked suffix: Kitchen, Locked components: - - type: AccessReader - access: [["Kitchen"]] - - type: Wires - layoutId: AirlockService + - type: ContainerFill + containers: + board: [ DoorElectronicsKitchen ] - type: entity parent: Airlock id: AirlockBarLocked suffix: Bar, Locked components: - - type: AccessReader - access: [["Bar"]] - - type: Wires - layoutId: AirlockService + - type: ContainerFill + containers: + board: [ DoorElectronicsBar ] - type: entity parent: Airlock id: AirlockHydroponicsLocked suffix: Hydroponics, Locked components: - - type: AccessReader - access: [["Hydroponics"]] - - type: Wires - layoutId: AirlockService + - type: ContainerFill + containers: + board: [ DoorElectronicsHydroponics ] - type: entity parent: Airlock id: AirlockServiceCaptainLocked suffix: Captain, Locked components: - - type: AccessReader - access: [["Captain"]] - - type: Wires - layoutId: AirlockCommand + - type: ContainerFill + containers: + board: [ DoorElectronicsCaptain ] - type: entity parent: AirlockExternal id: AirlockExternalLocked suffix: External, Locked components: - - type: AccessReader - access: [["External"]] + - type: ContainerFill + containers: + board: [ DoorElectronicsExternal ] - type: entity parent: AirlockExternal id: AirlockExternalCargoLocked suffix: External, Cargo, Locked components: - - type: AccessReader - access: [["Cargo"]] - - type: Wires - layoutId: AirlockCargo + - type: ContainerFill + containers: + board: [ DoorElectronicsCargo ] - type: entity parent: AirlockExternal id: AirlockExternalEngineeringLocked suffix: External, Engineering, Locked components: - - type: AccessReader - access: [["Engineering"]] - - type: Wires - layoutId: AirlockEngineering + - type: ContainerFill + containers: + board: [ DoorElectronicsEngineering ] - type: entity parent: AirlockExternal id: AirlockExternalAtmosphericsLocked suffix: External, Atmospherics, Locked components: - - type: AccessReader - access: [["Atmospherics"]] - - type: Wires - layoutId: AirlockEngineering + - type: ContainerFill + containers: + board: [ DoorElectronicsAtmospherics ] - type: entity parent: AirlockExternal @@ -148,20 +138,18 @@ id: AirlockFreezerLocked suffix: Kitchen, Locked components: - - type: AccessReader - access: [["Kitchen"]] - - type: Wires - layoutId: AirlockService + - type: ContainerFill + containers: + board: [ DoorElectronicsKitchen ] - type: entity parent: AirlockFreezer id: AirlockFreezerKitchenHydroLocked suffix: Kitchen/Hydroponics, Locked components: - - type: AccessReader - access: [["Kitchen"], ["Hydroponics"]] - - type: Wires - layoutId: AirlockService + - type: ContainerFill + containers: + board: [ DoorElectronicsFreezer ] - type: entity parent: AirlockFreezer @@ -178,40 +166,36 @@ id: AirlockEngineeringLocked suffix: Engineering, Locked components: - - type: AccessReader - access: [["Engineering"]] - - type: Wires - layoutId: AirlockEngineering + - type: ContainerFill + containers: + board: [ DoorElectronicsEngineering ] - type: entity parent: AirlockAtmospherics id: AirlockAtmosphericsLocked suffix: Atmospherics, Locked components: - - type: AccessReader - access: [["Atmospherics"]] - - type: Wires - layoutId: AirlockEngineering + - type: ContainerFill + containers: + board: [ DoorElectronicsAtmospherics ] - type: entity parent: AirlockCargo id: AirlockCargoLocked suffix: Cargo, Locked components: - - type: AccessReader - access: [["Cargo"]] - - type: Wires - layoutId: AirlockCargo + - type: ContainerFill + containers: + board: [ DoorElectronicsCargo ] - type: entity parent: AirlockCargo id: AirlockSalvageLocked suffix: Salvage, Locked components: - - type: AccessReader - access: [["Salvage"]] - - type: Wires - layoutId: AirlockCargo + - type: ContainerFill + containers: + board: [ DoorElectronicsSalvage ] - type: entity parent: AirlockMining @@ -228,50 +212,45 @@ id: AirlockMedicalLocked suffix: Medical, Locked components: - - type: AccessReader - access: [["Medical"]] - - type: Wires - layoutId: AirlockMedical + - type: ContainerFill + containers: + board: [ DoorElectronicsMedical ] - type: entity parent: AirlockVirology id: AirlockVirologyLocked suffix: Virology, Locked components: - - type: AccessReader - access: [["Medical"]] - - type: Wires - layoutId: AirlockMedical + - type: ContainerFill + containers: + board: [ DoorElectronicsMedical ] - type: entity parent: AirlockChemistry id: AirlockChemistryLocked suffix: Chemistry, Locked components: - - type: AccessReader - access: [["Chemistry"]] - - type: Wires - layoutId: AirlockMedical + - type: ContainerFill + containers: + board: [ DoorElectronicsChemistry ] - type: entity parent: AirlockScience id: AirlockScienceLocked suffix: Science, Locked components: - - type: AccessReader - access: [["Research"]] - - type: Wires - layoutId: AirlockScience + - type: ContainerFill + containers: + board: [ DoorElectronicsResearch ] - type: entity parent: AirlockScience id: AirlockMedicalScienceLocked suffix: Medical/Science, Locked components: - - type: AccessReader - access: [["Research"], ["Medical"]] - - type: Wires - layoutId: AirlockScience + - type: ContainerFill + containers: + board: [ DoorElectronicsScience ] - type: entity parent: AirlockCentralCommand @@ -288,8 +267,9 @@ id: AirlockCommandLocked suffix: Command, Locked components: - - type: AccessReader - access: [["Command"]] + - type: ContainerFill + containers: + board: [ DoorElectronicsCommand ] - type: Wires layoutId: AirlockCommand @@ -298,78 +278,72 @@ id: AirlockCaptainLocked suffix: Captain, Locked components: - - type: AccessReader - access: [["Captain"]] - - type: Wires - layoutId: AirlockCommand + - type: ContainerFill + containers: + board: [ DoorElectronicsCaptain ] - type: entity parent: AirlockCommand id: AirlockChiefMedicalOfficerLocked suffix: ChiefMedicalOfficer, Locked components: - - type: AccessReader - access: [["ChiefMedicalOfficer"]] - - type: Wires - layoutId: AirlockCommand + - type: ContainerFill + containers: + board: [ DoorElectronicsChiefMedicalOfficer ] - type: entity parent: AirlockCommand id: AirlockChiefEngineerLocked suffix: ChiefEngineer, Locked components: - - type: AccessReader - access: [["ChiefEngineer"]] - - type: Wires - layoutId: AirlockCommand + - type: ContainerFill + containers: + board: [ DoorElectronicsChiefEngineer ] - type: entity parent: AirlockCommand id: AirlockHeadOfSecurityLocked suffix: HeadOfSecurity, Locked components: - - type: AccessReader - access: [["HeadOfSecurity"]] - - type: Wires - layoutId: AirlockCommand + - type: ContainerFill + containers: + board: [ DoorElectronicsHeadOfSecurity ] - type: entity parent: AirlockCommand id: AirlockResearchDirectorLocked suffix: ResearchDirector, Locked components: - - type: AccessReader - access: [["ResearchDirector"]] - - type: Wires - layoutId: AirlockCommand + - type: ContainerFill + containers: + board: [ DoorElectronicsResearchDirector ] - type: entity parent: AirlockCommand id: AirlockHeadOfPersonnelLocked suffix: HeadOfPersonnel, Locked components: - - type: AccessReader - access: [["HeadOfPersonnel"]] - - type: Wires - layoutId: AirlockCommand + - type: ContainerFill + containers: + board: [ DoorElectronicsHeadOfPersonnel ] - type: entity parent: AirlockCommand id: AirlockQuartermasterLocked suffix: Quartermaster, Locked components: - - type: AccessReader - access: [["Quartermaster"]] - - type: Wires - layoutId: AirlockCommand + - type: ContainerFill + containers: + board: [ DoorElectronicsQuartermaster ] - type: entity parent: AirlockSecurity id: AirlockSecurityLocked suffix: Security, Locked components: - - type: AccessReader - access: [["Security"]] + - type: ContainerFill + containers: + board: [ DoorElectronicsSecurity ] - type: Wires layoutId: AirlockSecurity @@ -378,8 +352,9 @@ id: AirlockDetectiveLocked suffix: Detective, Locked components: - - type: AccessReader - access: [["Detective"]] + - type: ContainerFill + containers: + board: [ DoorElectronicsDetective ] - type: Wires layoutId: AirlockSecurity @@ -388,8 +363,9 @@ id: AirlockBrigLocked suffix: Brig, Locked components: - - type: AccessReader - access: [["Brig"]] + - type: ContainerFill + containers: + board: [ DoorElectronicsBrig ] - type: Wires layoutId: AirlockSecurity @@ -408,8 +384,9 @@ id: AirlockArmoryLocked suffix: Armory, Locked components: - - type: AccessReader - access: [["Armory"]] + - type: ContainerFill + containers: + board: [ DoorElectronicsArmory ] - type: Wires layoutId: AirlockArmory @@ -418,20 +395,18 @@ id: AirlockVaultLocked suffix: Vault, Locked components: - - type: AccessReader - access: [["Security", "Command"]] - - type: Wires - layoutId: AirlockSecurity + - type: ContainerFill + containers: + board: [ DoorElectronicsVault ] - type: entity parent: AirlockCommand id: AirlockEVALocked suffix: EVA, Locked components: - - type: AccessReader - access: [["External"]] - - type: Wires - layoutId: AirlockCommand + - type: ContainerFill + containers: + board: [ DoorElectronicsExternal ] # Glass Airlocks - type: entity @@ -439,10 +414,9 @@ id: AirlockServiceGlassLocked suffix: Service, Locked components: - - type: AccessReader - access: [["Service"]] - - type: Wires - layoutId: AirlockService + - type: ContainerFill + containers: + board: [ DoorElectronicsService ] - type: entity parent: AirlockGlass @@ -469,28 +443,27 @@ id: AirlockBarGlassLocked suffix: Bar, Locked components: - - type: AccessReader - access: [["Bar"]] - - type: Wires - layoutId: AirlockService + - type: ContainerFill + containers: + board: [ DoorElectronicsBar ] - type: entity parent: AirlockExternalGlass id: AirlockExternalGlassLocked suffix: External, Glass, Locked components: - - type: AccessReader - access: [["External"]] + - type: ContainerFill + containers: + board: [ DoorElectronicsExternal ] - type: entity parent: AirlockExternalGlass id: AirlockExternalGlassCargoLocked suffix: External, Glass, Cargo, Locked components: - - type: AccessReader - access: [["Cargo"]] - - type: Wires - layoutId: AirlockService + - type: ContainerFill + containers: + board: [ DoorElectronicsCargo ] - type: entity parent: AirlockExternalGlass @@ -513,30 +486,27 @@ id: AirlockExternalGlassEngineeringLocked suffix: External, Glass, Engineering, Locked components: - - type: AccessReader - access: [["Engineering"]] - - type: Wires - layoutId: AirlockEngineering + - type: ContainerFill + containers: + board: [ DoorElectronicsEngineering ] - type: entity parent: AirlockExternalGlass id: AirlockExternalGlassAtmosphericsLocked suffix: External, Glass, Atmospherics, Locked components: - - type: AccessReader - access: [["Atmospherics"]] - - type: Wires - layoutId: AirlockEngineering + - type: ContainerFill + containers: + board: [ DoorElectronicsAtmospherics ] - type: entity parent: AirlockGlass id: AirlockKitchenGlassLocked suffix: Kitchen, Locked components: - - type: AccessReader - access: [["Kitchen"]] - - type: Wires - layoutId: AirlockService + - type: ContainerFill + containers: + board: [ DoorElectronicsKitchen ] - type: entity parent: AirlockGlass @@ -553,60 +523,54 @@ id: AirlockHydroGlassLocked suffix: Hydroponics, Locked components: - - type: AccessReader - access: [["Hydroponics"]] - - type: Wires - layoutId: AirlockService + - type: ContainerFill + containers: + board: [ DoorElectronicsHydroponics ] - type: entity parent: AirlockGlass id: AirlockChapelGlassLocked suffix: Chapel, Locked components: - - type: AccessReader - access: [["Chapel"]] - - type: Wires - layoutId: AirlockService + - type: ContainerFill + containers: + board: [ DoorElectronicsChapel ] - type: entity parent: AirlockEngineeringGlass id: AirlockEngineeringGlassLocked suffix: Engineering, Locked components: - - type: AccessReader - access: [["Engineering"]] - - type: Wires - layoutId: AirlockEngineering + - type: ContainerFill + containers: + board: [ DoorElectronicsEngineering ] - type: entity parent: AirlockAtmosphericsGlass id: AirlockAtmosphericsGlassLocked suffix: Atmospherics, Locked components: - - type: AccessReader - access: [["Atmospherics"]] - - type: Wires - layoutId: AirlockEngineering + - type: ContainerFill + containers: + board: [ DoorElectronicsAtmospherics ] - type: entity parent: AirlockCargoGlass id: AirlockCargoGlassLocked suffix: Cargo, Locked components: - - type: AccessReader - access: [["Cargo"]] - - type: Wires - layoutId: AirlockCargo + - type: ContainerFill + containers: + board: [ DoorElectronicsCargo ] - type: entity parent: AirlockCargoGlass id: AirlockSalvageGlassLocked suffix: Salvage, Locked components: - - type: AccessReader - access: [["Salvage"]] - - type: Wires - layoutId: AirlockCargo + - type: ContainerFill + containers: + board: [ DoorElectronicsSalvage ] - type: entity parent: AirlockMiningGlass @@ -633,40 +597,36 @@ id: AirlockMedicalGlassLocked suffix: Medical, Locked components: - - type: AccessReader - access: [["Medical"]] - - type: Wires - layoutId: AirlockMedical + - type: ContainerFill + containers: + board: [ DoorElectronicsMedical ] - type: entity parent: AirlockVirologyGlass id: AirlockVirologyGlassLocked suffix: Virology, Locked components: - - type: AccessReader - access: [["Medical"]] - - type: Wires - layoutId: AirlockMedical + - type: ContainerFill + containers: + board: [ DoorElectronicsMedical ] - type: entity parent: AirlockScienceGlass id: AirlockScienceGlassLocked suffix: Science, Locked components: - - type: AccessReader - access: [["Research"]] - - type: Wires - layoutId: AirlockScience + - type: ContainerFill + containers: + board: [ DoorElectronicsResearch ] - type: entity parent: AirlockScienceGlass id: AirlockMedicalScienceGlassLocked suffix: Medical/Science, Locked components: - - type: AccessReader - access: [["Research"], ["Medical"]] - - type: Wires - layoutId: AirlockScience + - type: ContainerFill + containers: + board: [ DoorElectronicsScience ] - type: entity parent: AirlockCentralCommandGlass @@ -683,110 +643,99 @@ id: AirlockCommandGlassLocked suffix: Command, Locked components: - - type: AccessReader - access: [["Command"]] - - type: Wires - layoutId: AirlockCommand + - type: ContainerFill + containers: + board: [ DoorElectronicsCommand ] - type: entity parent: AirlockCommandGlass id: AirlockCaptainGlassLocked suffix: Captain, Locked components: - - type: AccessReader - access: [["Captain"]] - - type: Wires - layoutId: AirlockCommand + - type: ContainerFill + containers: + board: [ DoorElectronicsCaptain ] - type: entity parent: AirlockCommandGlass id: AirlockChiefMedicalOfficerGlassLocked suffix: ChiefMedicalOfficer, Locked components: - - type: AccessReader - access: [["ChiefMedicalOfficer"]] - - type: Wires - layoutId: AirlockCommand + - type: ContainerFill + containers: + board: [ DoorElectronicsChiefMedicalOfficer ] - type: entity parent: AirlockCommandGlass id: AirlockChiefEngineerGlassLocked suffix: ChiefEngineer, Locked components: - - type: AccessReader - access: [["ChiefEngineer"]] - - type: Wires - layoutId: AirlockCommand + - type: ContainerFill + containers: + board: [ DoorElectronicsChiefEngineer ] - type: entity parent: AirlockCommandGlass id: AirlockHeadOfSecurityGlassLocked suffix: HeadOfSecurity, Locked components: - - type: AccessReader - access: [["HeadOfSecurity"]] - - type: Wires - layoutId: AirlockCommand + - type: ContainerFill + containers: + board: [ DoorElectronicsHeadOfSecurity ] - type: entity parent: AirlockCommandGlass id: AirlockResearchDirectorGlassLocked suffix: ResearchDirector, Locked components: - - type: AccessReader - access: [["ResearchDirector"]] - - type: Wires - layoutId: AirlockCommand + - type: ContainerFill + containers: + board: [ DoorElectronicsResearchDirector ] - type: entity parent: AirlockCommandGlass id: AirlockHeadOfPersonnelGlassLocked suffix: HeadOfPersonnel, Locked components: - - type: AccessReader - access: [["HeadOfPersonnel"]] - - type: Wires - layoutId: AirlockCommand + - type: ContainerFill + containers: + board: [ DoorElectronicsHeadOfPersonnel ] - type: entity parent: AirlockCommandGlass id: AirlockQuartermasterGlassLocked suffix: Quartermaster, Locked components: - - type: AccessReader - access: [["Quartermaster"]] - - type: Wires - layoutId: AirlockCommand + - type: ContainerFill + containers: + board: [ DoorElectronicsQuartermaster ] - type: entity parent: AirlockSecurityGlass id: AirlockSecurityGlassLocked suffix: Security, Locked components: - - type: AccessReader - access: [["Security"]] - - type: Wires - layoutId: AirlockCommand + - type: ContainerFill + containers: + board: [ DoorElectronicsSecurity ] - type: entity parent: AirlockSecurityGlass id: AirlockDetectiveGlassLocked suffix: Detective, Locked components: - - type: AccessReader - access: [["Detective"]] - - type: Wires - layoutId: AirlockCommand + - type: ContainerFill + containers: + board: [ DoorElectronicsDetective ] - type: entity parent: AirlockSecurityGlass id: AirlockBrigGlassLocked suffix: Brig, Locked components: - - type: AccessReader - access: [["Brig"]] - - type: Wires - layoutId: AirlockCommand + - type: ContainerFill + containers: + board: [ DoorElectronicsBrig ] - type: entity parent: AirlockSecurityGlass @@ -803,18 +752,18 @@ id: AirlockArmoryGlassLocked suffix: Armory, Locked components: - - type: AccessReader - access: [["Armory"]] - - type: Wires - layoutId: AirlockSecurity + - type: ContainerFill + containers: + board: [ DoorElectronicsArmory ] - type: entity parent: AirlockCommandGlassLocked id: AirlockEVAGlassLocked suffix: EVA, Locked components: - - type: AccessReader - access: [["External"]] + - type: ContainerFill + containers: + board: [ DoorElectronicsExternal ] - type: entity parent: AirlockSyndicateGlass @@ -838,114 +787,108 @@ id: AirlockMaintLocked suffix: Locked components: - - type: AccessReader - access: [["Maintenance"]] + - type: ContainerFill + containers: + board: [ DoorElectronicsMaintenance ] - type: entity parent: AirlockMaintGlass id: AirlockMaintGlassLocked suffix: Locked components: - - type: AccessReader - access: [["Maintenance"]] + - type: ContainerFill + containers: + board: [ DoorElectronicsMaintenance ] - type: entity parent: AirlockMaint id: AirlockMaintSalvageLocked suffix: Salvage, Locked components: - - type: AccessReader - access: [["Salvage"]] - - type: Wires - layoutId: AirlockCargo + - type: ContainerFill + containers: + board: [ DoorElectronicsSalvage ] - type: entity parent: AirlockMaint id: AirlockMaintCargoLocked suffix: Cargo, Locked components: - - type: AccessReader - access: [["Cargo"]] - - type: Wires - layoutId: AirlockCargo + - type: ContainerFill + containers: + board: [ DoorElectronicsCargo ] - type: entity parent: AirlockMaint id: AirlockMaintCommandLocked suffix: Command, Locked components: - - type: AccessReader - access: [["Command"]] - - type: Wires - layoutId: AirlockCommand + - type: ContainerFill + containers: + board: [ DoorElectronicsCommand ] - type: entity parent: AirlockMaint id: AirlockMaintCommonLocked suffix: Common, Locked components: - - type: AccessReader - access: [["Maintenance"]] + - type: ContainerFill + containers: + board: [ DoorElectronicsMaintenance ] - type: entity parent: AirlockMaint id: AirlockMaintEngiLocked suffix: Engineering, Locked components: - - type: AccessReader - access: [["Engineering"]] - - type: Wires - layoutId: AirlockEngineering + - type: ContainerFill + containers: + board: [ DoorElectronicsEngineering ] - type: entity parent: AirlockMaint id: AirlockMaintAtmoLocked suffix: Atmospherics, Locked components: - - type: AccessReader - access: [["Atmospherics"]] - - type: Wires - layoutId: AirlockEngineering + - type: ContainerFill + containers: + board: [ DoorElectronicsAtmospherics ] - type: entity parent: AirlockMaint id: AirlockMaintBarLocked suffix: Bar, Locked components: - - type: AccessReader - access: [["Bar"]] - - type: Wires - layoutId: AirlockService + - type: ContainerFill + containers: + board: [ DoorElectronicsBar ] - type: entity parent: AirlockMaint id: AirlockMaintChapelLocked suffix: Chapel, Locked components: - - type: AccessReader - access: [["Chapel"]] - - type: Wires - layoutId: AirlockService + - type: ContainerFill + containers: + board: [ DoorElectronicsChapel ] - type: entity parent: AirlockMaint id: AirlockMaintHydroLocked suffix: Hydroponics, Locked components: - - type: AccessReader - access: [["Hydroponics"]] - - type: Wires - layoutId: AirlockService + - type: ContainerFill + containers: + board: [ DoorElectronicsHydroponics ] - type: entity parent: AirlockMaint id: AirlockMaintJanitorLocked suffix: Janitor, Locked components: - - type: AccessReader - access: [["Janitor"]] - - type: Wires - layoutId: AirlockService + - type: ContainerFill + containers: + board: [ DoorElectronicsJanitor ] - type: entity parent: AirlockMaint @@ -972,108 +915,99 @@ id: AirlockMaintTheatreLocked suffix: Theatre, Locked components: - - type: AccessReader - access: [["Theatre"]] - - type: Wires - layoutId: AirlockService + - type: ContainerFill + containers: + board: [ DoorElectronicsTheatre ] - type: entity parent: AirlockMaint id: AirlockMaintKitchenLocked suffix: Kitchen, Locked components: - - type: AccessReader - access: [["Kitchen"]] - - type: Wires - layoutId: AirlockService + - type: ContainerFill + containers: + board: [ DoorElectronicsKitchen ] - type: entity parent: AirlockMaint id: AirlockMaintIntLocked suffix: Interior, Locked components: - - type: AccessReader - access: [["Maintenance"]] + - type: ContainerFill + containers: + board: [ DoorElectronicsMaintenance ] - type: entity parent: AirlockMaint id: AirlockMaintMedLocked suffix: Medical, Locked components: - - type: AccessReader - access: [["Medical"]] - - type: Wires - layoutId: AirlockMedical + - type: ContainerFill + containers: + board: [ DoorElectronicsMedical ] - type: entity parent: AirlockMaint id: AirlockMaintChemLocked suffix: Chemistry, Locked components: - - type: AccessReader - access: [["Chemistry"]] - - type: Wires - layoutId: AirlockMedical + - type: ContainerFill + containers: + board: [ DoorElectronicsChemistry ] - type: entity parent: AirlockMaint id: AirlockMaintRnDLocked suffix: Science, Locked components: - - type: AccessReader - access: [["Research"]] - - type: Wires - layoutId: AirlockScience + - type: ContainerFill + containers: + board: [ DoorElectronicsResearch ] - type: entity parent: AirlockMaint id: AirlockMaintRnDMedLocked suffix: Medical/Science, Locked components: - - type: AccessReader - access: [["Research"], ["Medical"]] - - type: Wires - layoutId: AirlockScience + - type: ContainerFill + containers: + board: [ DoorElectronicsRnDMed ] - type: entity parent: AirlockMaint id: AirlockMaintSecLocked suffix: Security, Locked components: - - type: AccessReader - access: [["Security"]] - - type: Wires - layoutId: AirlockSecurity + - type: ContainerFill + containers: + board: [ DoorElectronicsSecurity ] - type: entity parent: AirlockMaint id: AirlockMaintDetectiveLocked suffix: Detective, Locked components: - - type: AccessReader - access: [["Detective"]] - - type: Wires - layoutId: AirlockSecurity + - type: ContainerFill + containers: + board: [ DoorElectronicsDetective ] - type: entity parent: AirlockMaint id: AirlockMaintHOPLocked suffix: HeadOfPersonnel, Locked components: - - type: AccessReader - access: [["HeadOfPersonnel"]] - - type: Wires - layoutId: AirlockCommand + - type: ContainerFill + containers: + board: [ DoorElectronicsHeadOfPersonnel ] - type: entity parent: AirlockMaint id: AirlockMaintCaptainLocked suffix: Captain, Locked components: - - type: AccessReader - access: [["Captain"]] - - type: Wires - layoutId: AirlockCommand + - type: ContainerFill + containers: + board: [ DoorElectronicsCaptain ] - type: entity parent: AirlockMaint @@ -1147,8 +1081,9 @@ id: AirlockExternalShuttleLocked suffix: External, Docking, Locked components: - - type: AccessReader - access: [["External"]] + - type: ContainerFill + containers: + board: [ DoorElectronicsExternal ] - type: entity parent: AirlockShuttleSyndicate @@ -1171,8 +1106,9 @@ id: AirlockExternalGlassShuttleLocked suffix: External, Glass, Docking, Locked components: - - type: AccessReader - access: [["External"]] + - type: ContainerFill + containers: + board: [ DoorElectronicsExternal ] - type: entity parent: AirlockGlassShuttleSyndicate @@ -1197,8 +1133,9 @@ components: - type: PriorityDock tag: DockEmergency - - type: AccessReader - access: [["External"]] + - type: ContainerFill + containers: + board: [ DoorElectronicsExternal ] - type: entity parent: AirlockGlassShuttle @@ -1229,24 +1166,27 @@ id: HighSecCommandLocked suffix: Command, Locked components: - - type: AccessReader - access: [["Command"]] + - type: ContainerFill + containers: + board: [ DoorElectronicsCommand ] - type: entity parent: HighSecDoor id: HighSecCaptainLocked suffix: Captain, Locked components: - - type: AccessReader - access: [["Captain"]] + - type: ContainerFill + containers: + board: [ DoorElectronicsCaptain ] - type: entity parent: HighSecDoor id: HighSecArmoryLocked suffix: Armory, Locked components: - - type: AccessReader - access: [["Armory"]] + - type: ContainerFill + containers: + board: [ DoorElectronicsArmory ] #Airtight hatch @@ -1255,6 +1195,6 @@ id: AirlockHatchSyndicate suffix: Syndicate, Locked components: - - type: AccessReader - access: [["SyndicateAgent"]] - + - type: ContainerFill + containers: + board: [ DoorElectronicsSyndicateAgent ] diff --git a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/airlocks.yml b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/airlocks.yml index ce2b326129..ff02e315cb 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/airlocks.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/airlocks.yml @@ -138,48 +138,6 @@ sprite: Structures/Doors/Airlocks/Standard/hatch_maint.rsi # Glass - -- type: entity - id: AirlockGlass - parent: Airlock - name: glass airlock - components: - - type: MeleeSound - soundGroups: - Brute: - collection: GlassSmack - - type: Door - occludes: false - - type: Occluder - enabled: false - - type: Sprite - sprite: Structures/Doors/Airlocks/Glass/glass.rsi - - type: AnimationPlayer - - type: Fixtures - fixtures: - fix1: - shape: - !type:PhysShapeAabb - bounds: "-0.49,-0.49,0.49,0.49" # don't want this colliding with walls or they won't close - density: 100 - mask: - - FullTileMask - layer: #removed opaque from the layer, allowing lasers to pass through glass airlocks - - GlassAirlockLayer - - type: LayerChangeOnWeld - unWeldedLayer: GlassAirlockLayer - weldedLayer: GlassLayer - - type: Construction - graph: Airlock - node: glassAirlock - - type: PaintableAirlock - group: Glass - - type: RadiationBlocker - resistance: 2 - - type: Tag - tags: - - GlassAirlock - # This tag is used to nagivate the Airlock construction graph. It's needed because the construction graph is shared between Airlock, AirlockGlass, and HighSecDoor - type: entity parent: AirlockGlass id: AirlockEngineeringGlass @@ -295,4 +253,4 @@ - type: Sprite sprite: Structures/Doors/Airlocks/Glass/centcomm.rsi - type: WiresPanelSecurity - securityLevel: medSecurity + securityLevel: medSecurity \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/base_assembly.yml b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/base_assembly.yml index fcdb0d2dea..283c9f22ae 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/base_assembly.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/base_assembly.yml @@ -30,6 +30,10 @@ - type: Damageable damageContainer: Inorganic damageModifierSet: Metallic + - type: RCDDeconstructable + cost: 6 + delay: 8 + fx: EffectRCDDeconstruct8 - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/base_structureairlocks.yml b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/base_structureairlocks.yml index 53a32e0f6f..4ca7df6482 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/base_structureairlocks.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/base_structureairlocks.yml @@ -48,6 +48,8 @@ - type: ContainerFill containers: board: [ DoorElectronics ] + - type: AccessReader + containerAccessProvider: board - type: Door crushDamage: types: @@ -111,6 +113,10 @@ - type: Damageable damageContainer: StructuralInorganic damageModifierSet: StrongMetallic + - type: RCDDeconstructable + cost: 6 + delay: 8 + fx: EffectRCDDeconstruct8 - type: Destructible thresholds: - trigger: @@ -136,7 +142,6 @@ - type: PaintableAirlock group: Standard department: Civilian - - type: AccessReader - type: StaticPrice price: 150 - type: LightningTarget @@ -149,5 +154,53 @@ - type: BlockWeather placement: mode: SnapgridCenter + +- type: entity + id: AirlockRCDResistant + parent: Airlock + abstract: true + components: + - type: RCDDeconstructable + deconstructable: false - +- type: entity + id: AirlockGlass + parent: Airlock + name: glass airlock + components: + - type: MeleeSound + soundGroups: + Brute: + collection: GlassSmack + - type: Door + occludes: false + - type: Occluder + enabled: false + - type: Sprite + sprite: Structures/Doors/Airlocks/Glass/glass.rsi + - type: AnimationPlayer + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeAabb + bounds: "-0.49,-0.49,0.49,0.49" # don't want this colliding with walls or they won't close + density: 100 + mask: + - FullTileMask + layer: #removed opaque from the layer, allowing lasers to pass through glass airlocks + - GlassAirlockLayer + - type: LayerChangeOnWeld + unWeldedLayer: GlassAirlockLayer + weldedLayer: GlassLayer + - type: Construction + graph: Airlock + node: glassAirlock + - type: PaintableAirlock + group: Glass + - type: RadiationBlocker + resistance: 2 + - type: Tag + tags: + - GlassAirlock + # This tag is used to nagivate the Airlock construction graph. It's needed because the construction graph is shared between Airlock, AirlockGlass, and HighSecDoor \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/external.yml b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/external.yml index 75b23f7071..293aaac273 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/external.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/external.yml @@ -1,5 +1,5 @@ - type: entity - parent: Airlock + parent: AirlockRCDResistant id: AirlockExternal suffix: External description: It opens, it closes, it might crush you, and there might be only space behind it. diff --git a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/highsec.yml b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/highsec.yml index a26226c957..e9ea05a1c3 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/highsec.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/highsec.yml @@ -60,6 +60,7 @@ - type: NavMapDoor - type: DoorBolt - type: AccessReader + containerAccessProvider: board - type: Appearance - type: WiresVisuals - type: ApcPowerReceiver diff --git a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/shuttle.yml b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/shuttle.yml index 9771f63388..5d6b1088f1 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/shuttle.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/shuttle.yml @@ -1,5 +1,5 @@ - type: entity - parent: Airlock + parent: AirlockRCDResistant id: AirlockShuttle suffix: Docking name: external airlock diff --git a/Resources/Prototypes/Entities/Structures/Doors/Firelocks/firelock.yml b/Resources/Prototypes/Entities/Structures/Doors/Firelocks/firelock.yml index e677ef185b..a678ab7443 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Firelocks/firelock.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Firelocks/firelock.yml @@ -19,6 +19,10 @@ - type: Damageable damageContainer: Inorganic damageModifierSet: Metallic + - type: RCDDeconstructable + cost: 4 + delay: 6 + fx: EffectRCDDeconstruct6 - type: Destructible thresholds: - trigger: @@ -83,9 +87,6 @@ - type: Appearance - type: WiresVisuals - type: WiresPanel - - type: Wires - boardName: wires-board-name-firelock - layoutId: Firelock - type: UserInterface interfaces: - key: enum.WiresUiKey.Key diff --git a/Resources/Prototypes/Entities/Structures/Doors/Firelocks/frame.yml b/Resources/Prototypes/Entities/Structures/Doors/Firelocks/frame.yml index 8cf75e89e1..3f4306e4aa 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Firelocks/frame.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Firelocks/frame.yml @@ -25,6 +25,10 @@ - type: Damageable damageContainer: Inorganic damageModifierSet: Metallic + - type: RCDDeconstructable + cost: 4 + delay: 6 + fx: EffectRCDDeconstruct6 - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Doors/MaterialDoors/material_doors.yml b/Resources/Prototypes/Entities/Structures/Doors/MaterialDoors/material_doors.yml index 8dfe2f62a5..b8fb203b51 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/MaterialDoors/material_doors.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/MaterialDoors/material_doors.yml @@ -43,6 +43,10 @@ - type: Damageable damageContainer: Inorganic damageModifierSet: Metallic + - type: RCDDeconstructable + cost: 6 + delay: 6 + fx: EffectRCDDeconstruct6 - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Doors/SecretDoor/secret_door.yml b/Resources/Prototypes/Entities/Structures/Doors/SecretDoor/secret_door.yml index d6c087af0a..06e9d2219a 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/SecretDoor/secret_door.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/SecretDoor/secret_door.yml @@ -41,6 +41,10 @@ - type: Damageable damageContainer: Inorganic damageModifierSet: Metallic + - type: RCDDeconstructable + cost: 6 + delay: 8 + fx: EffectRCDDeconstruct8 - type: Destructible thresholds: - trigger: @@ -97,6 +101,10 @@ - type: Damageable damageContainer: Inorganic damageModifierSet: Metallic + - type: RCDDeconstructable + cost: 6 + delay: 8 + fx: EffectRCDDeconstruct8 - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Doors/Shutter/blast_door.yml b/Resources/Prototypes/Entities/Structures/Doors/Shutter/blast_door.yml index 97f3c1b9e3..0700a5a3e7 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Shutter/blast_door.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Shutter/blast_door.yml @@ -4,6 +4,7 @@ name: blast door description: This one says 'BLAST DONGER'. components: + - type: AccessReader - type: Sprite sprite: Structures/Doors/Shutters/blastdoor.rsi layers: diff --git a/Resources/Prototypes/Entities/Structures/Doors/Shutter/blast_door_autolink.yml b/Resources/Prototypes/Entities/Structures/Doors/Shutter/blast_door_autolink.yml index 399760616c..3386703ec9 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Shutter/blast_door_autolink.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Shutter/blast_door_autolink.yml @@ -56,6 +56,8 @@ parent: BlastDoor suffix: Autolink, Bridge components: + - type: AccessReader + access: [["Command"]] - type: AutoLinkReceiver channel: Bridge @@ -64,9 +66,51 @@ parent: BlastDoorOpen suffix: Open, Autolink, Bridge components: + - type: AccessReader + access: [["Command"]] - type: AutoLinkReceiver channel: Bridge +- type: entity + id: BlastDoorEngineering + parent: BlastDoor + suffix: Autolink, Engineering + components: + - type: AccessReader + access: [["Command"], ["Engineering"]] + - type: AutoLinkReceiver + channel: Engineering + +- type: entity + id: BlastDoorEngineeringOpen + parent: BlastDoorOpen + suffix: Open, Autolink, Engineering + components: + - type: AccessReader + access: [["Command"], ["Engineering"]] + - type: AutoLinkReceiver + channel: Engineering + +- type: entity + id: BlastDoorScience + parent: BlastDoor + suffix: Autolink, Science + components: + - type: AccessReader + access: [["Command"], ["Research"]] + - type: AutoLinkReceiver + channel: Research + +- type: entity + id: BlastDoorScienceOpen + parent: BlastDoorOpen + suffix: Open, Autolink, Science + components: + - type: AccessReader + access: [["Command"], ["Research"]] + - type: AutoLinkReceiver + channel: Research + - type: entity id: BlastDoorWindows parent: BlastDoor diff --git a/Resources/Prototypes/Entities/Structures/Doors/Windoors/assembly.yml b/Resources/Prototypes/Entities/Structures/Doors/Windoors/assembly.yml index 8d9cedac03..5d47d9c5c4 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Windoors/assembly.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Windoors/assembly.yml @@ -26,6 +26,10 @@ - type: Damageable damageContainer: Inorganic damageModifierSet: Metallic + - type: RCDDeconstructable + cost: 6 + delay: 8 + fx: EffectRCDDeconstruct8 - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Doors/Windoors/base_structurewindoors.yml b/Resources/Prototypes/Entities/Structures/Doors/Windoors/base_structurewindoors.yml index d03765d4fc..d58273edcc 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Windoors/base_structurewindoors.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Windoors/base_structurewindoors.yml @@ -66,7 +66,11 @@ damageContainer: Inorganic damageModifierSet: Glass - type: ExaminableDamage - messages: WindowMessages + messages: WindowMessages + - type: RCDDeconstructable + cost: 8 + delay: 8 + fx: EffectRCDDeconstruct8 - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Furniture/toilet.yml b/Resources/Prototypes/Entities/Structures/Furniture/toilet.yml index a6f14b383c..f02b126248 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/toilet.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/toilet.yml @@ -2,48 +2,100 @@ name: toilet id: ToiletEmpty suffix: Empty - parent: SeatBase + parent: [ DisposalUnitBase, SeatBase ] description: The HT-451, a torque rotation-based, waste disposal unit for small matter. This one seems remarkably clean. components: - - type: MeleeSound - soundGroups: - Brute: - path: - "/Audio/Weapons/slash.ogg" - - type: Anchorable - type: Sprite sprite: Structures/Furniture/toilet.rsi - state: closed_toilet_seat_up + layers: + - state: condisposal + map: [ "enum.DisposalUnitVisualLayers.Unanchored" ] + - state: disposal + map: [ "enum.DisposalUnitVisualLayers.Base" ] + - state: disposal-flush + map: [ "enum.DisposalUnitVisualLayers.OverlayFlush" ] + - state: dispover-charge + map: [ "enum.DisposalUnitVisualLayers.OverlayCharging" ] + - state: dispover-ready + map: [ "enum.DisposalUnitVisualLayers.OverlayReady" ] + - state: dispover-full + map: [ "enum.DisposalUnitVisualLayers.OverlayFull" ] + - state: dispover-handle + map: [ "enum.DisposalUnitVisualLayers.OverlayEngaged" ] + - map: [ "DoorVisualState.DoorOpen" ] + - map: [ "SeatVisualState.SeatUp" ] + - type: Rotatable + - type: Transform + noRot: false + - type: Strap + whitelist: + components: + - HumanoidAppearance + - type: DisposalUnit + autoEngageEnabled: false + noUI: true + blacklist: + components: + - HumanoidAppearance + - Plunger + - SolutionTransfer + whitelist: + components: + - Item + soundFlush: /Audio/Effects/Fluids/flush.ogg + soundInsert: /Audio/Effects/Fluids/splash.ogg - type: Toilet - - type: SecretStash - secretPartName: secret-stash-part-toilet - type: ContainerContainer containers: stash: !type:ContainerSlot {} - - type: SolutionContainerManager - solutions: - drainBuffer: - maxVol: 500 - toilet: - maxVol: 250 - - type: Transform - anchored: true + disposals: !type:Container - type: Physics bodyType: Static - type: Construction graph: Toilet node: toilet + - type: PlungerUse - type: Appearance + - type: SecretStash + secretPartName: secret-stash-part-toilet + examineStash: toilet-component-on-examine-found-hidden-item + openableStash: true - type: Drain autoDrain: false - - type: DumpableSolution - solution: drainBuffer - - type: SolutionContainerVisuals - maxFillLevels: 1 - fillBaseName: fill- - solutionName: drainBuffer - type: StaticPrice price: 25 + - type: UserInterface + interfaces: + - key: enum.DisposalUnitUiKey.Key + type: DisposalUnitBoundUserInterface + - type: RatKingRummageable + - type: SolutionContainerManager + solutions: + drainBuffer: + maxVol: 100 + tank: + maxVol: 500 + - type: SolutionRegeneration + solution: tank + generated: + reagents: + - ReagentId: Water + Quantity: 1 + - type: DrainableSolution + solution: tank + - type: ReagentTank + - type: DumpableSolution + solution: drainBuffer + - type: GenericVisualizer + visuals: + enum.ToiletVisuals.SeatVisualState: + SeatVisualState.SeatUp: + SeatUp: { state: disposal-up } + SeatDown: { state: disposal-down } + enum.StashVisuals.DoorVisualState: + DoorVisualState.DoorOpen: + DoorOpen: { state: disposal-open } + DoorClosed: { state: disposal-closed } - type: entity id: ToiletDirtyWater diff --git a/Resources/Prototypes/Entities/Structures/Holographic/projections.yml b/Resources/Prototypes/Entities/Structures/Holographic/projections.yml index a62af015f7..aaa0ed716d 100644 --- a/Resources/Prototypes/Entities/Structures/Holographic/projections.yml +++ b/Resources/Prototypes/Entities/Structures/Holographic/projections.yml @@ -25,9 +25,6 @@ behaviors: - !type:DoActsBehavior acts: [ "Destruction" ] - - type: Tag - tags: - - NoPaint - type: entity id: HoloFan diff --git a/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml b/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml index b4b198eb77..ef89088d1a 100644 --- a/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml +++ b/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml @@ -40,6 +40,10 @@ - type: Damageable damageContainer: Inorganic damageModifierSet: Metallic + - type: RCDDeconstructable + cost: 4 + delay: 2 + fx: EffectRCDDeconstruct2 - type: Destructible thresholds: - trigger: @@ -70,7 +74,7 @@ mode: SnapgridCenter snap: - Wallmount - + - type: entity name: light description: "A light fixture. Draws power and produces light when equipped with a light tube." diff --git a/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml b/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml index 8f58464bd4..5a3dc37582 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml @@ -63,6 +63,22 @@ color: "#43ccb5" - type: Rotatable rotateWhileAnchored: true + - type: ItemSlots + slots: + disk_slot: + name: Disk + insertSound: + path: /Audio/Machines/terminal_insert_disc.ogg + ejectSound: + path: /Audio/Machines/terminal_insert_disc.ogg + whitelist: + components: + - ShuttleDestinationCoordinates + - type: ContainerContainer + containers: + board: !type:Container + ents: [] + disk_slot: !type:ContainerSlot {} - type: entity parent: BaseComputerShuttle diff --git a/Resources/Prototypes/Entities/Structures/Machines/Medical/chemistry_machines.yml b/Resources/Prototypes/Entities/Structures/Machines/Medical/chemistry_machines.yml index e2c210e7e6..23789730d0 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Medical/chemistry_machines.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Medical/chemistry_machines.yml @@ -29,8 +29,6 @@ components: - FitsInDispenser - type: Machine - - type: Wires - layoutId: chem - type: WiresPanel - type: WiresVisuals - type: ContainerContainer diff --git a/Resources/Prototypes/Entities/Structures/Machines/anomaly_equipment.yml b/Resources/Prototypes/Entities/Structures/Machines/anomaly_equipment.yml index cc9f8035fe..ab09a03fef 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/anomaly_equipment.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/anomaly_equipment.yml @@ -37,9 +37,6 @@ color: "#fca3c0" - type: Appearance - type: WiresPanel - - type: Wires - boardName: wires-board-name-vessel - layoutId: Vessel - type: AmbientSound enabled: false range: 3 @@ -160,6 +157,7 @@ board: APECircuitboard - type: Lock locked: false + - type: LockedWiresPanel - type: AccessReader access: [[ "Research" ]] - type: Emitter @@ -171,10 +169,12 @@ - AnomalousParticleDelta - AnomalousParticleEpsilon - AnomalousParticleZeta + - AnomalousParticleSigma setTypePorts: SetParticleDelta: AnomalousParticleDelta SetParticleEpsilon: AnomalousParticleEpsilon SetParticleZeta: AnomalousParticleZeta + SetParticleSigma: AnomalousParticleSigma fireBurstSize: 1 fireBurstDelayMin: 2 fireBurstDelayMax: 6 @@ -184,6 +184,7 @@ guides: - APE - type: Gun + projectileSpeed: 4 fireRate: 10 #just has to be fast enough to keep up with upgrades showExamineText: false selectedMode: SemiAuto @@ -194,9 +195,6 @@ - type: Appearance - type: WiresPanel - type: WiresVisuals - - type: Wires - boardName: wires-board-name-ape - layoutId: Ape - type: GenericVisualizer visuals: enum.PowerDeviceVisuals.Powered: @@ -204,6 +202,7 @@ True: { visible: true } False: { visible: false } - type: LockVisuals + - type: LockedAnchorable - type: DeviceNetwork deviceNetId: Wireless receiveFrequencyId: BasicDevice @@ -217,6 +216,7 @@ - SetParticleDelta - SetParticleEpsilon - SetParticleZeta + - SetParticleSigma - type: entity id: MachineAnomalyGenerator @@ -284,9 +284,6 @@ fuelCost: 10 doAfterDelay: 5 - type: WiresPanel - - type: Wires - boardName: wires-board-name-anomalygenerator - layoutId: AnomalyGenerator - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Machines/artifact_analyzer.yml b/Resources/Prototypes/Entities/Structures/Machines/artifact_analyzer.yml index 1b183661f5..b00d6d8986 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/artifact_analyzer.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/artifact_analyzer.yml @@ -143,9 +143,6 @@ Blunt: 10 - type: Machine board: ArtifactCrusherMachineCircuitboard - - type: Wires - boardName: wires-board-name-crusher - layoutId: Crusher - type: WiresPanel - type: Sprite sprite: Structures/Machines/artifact_crusher.rsi diff --git a/Resources/Prototypes/Entities/Structures/Machines/chem_master.yml b/Resources/Prototypes/Entities/Structures/Machines/chem_master.yml index d7df219663..aee1246021 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/chem_master.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/chem_master.yml @@ -63,9 +63,6 @@ False: { visible: false } # Machine / Construction stuff - type: WiresPanel - - type: Wires - boardName: wires-board-name-chemmaster - layoutId: chem_master - type: Machine board: ChemMasterMachineCircuitboard - type: ContainerContainer diff --git a/Resources/Prototypes/Entities/Structures/Machines/cloning_machine.yml b/Resources/Prototypes/Entities/Structures/Machines/cloning_machine.yml index 5d9ab0dd7e..0451b39490 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/cloning_machine.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/cloning_machine.yml @@ -52,9 +52,6 @@ materialWhiteList: - Biomass - type: WiresPanel - - type: Wires - boardName: wires-board-name-cloningpod - layoutId: CloningPod - type: ApcPowerReceiver powerLoad: 200 #Receives most of its power from the console - type: Appearance diff --git a/Resources/Prototypes/Entities/Structures/Machines/fatextractor.yml b/Resources/Prototypes/Entities/Structures/Machines/fatextractor.yml index 9f09e49059..fc417e68d6 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/fatextractor.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/fatextractor.yml @@ -98,9 +98,6 @@ - type: Machine board: FatExtractorMachineCircuitboard - type: WiresPanel - - type: Wires - boardName: wires-board-name-fatextractor - layoutId: FatExtractor - type: Appearance - type: Speech speechVerb: Robotic diff --git a/Resources/Prototypes/Entities/Structures/Machines/flatpacker.yml b/Resources/Prototypes/Entities/Structures/Machines/flatpacker.yml index 54a32db69f..3244789a02 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/flatpacker.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/flatpacker.yml @@ -52,9 +52,6 @@ path: /Audio/Items/rped.ogg - type: WiresPanel - type: WiresVisuals - - type: Wires - boardName: wires-board-name-flatpacker - layoutId: Flatpacker - type: Appearance - type: ActivatableUI key: enum.FlatpackCreatorUIKey.Key diff --git a/Resources/Prototypes/Entities/Structures/Machines/gravity_generator.yml b/Resources/Prototypes/Entities/Structures/Machines/gravity_generator.yml index 2eb4f57fab..aebc4b03de 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/gravity_generator.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/gravity_generator.yml @@ -120,9 +120,6 @@ min: 1 max: 1 - type: WiresPanel - - type: Wires - boardName: wires-board-name-minigravitygenerator - layoutId: MiniGravityGenerator - type: Machine board: MiniGravityGeneratorCircuitboard - type: ApcPowerReceiver diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index 5fbe84a3fe..c32f2992f9 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -33,9 +33,6 @@ - !type:DoActsBehavior acts: ["Destruction"] - type: WiresPanel - - type: Wires - boardName: wires-board-name-autolathe - layoutId: Autolathe - type: ActivatableUI key: enum.LatheUiKey.Key - type: ActivatableUIRequiresPower @@ -239,9 +236,6 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: Machine board: ProtolatheMachineCircuitboard - - type: Wires - boardName: wires-board-name-protolathe - layoutId: Protolathe - type: MaterialStorage whitelist: tags: @@ -683,7 +677,6 @@ - CartridgeMagnumUranium - CartridgePistolUranium - CartridgeRifleUranium - - ClothingEyesGlassesSecurity - ExplosivePayload - FlashPayload - HoloprojectorSecurity diff --git a/Resources/Prototypes/Entities/Structures/Machines/material_reclaimer.yml b/Resources/Prototypes/Entities/Structures/Machines/material_reclaimer.yml index 028e348fd4..9a9c5283c0 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/material_reclaimer.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/material_reclaimer.yml @@ -61,9 +61,6 @@ - type: Machine board: MaterialReclaimerMachineCircuitboard - type: WiresPanel - - type: Wires - boardName: wires-board-name-reclaimer - layoutId: Reclaimer - type: MaterialReclaimer whitelist: components: diff --git a/Resources/Prototypes/Entities/Structures/Machines/medical_scanner.yml b/Resources/Prototypes/Entities/Structures/Machines/medical_scanner.yml index 6f05baee94..de19db96b5 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/medical_scanner.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/medical_scanner.yml @@ -69,9 +69,6 @@ - type: Machine board: MedicalScannerMachineCircuitboard - type: WiresPanel - - type: Wires - boardName: wires-board-name-medicalscanner - layoutId: MedicalScanner - type: Appearance - type: Climbable - type: ApcPowerReceiver diff --git a/Resources/Prototypes/Entities/Objects/Devices/nuke.yml b/Resources/Prototypes/Entities/Structures/Machines/nuke.yml similarity index 95% rename from Resources/Prototypes/Entities/Objects/Devices/nuke.yml rename to Resources/Prototypes/Entities/Structures/Machines/nuke.yml index 811210d429..f37c42e474 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/nuke.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/nuke.yml @@ -1,5 +1,5 @@ - type: entity - parent: BaseStructure + parent: [BaseStructure, StructureWheeled] id: NuclearBomb name: nuclear fission explosive description: You probably shouldn't stick around to see if this is armed. @@ -49,7 +49,7 @@ shape: !type:PhysShapeCircle radius: 0.45 - density: 80 #It has wheels and bluespace tech to make it lighter. + density: 255 # Has "bluespace technology" to make it lighter, whatever that means. Don't mind the fact that this is lighter then a high capacity fuel tank. mask: - MachineMask layer: diff --git a/Resources/Prototypes/Entities/Structures/Machines/reagent_grinder.yml b/Resources/Prototypes/Entities/Structures/Machines/reagent_grinder.yml index 3bb1458b8c..773112f6f3 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/reagent_grinder.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/reagent_grinder.yml @@ -97,4 +97,8 @@ node: machine containers: - machine_parts - - machine_board \ No newline at end of file + - machine_board + - type: DrainableSolution + solution: output + - type: ExaminableSolution + solution: output \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Structures/Machines/research.yml b/Resources/Prototypes/Entities/Structures/Machines/research.yml index 7b369f62cc..83525a0510 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/research.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/research.yml @@ -23,8 +23,6 @@ priority: Low - type: ExtensionCableReceiver - type: WiresPanel - - type: Wires - layoutId: rndserver - type: WiresVisuals - type: Machine board: ResearchAndDevelopmentServerMachineCircuitboard diff --git a/Resources/Prototypes/Entities/Structures/Machines/telecomms.yml b/Resources/Prototypes/Entities/Structures/Machines/telecomms.yml index e12826a8ce..6cc1fc7981 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/telecomms.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/telecomms.yml @@ -51,9 +51,6 @@ - type: Machine board: TelecomServerCircuitboard - type: WiresPanel - - type: Wires - boardName: wires-board-name-telecomserver - layoutId: TelecomServer - type: Transform anchored: true - type: Pullable diff --git a/Resources/Prototypes/Entities/Structures/Machines/vending_machines.yml b/Resources/Prototypes/Entities/Structures/Machines/vending_machines.yml index c97dc4b9dc..e738510277 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/vending_machines.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/vending_machines.yml @@ -1391,9 +1391,6 @@ snap: - Wallmount components: - - type: Physics - canCollide: false - - type: Fixtures - type: Sprite drawdepth: WallMountedItems snapCardinals: false diff --git a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/portable.yml b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/portable.yml index 0e2a5f6fe5..316c403d7a 100644 --- a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/portable.yml +++ b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/portable.yml @@ -1,6 +1,6 @@ - type: entity id: PortableScrubber - parent: [BaseMachinePowered, ConstructibleMachine] + parent: [BaseMachinePowered, ConstructibleMachine, StructureWheeled] name: portable scrubber description: It scrubs, portably! components: diff --git a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/unary.yml b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/unary.yml index c2f8fa339d..4ee78f1213 100644 --- a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/unary.yml +++ b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/unary.yml @@ -206,7 +206,7 @@ visuals: # toggle color of the unshaded light: enum.OutletInjectorVisuals.Enabled: - unshaded: + enum.LightLayers.Unshaded: True: { color: "#5eff5e" } False: { color: "#990000" } - type: Appearance @@ -245,9 +245,6 @@ inHandsOnly: false key: enum.ThermomachineUiKey.Key - type: WiresPanel - - type: Wires - boardName: wires-board-name-thermomachine - layoutId: Thermomachine - type: WiresVisuals - type: NodeContainer nodes: @@ -430,9 +427,6 @@ - type: Machine board: CondenserMachineCircuitBoard - type: WiresPanel - - type: Wires - boardName: wires-board-name-condenser - layoutId: Condenser - type: WiresVisuals - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Structures/Piping/Disposal/units.yml b/Resources/Prototypes/Entities/Structures/Piping/Disposal/units.yml index 1193182d09..25047bb575 100644 --- a/Resources/Prototypes/Entities/Structures/Piping/Disposal/units.yml +++ b/Resources/Prototypes/Entities/Structures/Piping/Disposal/units.yml @@ -10,7 +10,6 @@ components: - type: Sprite sprite: Structures/Piping/disposal.rsi - snapCardinals: true layers: - state: condisposal map: [ "enum.DisposalUnitVisualLayers.Unanchored" ] @@ -19,7 +18,7 @@ - state: disposal-charging map: [ "enum.DisposalUnitVisualLayers.BaseCharging" ] - state: disposal-flush - map: [ "enum.DisposalUnitVisualLayers.BaseFlush" ] + map: [ "enum.DisposalUnitVisualLayers.OverlayFlush" ] - state: dispover-charge map: [ "enum.DisposalUnitVisualLayers.OverlayCharging" ] - state: dispover-ready @@ -30,17 +29,6 @@ map: [ "enum.DisposalUnitVisualLayers.OverlayEngaged" ] - type: Physics bodyType: Static - - type: Fixtures - fixtures: - fix1: - shape: - !type:PhysShapeAabb - bounds: "-0.25,-0.4,0.25,0.4" - density: 75 - mask: - - MachineMask - layer: - - MachineLayer - type: Destructible thresholds: - trigger: @@ -82,6 +70,9 @@ parent: DisposalUnitBase name: disposal unit components: + - type: Sprite + sprite: Structures/Piping/disposal.rsi + snapCardinals: true - type: Construction graph: DisposalMachine node: disposal_unit @@ -100,6 +91,7 @@ components: - type: Sprite sprite: Structures/Piping/disposal.rsi + snapCardinals: true layers: - state: conmailing map: [ "enum.DisposalUnitVisualLayers.Unanchored" ] @@ -108,7 +100,7 @@ - state: mailing-charging map: [ "enum.DisposalUnitVisualLayers.BaseCharging" ] - state: mailing-flush - map: [ "enum.DisposalUnitVisualLayers.BaseFlush" ] + map: [ "enum.DisposalUnitVisualLayers.OverlayFlush" ] - state: dispover-charge map: [ "enum.DisposalUnitVisualLayers.OverlayCharging" ] - state: dispover-ready diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/emitter.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/emitter.yml index 52698f62cc..b999b2bded 100644 --- a/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/emitter.yml +++ b/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/emitter.yml @@ -84,6 +84,8 @@ - type: Lock locked: false - type: LockVisuals + - type: LockedAnchorable + - type: LockedWiresPanel - type: AccessReader access: [[ "Engineering" ]] - type: Machine diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/portable_generator.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/portable_generator.yml index b606c01f1d..dbaacd6abc 100644 --- a/Resources/Prototypes/Entities/Structures/Power/Generation/portable_generator.yml +++ b/Resources/Prototypes/Entities/Structures/Power/Generation/portable_generator.yml @@ -6,7 +6,7 @@ - type: entity abstract: true id: PortableGeneratorBase - parent: [ BaseMachine, ConstructibleMachine ] + parent: [ BaseMachine, ConstructibleMachine, StructureWheeled] components: # Basic properties - type: Transform @@ -27,8 +27,8 @@ shape: !type:PhysShapeAabb bounds: "-0.40,-0.40,0.40,0.40" - # It has wheels - density: 45 + # Despite the heavy weight, it has wheels, so it's still fairly portable. + density: 155 mask: - MachineMask layer: @@ -42,9 +42,6 @@ # Construction, interaction - type: WiresPanel - - type: Wires - boardName: wires-board-name-generator - layoutId: Generator - type: UserInterface interfaces: - key: enum.GeneratorComponentUiKey.Key @@ -259,8 +256,7 @@ shape: !type:PhysShapeAabb bounds: "-0.30,-0.30,0.30,0.30" - # It has wheels - density: 30 + density: 80 mask: - MachineMask layer: diff --git a/Resources/Prototypes/Entities/Structures/Power/apc.yml b/Resources/Prototypes/Entities/Structures/Power/apc.yml index 7efa53e254..4df502791f 100644 --- a/Resources/Prototypes/Entities/Structures/Power/apc.yml +++ b/Resources/Prototypes/Entities/Structures/Power/apc.yml @@ -97,9 +97,6 @@ supplyRampRate: 500 - type: WallMount - type: WiresPanel - - type: Wires - boardName: wires-board-name-apc - layoutId: APC - type: WiresVisuals - type: Damageable damageContainer: Inorganic diff --git a/Resources/Prototypes/Entities/Structures/Power/cable_terminal.yml b/Resources/Prototypes/Entities/Structures/Power/cable_terminal.yml index da724014dc..2e8f047c21 100644 --- a/Resources/Prototypes/Entities/Structures/Power/cable_terminal.yml +++ b/Resources/Prototypes/Entities/Structures/Power/cable_terminal.yml @@ -17,6 +17,10 @@ - type: Damageable damageContainer: Inorganic damageModifierSet: Metallic + - type: RCDDeconstructable + cost: 2 + delay: 2 + fx: EffectRCDDeconstruct2 - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Power/cables.yml b/Resources/Prototypes/Entities/Structures/Power/cables.yml index de66dfc66d..a81c89de0f 100644 --- a/Resources/Prototypes/Entities/Structures/Power/cables.yml +++ b/Resources/Prototypes/Entities/Structures/Power/cables.yml @@ -43,6 +43,10 @@ lowVoltageNode: power - type: CableVis node: power + - type: RCDDeconstructable + cost: 2 + delay: 2 + fx: EffectRCDDeconstruct2 - type: entity parent: CableBase diff --git a/Resources/Prototypes/Entities/Structures/Power/chargers.yml b/Resources/Prototypes/Entities/Structures/Power/chargers.yml index 388cc3c987..582a5b0dee 100644 --- a/Resources/Prototypes/Entities/Structures/Power/chargers.yml +++ b/Resources/Prototypes/Entities/Structures/Power/chargers.yml @@ -83,9 +83,6 @@ visible: false - type: Machine board: CellRechargerCircuitboard - - type: Wires - boardName: wires-board-name-recharger - layoutId: Recharger - type: WiresPanel - type: GenericVisualizer visuals: @@ -250,8 +247,6 @@ - machine_parts - machine_board - entity_storage - - type: Wires - layoutId: borgcharger - type: WiresPanel - type: WiresVisuals - type: Machine diff --git a/Resources/Prototypes/Entities/Structures/Power/smes.yml b/Resources/Prototypes/Entities/Structures/Power/smes.yml index c2170a127a..1e3559e5a9 100644 --- a/Resources/Prototypes/Entities/Structures/Power/smes.yml +++ b/Resources/Prototypes/Entities/Structures/Power/smes.yml @@ -67,9 +67,6 @@ color: "#c9c042" castShadows: false - type: WiresPanel - - type: Wires - boardName: wires-board-name-smes - layoutId: SMES - type: Machine board: SMESMachineCircuitboard - type: StationInfiniteBatteryTarget diff --git a/Resources/Prototypes/Entities/Structures/Power/substation.yml b/Resources/Prototypes/Entities/Structures/Power/substation.yml index 94de12be18..4bd0bec5ea 100644 --- a/Resources/Prototypes/Entities/Structures/Power/substation.yml +++ b/Resources/Prototypes/Entities/Structures/Power/substation.yml @@ -92,9 +92,6 @@ intensitySlope: 2 totalIntensity: 200 - type: WiresPanel - - type: Wires - boardName: wires-board-name-substation - layoutId: Substation - type: Machine board: SubstationMachineCircuitboard - type: StationInfiniteBatteryTarget diff --git a/Resources/Prototypes/Entities/Structures/Specific/Anomaly/anomalies.yml b/Resources/Prototypes/Entities/Structures/Specific/Anomaly/anomalies.yml index 14a9997b80..c7b3e8ab5d 100644 --- a/Resources/Prototypes/Entities/Structures/Specific/Anomaly/anomalies.yml +++ b/Resources/Prototypes/Entities/Structures/Specific/Anomaly/anomalies.yml @@ -21,6 +21,7 @@ anchored: false - type: Physics bodyType: Static + bodyStatus: InAir - type: Fixtures fixtures: fix1: @@ -47,6 +48,9 @@ - type: EmitSoundOnSpawn sound: path: /Audio/Effects/teleport_arrival.ogg + - type: SecretDataAnomaly + randomStartSecretMin: 0 + randomStartSecretMax: 2 - type: entity id: AnomalyPyroclastic @@ -160,6 +164,8 @@ - type: Anomaly corePrototype: AnomalyCoreFlesh coreInertPrototype: AnomalyCoreFleshInert + minPulseLength: 180 + maxPulseLength: 300 - type: Sprite layers: - state: anom5 @@ -351,6 +357,8 @@ - type: Anomaly corePrototype: AnomalyCoreRock coreInertPrototype: AnomalyCoreRockInert + minPulseLength: 180 + maxPulseLength: 300 - type: Sprite layers: - state: anom6 @@ -598,9 +606,11 @@ color: "#6270bb" - type: Anomaly animationTime: 6 - offset: 0.05, 0 + offset: 0, 0 corePrototype: AnomalyCoreFlora coreInertPrototype: AnomalyCoreFloraInert + minPulseLength: 60 + maxPulseLength: 120 anomalyContactDamage: types: Slash: 0 @@ -705,6 +715,8 @@ - type: Anomaly corePrototype: AnomalyCoreLiquid coreInertPrototype: AnomalyCoreLiquidInert + minPulseLength: 60 + maxPulseLength: 120 anomalyContactDamage: types: Slash: 1 @@ -818,6 +830,8 @@ - type: Anomaly corePrototype: AnomalyCoreShadow coreInertPrototype: AnomalyCoreShadowInert + minPulseLength: 60 + maxPulseLength: 120 anomalyContactDamage: types: Cold: 10 diff --git a/Resources/Prototypes/Entities/Structures/Specific/Janitor/drain.yml b/Resources/Prototypes/Entities/Structures/Specific/Janitor/drain.yml new file mode 100644 index 0000000000..e0247001f2 --- /dev/null +++ b/Resources/Prototypes/Entities/Structures/Specific/Janitor/drain.yml @@ -0,0 +1,62 @@ +- type: entity + id: FloorDrain + name: drain + description: Drains puddles around it. Useful for dumping mop buckets or keeping certain rooms clean. + placement: + mode: SnapgridCenter + components: + - type: Sprite + drawdepth: FloorObjects + sprite: Objects/Specific/Janitorial/drain.rsi + layers: + - state: icon + - map: [ "enum.SolutionContainerLayers.Fill" ] + state: fill-1 + visible: false + - type: InteractionOutline + - type: Clickable + - type: Transform + anchored: true + - type: Physics + bodyType: Static + canCollide: false + - type: AmbientSound + enabled: false + volume: -8 + range: 8 + sound: + path: /Audio/Ambience/Objects/drain.ogg + - type: Drain + - type: DumpableSolution + solution: drainBuffer + - type: Appearance + - type: SolutionContainerVisuals + maxFillLevels: 1 + fillBaseName: fill- + solutionName: drainBuffer + - type: SolutionContainerManager + solutions: + drainBuffer: + maxVol: 1000 + - type: DrainableSolution + solution: drainBuffer + - type: Damageable + damageContainer: Inorganic + damageModifierSet: Metallic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 200 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - trigger: + !type:DamageTrigger + damage: 100 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - !type:PlaySoundBehavior + sound: + collection: MetalBreak diff --git a/Resources/Prototypes/Entities/Structures/Specific/Janitor/janicart.yml b/Resources/Prototypes/Entities/Structures/Specific/Janitor/janicart.yml new file mode 100644 index 0000000000..bdbff1b504 --- /dev/null +++ b/Resources/Prototypes/Entities/Structures/Specific/Janitor/janicart.yml @@ -0,0 +1,324 @@ +# Mop Bucket +- type: entity + name: mop bucket + id: MopBucket + parent: [BaseStructureDynamic, StructureWheeled] + description: Holds water and the tears of the janitor. + components: + - type: Clickable + - type: Sprite + sprite: Objects/Specific/Janitorial/janitorial.rsi + noRot: true + layers: + - state: mopbucket + - state: mopbucket_water-1 + map: ["enum.SolutionContainerLayers.Fill"] + visible: false + drawdepth: Objects + - type: InteractionOutline + - type: SolutionContainerManager + solutions: + bucket: + maxVol: 600 + - type: Spillable + solution: bucket + spillDelay: 3.0 + - type: DrainableSolution + solution: bucket + - type: RefillableSolution + solution: bucket + - type: ExaminableSolution + solution: bucket + - type: Tag + tags: + - Wringer + - type: ItemMapper + mapLayers: + mopbucket_shark_blue: + whitelist: + tags: + - PlushieSharkBlue + mopbucket_shark_pink: + whitelist: + tags: + - PlushieSharkPink + mopbucket_shark_grey: + whitelist: + tags: + - PlushieSharkGrey + sprite: Objects/Fun/sharkplush.rsi + - type: Transform + noRot: true + - type: ItemSlots + slots: + shark_slot: + name: mop-bucket-slot-component-slot-name-shark + whitelist: + tags: + - PlushieSharkBlue + - PlushieSharkPink + - PlushieSharkGrey + priority: 3 # Higher than drinking priority + - type: Drink + solution: bucket + - type: SolutionContainerVisuals + maxFillLevels: 3 + fillBaseName: mopbucket_water- + - type: ContainerContainer + containers: + storagebase: !type:Container + ents: [] + shark_slot: !type:ContainerSlot {} + - type: GuideHelp + guides: + - Janitorial + - type: Damageable + damageContainer: Inorganic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 70 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + +- type: entity + name: mop bucket + id: MopBucketFull + parent: MopBucket + suffix: full + components: + - type: Sprite + layers: + - state: mopbucket + - state: mopbucket_water-3 + map: [ "enum.SolutionContainerLayers.Fill" ] + - type: SolutionContainerManager + solutions: + bucket: + maxVol: 600 + reagents: + - ReagentId: Water + Quantity: 600 + +# Janicart +- type: entity + name: janitorial trolley + id: JanitorialTrolley + parent: [BaseStructureDynamic, StructureWheeled] + description: This is the alpha and omega of sanitation. + components: + - type: Sprite + noRot: true + sprite: Objects/Specific/Janitorial/janitorial_cart.rsi + layers: + - state: cart + - state: cart_water-1 + map: ["enum.SolutionContainerLayers.Fill"] + visible: false + - type: Rotatable + - type: InteractionOutline + # Removing storage until OnInteractUsing logic resolved + #- type: Storage + # popup: false + # capacity: 80 + # blacklist: # there is exclusive item slots for that + # tags: + # - Mop + # - TrashBag + # - Bucket + - type: ItemSlots + slots: + mop_slot: + name: janitorial-trolley-slot-component-slot-name-mop + whitelist: + tags: + - Mop + insertOnInteract: false # or it conflicts with bucket logic + priority: 9 # Higher than bucket slot + plunger_slot: + name: janitorial-trolley-slot-component-slot-name-plunger + whitelist: + tags: + - Plunger + priority: 8 + wetfloorsign_slot4: + name: janitorial-trolley-slot-component-slot-name-sign + whitelist: + tags: + - WetFloorSign + priority: 7 + wetfloorsign_slot3: + name: janitorial-trolley-slot-component-slot-name-sign + whitelist: + tags: + - WetFloorSign + priority: 7 + wetfloorsign_slot2: + name: janitorial-trolley-slot-component-slot-name-sign + whitelist: + tags: + - WetFloorSign + priority: 7 + wetfloorsign_slot1: + name: janitorial-trolley-slot-component-slot-name-sign + whitelist: + tags: + - WetFloorSign + priority: 7 + lightreplacer_slot: + name: janitorial-trolley-slot-component-slot-name-lightreplacer + whitelist: + components: + - LightReplacer + priority: 6 + spraybottle_slot: + name: janitorial-trolley-slot-component-slot-name-spray + whitelist: + tags: + - Spray + insertOnInteract: false # or it conflicts with bucket logic + priority: 5 # Higher than bucket slot + bucket_slot: + name: janitorial-trolley-slot-component-slot-name-bucket + whitelist: + tags: + - Bucket + insertOnInteract: false # or it also conflicts with bucket logic + priority: 4 # Higher than trash bag slot + trashbag_slot: + name: janitorial-trolley-slot-component-slot-name-trashbag + whitelist: + tags: + - TrashBag + priority: 3 # Higher than drinking priority + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeCircle + radius: 0.3 + density: 250 + layer: + - MobLayer + mask: + - MobMask + - type: Spillable + solution: bucket + spillDelay: 3.0 + - type: SolutionContainerManager + solutions: + bucket: + maxVol: 800 + reagents: + - ReagentId: Water + Quantity: 600 # 3 quarters full at roundstart to make it more appealing + - type: DrainableSolution + solution: bucket + - type: RefillableSolution + solution: bucket + - type: ExaminableSolution + solution: bucket + - type: Tag + tags: + - Wringer + - type: Damageable + damageContainer: Inorganic + damageModifierSet: Metallic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 400 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - trigger: + !type:DamageTrigger + damage: 200 + behaviors: + - !type:EmptyAllContainersBehaviour + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: + collection: MetalBreak + - type: ItemMapper + mapLayers: + cart_plunger: + whitelist: + tags: + - Plunger + cart_mop: + whitelist: + tags: + - MopBasic + cart_advmop: + whitelist: + tags: + - MopAdv + cart_garbage: + whitelist: + tags: + - TrashBag + cart_replacer: + whitelist: + components: + - LightReplacer + cart_spray: + whitelist: + tags: + - Spray + cart_sign1: # this is like stack of floor signs + minCount: 1 + whitelist: + tags: + - WetFloorSign + cart_sign2: + minCount: 2 + whitelist: + tags: + - WetFloorSign + cart_sign3: + minCount: 3 + whitelist: + tags: + - WetFloorSign + cart_sign4: + minCount: 4 + whitelist: + tags: + - WetFloorSign + cart_bucket: + whitelist: + tags: + - Bucket + sprite: Objects/Specific/Janitorial/janitorial_cart.rsi + - type: Appearance + - type: SolutionContainerVisuals + maxFillLevels: 3 + fillBaseName: cart_water- + - type: UserInterface + interfaces: + - key: enum.StorageUiKey.Key + type: StorageBoundUserInterface + - type: Drink + solution: bucket + - type: ContainerContainer + containers: + storagebase: !type:Container + ents: [] + mop_slot: !type:ContainerSlot {} + trashbag_slot: !type:ContainerSlot {} + bucket_slot: !type:ContainerSlot {} + plunger_slot: !type:ContainerSlot {} + wetfloorsign_slot4: !type:ContainerSlot {} + wetfloorsign_slot3: !type:ContainerSlot {} + wetfloorsign_slot2: !type:ContainerSlot {} + wetfloorsign_slot1: !type:ContainerSlot {} + lightreplacer_slot: !type:ContainerSlot {} + spraybottle_slot: !type:ContainerSlot {} + - type: GuideHelp + guides: + - Janitorial diff --git a/Resources/Prototypes/Entities/Structures/Storage/Crates/crates.yml b/Resources/Prototypes/Entities/Structures/Storage/Crates/crates.yml index 24bcf7cf7a..e55612d2c4 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Crates/crates.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Crates/crates.yml @@ -563,7 +563,7 @@ sprite: Structures/Storage/Crates/syndicate.rsi - type: entity - parent: CrateBaseWeldable + parent: [StructureWheeled, CrateBaseWeldable] id: CrateTrashCart name: trash cart components: diff --git a/Resources/Prototypes/Entities/Structures/Storage/Tanks/base_structuretanks.yml b/Resources/Prototypes/Entities/Structures/Storage/Tanks/base_structuretanks.yml index 238efaf68d..7b56e6d36b 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Tanks/base_structuretanks.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Tanks/base_structuretanks.yml @@ -65,3 +65,21 @@ - type: ReagentTank - type: Transform noRot: true + +# For highcap tanks +- type: entity + id: StorageTankBig + parent: StorageTank + abstract: true + components: + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeAabb + bounds: "-0.4,-0.4,0.4,0.4" + density: 455 #very heavy, they store 10k units of reagents after all. + mask: + - MachineMask + layer: + - WallLayer \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Structures/Storage/Tanks/tanks.yml b/Resources/Prototypes/Entities/Structures/Storage/Tanks/tanks.yml index a644c7afa1..e177cc72b1 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Tanks/tanks.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Tanks/tanks.yml @@ -2,7 +2,7 @@ - type: entity id: WeldingFuelTank - parent: StorageTank + parent: [StorageTank, StructureWheeled] name: fuel tank description: A fuel tank. It's used to store high amounts of fuel. suffix: Empty @@ -48,7 +48,7 @@ Quantity: 1500 - type: entity - parent: WeldingFuelTank + parent: [StorageTankBig, WeldingFuelTank] # StorageTankBig must come first, or else the desnity won't get inherited. id: WeldingFuelTankHighCapacity name: high-capacity fuel tank description: A highly pressurized fuel tank made to hold gargantuan amounts of welding fuel. @@ -81,7 +81,7 @@ - type: entity id: WaterTank - parent: StorageTank + parent: [StorageTank, StructureWheeled] name: water tank description: A water tank. It's used to store high amounts of water. suffix: Empty @@ -115,7 +115,7 @@ Quantity: 1500 - type: entity - parent: WaterTankFull + parent: StorageTank id: WaterCooler name: water cooler description: Seems like a good place to stand and waste time. It has a stock of paper cups on the side. @@ -157,14 +157,20 @@ - FitsInDispenser tags: - Trash + - type: ExaminableSolution + solution: tank + - type: StaticPrice + price: 500 - type: entity - parent: StorageTank + parent: [StorageTankBig, WaterTank] id: WaterTankHighCapacity name: high-capacity water tank description: A highly pressurized water tank made to hold gargantuan amounts of water. suffix: Full components: + - type: StaticPrice + price: 2500 - type: Sprite sprite: Structures/Storage/tanks.rsi layers: @@ -192,7 +198,7 @@ - type: entity id: GenericTank - parent: StorageTank + parent: [StorageTank, StructureWheeled] suffix: Empty components: - type: StaticPrice diff --git a/Resources/Prototypes/Entities/Structures/Walls/fence_metal.yml b/Resources/Prototypes/Entities/Structures/Walls/fence_metal.yml index 88d2f272c0..1dca59225c 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/fence_metal.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/fence_metal.yml @@ -10,9 +10,6 @@ Brute: path: "/Audio/Weapons/grille_hit.ogg" - - type: Tag - tags: - - RCDDeconstructWhitelist - type: Sprite sprite: Structures/Walls/fence.rsi drawdepth: WallTops @@ -78,6 +75,10 @@ True: { visible: True } False: { visible: False } - type: AnimationPlayer + - type: RCDDeconstructable + cost: 2 + delay: 2 + fx: EffectRCDDeconstruct2 - type: entity parent: BaseFenceMetal diff --git a/Resources/Prototypes/Entities/Structures/Walls/fence_wood.yml b/Resources/Prototypes/Entities/Structures/Walls/fence_wood.yml index f2b03aaeb8..55b7e40803 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/fence_wood.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/fence_wood.yml @@ -12,7 +12,6 @@ "/Audio/Weapons/boxingpunch1.ogg" - type: Tag tags: - - RCDDeconstructWhitelist - Wooden - type: Sprite sprite: Structures/Walls/wooden_fence.rsi @@ -24,6 +23,10 @@ - type: Damageable damageContainer: Inorganic damageModifierSet: Wood + - type: RCDDeconstructable + cost: 2 + delay: 2 + fx: EffectRCDDeconstruct2 - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Walls/grille.yml b/Resources/Prototypes/Entities/Structures/Walls/grille.yml index b532db221d..11ada142fa 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/grille.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/grille.yml @@ -9,9 +9,10 @@ Brute: path: "/Audio/Weapons/grille_hit.ogg" - - type: Tag - tags: - - RCDDeconstructWhitelist + - type: RCDDeconstructable + cost: 6 + delay: 4 + fx: EffectRCDDeconstruct4 - type: CanBuildWindowOnTop - type: Sprite drawdepth: Walls @@ -120,9 +121,10 @@ - type: Icon sprite: Structures/Walls/grille.rsi state: grille_broken - - type: Tag - tags: - - RCDDeconstructWhitelist + - type: RCDDeconstructable + cost: 6 + delay: 4 + fx: EffectRCDDeconstruct4 - type: Construction graph: Grille node: grilleBroken diff --git a/Resources/Prototypes/Entities/Structures/Walls/railing.yml b/Resources/Prototypes/Entities/Structures/Walls/railing.yml index 95d16742d5..a23c559aba 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/railing.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/railing.yml @@ -57,6 +57,10 @@ - type: Construction graph: Railing node: railing + - type: RCDDeconstructable + cost: 2 + delay: 2 + fx: EffectRCDDeconstruct2 - type: entity parent: BaseStructure @@ -126,6 +130,10 @@ - type: Construction graph: Railing node: railingCorner + - type: RCDDeconstructable + cost: 2 + delay: 2 + fx: EffectRCDDeconstruct2 - type: entity parent: BaseStructure @@ -186,7 +194,11 @@ - type: Construction graph: Railing node: railingCornerSmall - + - type: RCDDeconstructable + cost: 2 + delay: 2 + fx: EffectRCDDeconstruct2 + - type: entity parent: BaseStructure id: RailingRound @@ -261,3 +273,7 @@ - type: Construction graph: Railing node: railingRound + - type: RCDDeconstructable + cost: 2 + delay: 2 + fx: EffectRCDDeconstruct2 diff --git a/Resources/Prototypes/Entities/Structures/Walls/walls.yml b/Resources/Prototypes/Entities/Structures/Walls/walls.yml index f06c0fc424..8eca58b124 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/walls.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/walls.yml @@ -59,11 +59,14 @@ - type: Tag tags: - Wall - - RCDDeconstructWhitelist - type: Sprite sprite: Structures/Walls/brick.rsi - type: Icon sprite: Structures/Walls/brick.rsi + - type: RCDDeconstructable + cost: 6 + delay: 8 + fx: EffectRCDDeconstruct8 - type: Destructible thresholds: - trigger: @@ -90,7 +93,6 @@ - type: Tag tags: - Wall - - RCDDeconstructWhitelist - type: Sprite sprite: Structures/Walls/clock.rsi - type: Icon @@ -123,7 +125,6 @@ - type: Tag tags: - Wall - - RCDDeconstructWhitelist - type: Sprite sprite: Structures/Walls/clown.rsi - type: Icon @@ -131,6 +132,10 @@ - type: Construction graph: Girder node: bananiumWall + - type: RCDDeconstructable + cost: 6 + delay: 8 + fx: EffectRCDDeconstruct8 - type: Destructible thresholds: - trigger: @@ -156,7 +161,6 @@ components: - type: Tag tags: - - RCDDeconstructWhitelist - Wall - Structure - type: Sprite @@ -190,7 +194,6 @@ components: - type: Tag tags: - - RCDDeconstructWhitelist - Wall - type: Sprite sprite: Structures/Walls/cult.rsi @@ -223,7 +226,6 @@ tags: - Wall - Debug - - RCDDeconstructWhitelist - type: Sprite sprite: Structures/Walls/debug.rsi - type: Icon @@ -253,11 +255,14 @@ - type: Tag tags: - Wall - - RCDDeconstructWhitelist - type: Sprite sprite: Structures/Walls/diamond.rsi - type: Icon sprite: Structures/Walls/diamond.rsi + - type: RCDDeconstructable + cost: 6 + delay: 8 + fx: EffectRCDDeconstruct8 - type: Destructible thresholds: - trigger: @@ -283,7 +288,6 @@ - type: Tag tags: - Wall - - RCDDeconstructWhitelist - type: Sprite sprite: Structures/Walls/gold.rsi - type: Icon @@ -291,6 +295,10 @@ - type: Construction graph: Girder node: goldWall + - type: RCDDeconstructable + cost: 6 + delay: 8 + fx: EffectRCDDeconstruct8 - type: Destructible thresholds: - trigger: @@ -325,7 +333,6 @@ - type: Tag tags: - Wall - - RCDDeconstructWhitelist - type: Sprite sprite: Structures/Walls/ice.rsi - type: Icon @@ -355,7 +362,6 @@ - type: Tag tags: - Wall - - RCDDeconstructWhitelist - type: Sprite sprite: Structures/Walls/plasma.rsi - type: Icon @@ -363,6 +369,10 @@ - type: Construction graph: Girder node: plasmaWall + - type: RCDDeconstructable + cost: 6 + delay: 8 + fx: EffectRCDDeconstruct8 - type: Destructible thresholds: - trigger: @@ -399,7 +409,6 @@ - type: Tag tags: - Wall - - RCDDeconstructWhitelist - type: Sprite sprite: Structures/Walls/plastic.rsi - type: Icon @@ -407,6 +416,10 @@ - type: Construction graph: Girder node: plasticWall + - type: RCDDeconstructable + cost: 6 + delay: 8 + fx: EffectRCDDeconstruct8 - type: Destructible thresholds: - trigger: @@ -459,7 +472,6 @@ - type: Tag tags: - Wall - - RCDDeconstructWhitelist - type: Destructible thresholds: - trigger: @@ -604,7 +616,6 @@ - type: Tag tags: - Wall - - RCDDeconstructWhitelist - type: Sprite sprite: Structures/Walls/riveted.rsi - type: Icon @@ -639,11 +650,14 @@ - type: Tag tags: - Wall - - RCDDeconstructWhitelist - type: Sprite sprite: Structures/Walls/sandstone.rsi - type: Icon sprite: Structures/Walls/sandstone.rsi + - type: RCDDeconstructable + cost: 6 + delay: 8 + fx: EffectRCDDeconstruct8 - type: Destructible thresholds: - trigger: @@ -669,7 +683,6 @@ - type: Tag tags: - Wall - - RCDDeconstructWhitelist - type: Sprite sprite: Structures/Walls/silver.rsi - type: Icon @@ -677,6 +690,10 @@ - type: Construction graph: Girder node: silverWall + - type: RCDDeconstructable + cost: 6 + delay: 8 + fx: EffectRCDDeconstruct8 - type: Destructible thresholds: - trigger: @@ -842,7 +859,6 @@ - type: Tag tags: - Wall - - RCDDeconstructWhitelist - type: Sprite sprite: Structures/Walls/solid.rsi - type: WallReplacementMarker @@ -851,6 +867,10 @@ node: wall - type: Icon sprite: Structures/Walls/solid.rsi + - type: RCDDeconstructable + cost: 6 + delay: 8 + fx: EffectRCDDeconstruct8 - type: Destructible thresholds: - trigger: @@ -1012,7 +1032,6 @@ - type: Tag tags: - Wall - - RCDDeconstructWhitelist - type: Sprite sprite: Structures/Walls/web.rsi - type: Icon @@ -1224,11 +1243,14 @@ - type: Tag tags: - Wall - - RCDDeconstructWhitelist - type: Sprite sprite: Structures/Walls/cobblebrick.rsi - type: Icon sprite: Structures/Walls/cobblebrick.rsi + - type: RCDDeconstructable + cost: 6 + delay: 8 + fx: EffectRCDDeconstruct8 - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Windows/mining.yml b/Resources/Prototypes/Entities/Structures/Windows/mining.yml index 910c3daae2..82d11b732b 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/mining.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/mining.yml @@ -1,7 +1,7 @@ - type: entity id: MiningWindow name: mining window - parent: Window + parent: WindowRCDResistant components: - type: Sprite drawdepth: WallTops diff --git a/Resources/Prototypes/Entities/Structures/Windows/plasma.yml b/Resources/Prototypes/Entities/Structures/Windows/plasma.yml index 0dd2a1b06c..36a12f2d84 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/plasma.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/plasma.yml @@ -1,7 +1,7 @@ - type: entity id: PlasmaWindow name: plasma window - parent: Window + parent: WindowRCDResistant components: - type: Sprite drawdepth: WallTops @@ -55,7 +55,7 @@ - type: entity id: PlasmaWindowDirectional - parent: WindowDirectional + parent: WindowDirectionalRCDResistant name: directional plasma window description: Don't smudge up the glass down there. placement: diff --git a/Resources/Prototypes/Entities/Structures/Windows/reinforced.yml b/Resources/Prototypes/Entities/Structures/Windows/reinforced.yml index 1c79644ce4..d8b6c7d11d 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/reinforced.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/reinforced.yml @@ -14,6 +14,10 @@ - type: Damageable damageContainer: StructuralInorganic damageModifierSet: RGlass + - type: RCDDeconstructable + cost: 6 + delay: 6 + fx: EffectRCDDeconstruct6 - type: Destructible thresholds: - trigger: @@ -99,6 +103,10 @@ sprite: Structures/Windows/cracks_directional.rsi - type: Damageable damageModifierSet: RGlass + - type: RCDDeconstructable + cost: 4 + delay: 4 + fx: EffectRCDDeconstruct4 - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Windows/rplasma.yml b/Resources/Prototypes/Entities/Structures/Windows/rplasma.yml index d81204be07..93859b1db2 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/rplasma.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/rplasma.yml @@ -1,7 +1,7 @@ - type: entity id: ReinforcedPlasmaWindow name: reinforced plasma window - parent: Window + parent: WindowRCDResistant components: - type: Sprite drawdepth: WallTops @@ -58,7 +58,7 @@ - type: entity id: PlasmaReinforcedWindowDirectional - parent: WindowDirectional + parent: WindowDirectionalRCDResistant name: directional reinforced plasma window description: Don't smudge up the glass down there. placement: diff --git a/Resources/Prototypes/Entities/Structures/Windows/ruranium.yml b/Resources/Prototypes/Entities/Structures/Windows/ruranium.yml index 6ed2cc5926..e26fec65b7 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/ruranium.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/ruranium.yml @@ -1,7 +1,7 @@ - type: entity id: ReinforcedUraniumWindow name: reinforced uranium window - parent: Window + parent: WindowRCDResistant components: - type: Sprite drawdepth: WallTops diff --git a/Resources/Prototypes/Entities/Structures/Windows/shuttle.yml b/Resources/Prototypes/Entities/Structures/Windows/shuttle.yml index d953cc588a..f1b840c143 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/shuttle.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/shuttle.yml @@ -1,7 +1,7 @@ - type: entity id: ShuttleWindow name: shuttle window - parent: Window + parent: WindowRCDResistant components: - type: Sprite drawdepth: WallTops diff --git a/Resources/Prototypes/Entities/Structures/Windows/uranium.yml b/Resources/Prototypes/Entities/Structures/Windows/uranium.yml index b956d369fa..e5228bc593 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/uranium.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/uranium.yml @@ -1,7 +1,7 @@ - type: entity id: UraniumWindow name: uranium window - parent: Window + parent: WindowRCDResistant components: - type: Sprite drawdepth: WallTops diff --git a/Resources/Prototypes/Entities/Structures/Windows/window.yml b/Resources/Prototypes/Entities/Structures/Windows/window.yml index 375d0c16ae..606c54e35b 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/window.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/window.yml @@ -16,7 +16,6 @@ arc: 360 # interact despite grilles - type: Tag tags: - - RCDDeconstructWhitelist - ForceFixRotations - Window - type: Sprite @@ -42,6 +41,10 @@ - type: ExaminableDamage messages: WindowMessages - type: Repairable + - type: RCDDeconstructable + cost: 6 + delay: 4 + fx: EffectRCDDeconstruct4 - type: Destructible thresholds: - trigger: @@ -89,6 +92,14 @@ - type: StaticPrice price: 100 - type: BlockWeather + +- type: entity + id: WindowRCDResistant + parent: Window + abstract: true + components: + - type: RCDDeconstructable + deconstructable: false - type: entity id: WindowDirectional @@ -139,6 +150,10 @@ damageModifierSet: Glass - type: ExaminableDamage messages: WindowMessages + - type: RCDDeconstructable + cost: 4 + delay: 2 + fx: EffectRCDDeconstruct2 - type: Destructible thresholds: - trigger: @@ -181,6 +196,14 @@ - type: StaticPrice price: 10 +- type: entity + id: WindowDirectionalRCDResistant + parent: WindowDirectional + abstract: true + components: + - type: RCDDeconstructable + deconstructable: false + - type: entity id: WindowFrostedDirectional parent: WindowDirectional diff --git a/Resources/Prototypes/Entities/Structures/base_structure.yml b/Resources/Prototypes/Entities/Structures/base_structure.yml index b5356674aa..71971a6624 100644 --- a/Resources/Prototypes/Entities/Structures/base_structure.yml +++ b/Resources/Prototypes/Entities/Structures/base_structure.yml @@ -56,5 +56,13 @@ - LowImpassable - type: Anchorable +# For use with yaml composition, so that all wheeled structures can easily be changed. +- type: entity + id: StructureWheeled + abstract: true + components: + - type: TileFrictionModifier + modifier: 0.4 + - type: Tag id: Structure diff --git a/Resources/Prototypes/Entities/Structures/catwalk.yml b/Resources/Prototypes/Entities/Structures/catwalk.yml index c727c24952..6dee91365e 100644 --- a/Resources/Prototypes/Entities/Structures/catwalk.yml +++ b/Resources/Prototypes/Entities/Structures/catwalk.yml @@ -51,3 +51,7 @@ max: 1 - !type:DoActsBehavior acts: [ "Destruction" ] + - type: RCDDeconstructable + cost: 2 + delay: 2 + fx: EffectRCDDeconstruct2 \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Structures/hydro_tray.yml b/Resources/Prototypes/Entities/Structures/hydro_tray.yml index 43b8bd197a..8ea7172d8b 100644 --- a/Resources/Prototypes/Entities/Structures/hydro_tray.yml +++ b/Resources/Prototypes/Entities/Structures/hydro_tray.yml @@ -81,9 +81,6 @@ - type: Machine board: HydroponicsTrayMachineCircuitboard - type: WiresPanel - - type: Wires - boardName: wires-board-name-hydroponicstray - layoutId: HydroponicsTray - type: AmbientSound volume: -9 range: 5 @@ -92,9 +89,6 @@ - type: GuideHelp guides: - Botany - - type: Tag - tags: - - NoPaint - type: entity parent: hydroponicsTray diff --git a/Resources/Prototypes/Entities/Structures/plastic_flaps.yml b/Resources/Prototypes/Entities/Structures/plastic_flaps.yml index bf49eb1be3..c4ee507395 100644 --- a/Resources/Prototypes/Entities/Structures/plastic_flaps.yml +++ b/Resources/Prototypes/Entities/Structures/plastic_flaps.yml @@ -66,12 +66,15 @@ - Opaque - MidImpassable - type: Occluder + - type: Construction + graph: PlasticFlapsGraph + node: opaqueFlaps - type: entity id: PlasticFlapsAirtightClear parent: PlasticFlapsClear name: airtight plastic flaps - suffix: Airtight Clear + suffix: Airtight, Clear description: Heavy duty, slightly stronger, airtight plastic flaps. Definitely can't get past those. No way. components: - type: Destructible @@ -83,12 +86,17 @@ - !type:DoActsBehavior acts: ["Destruction"] - type: Airtight + - type: Construction + graph: PlasticFlapsGraph + node: airtightFlaps + - type: StaticPrice + price: 100 - type: entity id: PlasticFlapsAirtightOpaque parent: PlasticFlapsOpaque name: airtight plastic flaps - suffix: Airtight Opaque + suffix: Airtight, Opaque description: Heavy duty, slightly stronger, airtight plastic flaps. Definitely can't get past those. No way. components: - type: Destructible @@ -100,3 +108,8 @@ - !type:DoActsBehavior acts: ["Destruction"] - type: Airtight + - type: Construction + graph: PlasticFlapsGraph + node: airtightopaqueFlaps + - type: StaticPrice + price: 100 diff --git a/Resources/Prototypes/Flavors/flavors.yml b/Resources/Prototypes/Flavors/flavors.yml index 446abf99ed..2b55efc21b 100644 --- a/Resources/Prototypes/Flavors/flavors.yml +++ b/Resources/Prototypes/Flavors/flavors.yml @@ -624,6 +624,11 @@ flavorType: Complex description: flavor-complex-dr-gibb +- type: flavor + id: gingersoda + flavorType: Complex + description: flavor-complex-ginger-soda + - type: flavor id: lemonlimesoda flavorType: Complex @@ -694,6 +699,11 @@ flavorType: Complex description: flavor-complex-rum +- type: flavor + id: coconutrum + flavorType: Complex + description: flavor-complex-coconut-rum + - type: flavor id: coffeeliquor flavorType: Complex @@ -739,6 +749,31 @@ flavorType: Complex description: flavor-complex-ice +- type: flavor + id: arnoldpalmer + flavorType: Complex + description: flavor-complex-arnold-palmer + +- type: flavor + id: bluehawaiian + flavorType: Complex + description: flavor-complex-blue-hawaiian + +- type: flavor + id: cosmopolitan + flavorType: Complex + description: flavor-complex-cosmopolitan + +- type: flavor + id: painkiller + flavorType: Complex + description: flavor-complex-painkiller + +- type: flavor + id: pinacolada + flavorType: Complex + description: flavor-complex-pina-colada + - type: flavor id: longisland flavorType: Complex diff --git a/Resources/Prototypes/Guidebook/chemicals.yml b/Resources/Prototypes/Guidebook/chemicals.yml new file mode 100644 index 0000000000..508b61b4ac --- /dev/null +++ b/Resources/Prototypes/Guidebook/chemicals.yml @@ -0,0 +1,63 @@ +- type: guideEntry + id: Chemicals + name: guide-entry-chemicals + text: "/ServerInfo/Guidebook/Chemicals.xml" + children: + - Elements + - Medicine + - Narcotics + - Pyrotechnic + - Toxins + - Foods + - Botanical + - Biological + - Others + filterEnabled: True + +- type: guideEntry + id: Elements + name: guide-entry-elements + text: "/ServerInfo/Guidebook/ChemicalTabs/Elements.xml" + filterEnabled: True + +- type: guideEntry + id: Narcotics + name: guide-entry-narcotics + text: "/ServerInfo/Guidebook/ChemicalTabs/Narcotics.xml" + filterEnabled: True + +- type: guideEntry + id: Pyrotechnic + name: guide-entry-pyrotechnics + text: "/ServerInfo/Guidebook/ChemicalTabs/Pyrotechnic.xml" + filterEnabled: True + +- type: guideEntry + id: Toxins + name: guide-entry-toxins + text: "/ServerInfo/Guidebook/ChemicalTabs/Toxins.xml" + filterEnabled: True + +- type: guideEntry + id: Foods + name: guide-entry-foods + text: "/ServerInfo/Guidebook/ChemicalTabs/Foods.xml" + filterEnabled: True + +- type: guideEntry + id: Botanical + name: guide-entry-botanical + text: "/ServerInfo/Guidebook/ChemicalTabs/Botany.xml" + filterEnabled: True + +- type: guideEntry + id: Biological + name: guide-entry-biological + text: "/ServerInfo/Guidebook/ChemicalTabs/Biological.xml" + filterEnabled: True + +- type: guideEntry + id: Others + name: guide-entry-others + text: "/ServerInfo/Guidebook/ChemicalTabs/Other.xml" + filterEnabled: True diff --git a/Resources/Prototypes/Guidebook/medical.yml b/Resources/Prototypes/Guidebook/medical.yml index 9ea2398a7c..95a4f1ca75 100644 --- a/Resources/Prototypes/Guidebook/medical.yml +++ b/Resources/Prototypes/Guidebook/medical.yml @@ -47,4 +47,4 @@ - type: guideEntry id: AdvancedBrute name: guide-entry-brute - text: "/ServerInfo/Guidebook/Medical/AdvancedBrute.xml" \ No newline at end of file + text: "/ServerInfo/Guidebook/Medical/AdvancedBrute.xml" diff --git a/Resources/Prototypes/Guidebook/shiftandcrew.yml b/Resources/Prototypes/Guidebook/shiftandcrew.yml index 9df1b26008..3c4618902e 100644 --- a/Resources/Prototypes/Guidebook/shiftandcrew.yml +++ b/Resources/Prototypes/Guidebook/shiftandcrew.yml @@ -19,12 +19,6 @@ name: guide-entry-survival text: "/ServerInfo/Guidebook/Survival.xml" -- type: guideEntry - id: Chemicals - name: guide-entry-chemicals - text: "/ServerInfo/Guidebook/Chemicals.xml" - filterEnabled: True - - type: guideEntry id: Janitorial name: guide-entry-janitorial @@ -47,4 +41,3 @@ id: Food Recipes name: guide-entry-foodrecipes text: "/ServerInfo/Guidebook/Service/FoodRecipes.xml" - diff --git a/Resources/Prototypes/Objectives/objectiveGroups.yml b/Resources/Prototypes/Objectives/objectiveGroups.yml index 83921ec983..ff126eb5d1 100644 --- a/Resources/Prototypes/Objectives/objectiveGroups.yml +++ b/Resources/Prototypes/Objectives/objectiveGroups.yml @@ -72,7 +72,6 @@ TechnologyDiskStealCollectionObjective: 1 #rnd FigurineStealCollectionObjective: 0.3 #service IDCardsStealCollectionObjective: 1 - CannabisStealCollectionObjective: 1 LAMPStealCollectionObjective: 2 #only for moth - type: weightedRandom diff --git a/Resources/Prototypes/RCD/rcd.yml b/Resources/Prototypes/RCD/rcd.yml new file mode 100644 index 0000000000..cb2c9ed234 --- /dev/null +++ b/Resources/Prototypes/RCD/rcd.yml @@ -0,0 +1,294 @@ +# Operations +- type: rcd + id: Invalid # Hidden prototype - do not add to RCDs + mode: Invalid + +- type: rcd + id: Deconstruct + name: rcd-component-deconstruct + category: Main + sprite: /Textures/Interface/Radial/RCD/deconstruct.png + mode: Deconstruct + prototype: EffectRCDDeconstructPreview + rotation: Camera + +- type: rcd + id: DeconstructLattice # Hidden prototype - do not add to RCDs + mode: Deconstruct + cost: 2 + delay: 1 + rotation: Camera + fx: EffectRCDDeconstruct2 + +- type: rcd + id: DeconstructTile # Hidden prototype - do not add to RCDs + mode: Deconstruct + cost: 4 + delay: 4 + rotation: Camera + fx: EffectRCDDeconstruct4 + +# Flooring +- type: rcd + id: Plating + name: rcd-component-plating + category: WallsAndFlooring + sprite: /Textures/Interface/Radial/RCD/plating.png + mode: ConstructTile + prototype: Plating + cost: 1 + delay: 1 + collisionMask: InteractImpassable + rules: + - CanBuildOnEmptyTile + fx: EffectRCDConstruct1 + +- type: rcd + id: FloorSteel + name: rcd-component-floor-steel + category: WallsAndFlooring + sprite: /Textures/Interface/Radial/RCD/metal_tile.png + mode: ConstructTile + prototype: FloorSteel + cost: 1 + delay: 1 + collisionMask: InteractImpassable + rules: + - CanBuildOnEmptyTile + fx: EffectRCDConstruct1 + +- type: rcd + id: Catwalk + name: rcd-component-catwalk + category: WallsAndFlooring + sprite: /Textures/Interface/Radial/RCD/catwalk.png + mode: ConstructObject + prototype: Catwalk + cost: 1 + delay: 1 + collisionMask: InteractImpassable + rules: + - MustBuildOnSubfloor + - IsCatwalk + rotation: Fixed + fx: EffectRCDConstruct1 + +# Walls +- type: rcd + id: WallSolid + name: rcd-component-wall-solid + category: WallsAndFlooring + sprite: /Textures/Interface/Radial/RCD/solid_wall.png + mode: ConstructObject + prototype: WallSolid + cost: 4 + delay: 2 + collisionMask: FullTileMask + rotation: Fixed + fx: EffectRCDConstruct2 + +- type: rcd + id: Grille + name: rcd-component-grille + category: WindowsAndGrilles + sprite: /Textures/Interface/Radial/RCD/grille.png + mode: ConstructObject + prototype: Grille + cost: 4 + delay: 2 + collisionMask: FullTileMask + rotation: Fixed + fx: EffectRCDConstruct2 + +# Windows +- type: rcd + id: Window + name: rcd-component-window + category: WindowsAndGrilles + sprite: /Textures/Interface/Radial/RCD/window.png + mode: ConstructObject + prototype: Window + cost: 3 + delay: 2 + collisionMask: FullTileMask + rules: + - IsWindow + rotation: Fixed + fx: EffectRCDConstruct2 + +- type: rcd + id: WindowDirectional + name: rcd-component-window-directional + category: WindowsAndGrilles + sprite: /Textures/Interface/Radial/RCD/directional.png + mode: ConstructObject + prototype: WindowDirectional + cost: 2 + delay: 1 + collisionMask: FullTileMask + collisionBounds: "-0.23,-0.49,0.23,-0.36" + rules: + - IsWindow + rotation: User + fx: EffectRCDConstruct1 + +- type: rcd + id: ReinforcedWindow + name: rcd-component-reinforced-window + category: WindowsAndGrilles + sprite: /Textures/Interface/Radial/RCD/window_reinforced.png + mode: ConstructObject + prototype: ReinforcedWindow + cost: 4 + delay: 3 + collisionMask: FullTileMask + rules: + - IsWindow + rotation: User + fx: EffectRCDConstruct3 + +- type: rcd + id: WindowReinforcedDirectional + name: rcd-component-window-reinforced-directional + category: WindowsAndGrilles + sprite: /Textures/Interface/Radial/RCD/directional_reinforced.png + mode: ConstructObject + prototype: WindowReinforcedDirectional + cost: 3 + delay: 2 + collisionMask: FullTileMask + collisionBounds: "-0.23,-0.49,0.23,-0.36" + rules: + - IsWindow + rotation: User + fx: EffectRCDConstruct2 + +# Airlocks +- type: rcd + id: Airlock + name: rcd-component-airlock + category: Airlocks + sprite: /Textures/Interface/Radial/RCD/airlock.png + mode: ConstructObject + prototype: Airlock + cost: 4 + delay: 4 + collisionMask: FullTileMask + rotation: Camera + fx: EffectRCDConstruct4 + +- type: rcd + id: AirlockGlass + name: rcd-component-airlock-glass + category: Airlocks + sprite: /Textures/Interface/Radial/RCD/glass_airlock.png + mode: ConstructObject + prototype: AirlockGlass + cost: 4 + delay: 4 + collisionMask: FullTileMask + rotation: Camera + fx: EffectRCDConstruct4 + +- type: rcd + id: Firelock + name: rcd-component-firelock + category: Airlocks + sprite: /Textures/Interface/Radial/RCD/firelock.png + mode: ConstructObject + prototype: Firelock + cost: 4 + delay: 3 + collisionMask: FullTileMask + rotation: Camera + fx: EffectRCDConstruct3 + +# Lighting +- type: rcd + id: TubeLight + name: rcd-component-tube-light + category: Lighting + sprite: /Textures/Interface/Radial/RCD/tube_light.png + mode: ConstructObject + prototype: Poweredlight + cost: 2 + delay: 1 + collisionMask: TabletopMachineMask + collisionBounds: "-0.23,-0.49,0.23,-0.36" + rotation: User + fx: EffectRCDConstruct1 + +- type: rcd + id: BulbLight + name: rcd-component-window-bulb-light + category: Lighting + sprite: /Textures/Interface/Radial/RCD/bulb_light.png + mode: ConstructObject + prototype: PoweredSmallLight + cost: 2 + delay: 1 + collisionMask: TabletopMachineMask + collisionBounds: "-0.23,-0.49,0.23,-0.36" + rotation: User + fx: EffectRCDConstruct1 + +# Electrical +- type: rcd + id: LVCable + name: rcd-component-window-lv-cable + category: Electrical + sprite: /Textures/Interface/Radial/RCD/lv_coil.png + mode: ConstructObject + prototype: CableApcExtension + cost: 1 + delay: 0 + collisionMask: InteractImpassable + rules: + - MustBuildOnSubfloor + rotation: Fixed + fx: EffectRCDConstruct0 + +- type: rcd + id: MVCable + name: rcd-component-window-mv-cable + category: Electrical + sprite: /Textures/Interface/Radial/RCD/mv_coil.png + mode: ConstructObject + prototype: CableMV + cost: 1 + delay: 0 + collisionMask: InteractImpassable + rules: + - MustBuildOnSubfloor + rotation: Fixed + fx: EffectRCDConstruct0 + +- type: rcd + id: HVCable + name: rcd-component-window-hv-cable + category: Electrical + sprite: /Textures/Interface/Radial/RCD/hv_coil.png + mode: ConstructObject + prototype: CableHV + cost: 1 + delay: 0 + collisionMask: InteractImpassable + rules: + - MustBuildOnSubfloor + rotation: Fixed + fx: EffectRCDConstruct0 + +- type: rcd + id: CableTerminal + name: rcd-component-window-cable-terminal + category: Electrical + sprite: /Textures/Interface/Radial/RCD/cable_terminal.png + mode: ConstructObject + prototype: CableTerminal + cost: 1 + delay: 0 + collisionMask: InteractImpassable + rules: + - MustBuildOnSubfloor + rotation: User + fx: EffectRCDConstruct0 \ No newline at end of file diff --git a/Resources/Prototypes/Reagents/Consumable/Drink/alcohol.yml b/Resources/Prototypes/Reagents/Consumable/Drink/alcohol.yml index f6bac28b32..44eba0f848 100644 --- a/Resources/Prototypes/Reagents/Consumable/Drink/alcohol.yml +++ b/Resources/Prototypes/Reagents/Consumable/Drink/alcohol.yml @@ -79,6 +79,26 @@ reagent: Ethanol amount: 0.1 +- type: reagent + id: BlueHawaiian + name: reagent-name-blue-hawaiian + parent: BaseAlcohol + desc: reagent-desc-blue-hawaiian + physicalDesc: reagent-physical-desc-tropical + flavor: bluehawaiian + color: "#47687b" + metamorphicSprite: + sprite: Objects/Consumable/Drinks/bluehawaiian.rsi + state: icon + metabolisms: + Drink: + effects: + - !type:SatiateThirst + factor: 2 + - !type:AdjustReagent + reagent: Ethanol + amount: 0.2 + - type: reagent id: Cognac name: reagent-name-cognac @@ -732,6 +752,46 @@ reagent: Ethanol amount: 0.2 +- type: reagent + id: CoconutRum + name: reagent-name-coconut-rum + parent: BaseAlcohol + desc: reagent-desc-coconut-rum + physicalDesc: reagent-physical-desc-strong-smelling + flavor: rum + color: "#cccbc8" + metamorphicSprite: + sprite: Objects/Consumable/Drinks/coconutrum.rsi + state: icon + metabolisms: + Drink: + effects: + - !type:SatiateThirst + factor: 2 + - !type:AdjustReagent + reagent: Ethanol + amount: 0.2 + +- type: reagent + id: Cosmopolitan + name: reagent-name-cosmopolitan + parent: BaseAlcohol + desc: reagent-desc-cosmopolitan + physicalDesc: reagent-physical-desc-citric + flavor: cosmopolitan + color: "#f73030" + metamorphicSprite: + sprite: Objects/Consumable/Drinks/cosmopolitan.rsi + state: icon + metabolisms: + Drink: + effects: + - !type:SatiateThirst + factor: 2 + - !type:AdjustReagent + reagent: Ethanol + amount: 0.15 + - type: reagent id: CubaLibre name: reagent-name-cuba-libre @@ -1254,6 +1314,26 @@ types: Poison: 1 +- type: reagent + id: Painkiller + name: reagent-name-painkiller + parent: BaseAlcohol + desc: reagent-desc-painkiller + physicalDesc: reagent-physical-desc-refreshing + flavor: painkiller + color: "#e6cb47" + metamorphicSprite: + sprite: Objects/Consumable/Drinks/painkiller.rsi + state: icon + metabolisms: + Drink: + effects: + - !type:SatiateThirst + factor: 2 + - !type:AdjustReagent + reagent: Ethanol + amount: 0.2 + - type: reagent id: Patron name: reagent-name-patron @@ -1292,6 +1372,18 @@ metamorphicFillBaseName: fill- metamorphicChangeColor: true +- type: reagent + id: PinaColada + name: reagent-name-pina-colada + parent: BaseAlcohol + desc: reagent-desc-pina-colada + physicalDesc: reagent-physical-desc-tropical + flavor: alcohol + color: "#e8dba4" + metamorphicSprite: + sprite: Objects/Consumable/Drinks/pinacolada.rsi + state: icon + - type: reagent id: Sbiten name: reagent-name-sbiten diff --git a/Resources/Prototypes/Reagents/Consumable/Drink/drinks.yml b/Resources/Prototypes/Reagents/Consumable/Drink/drinks.yml index 946a2a6e44..5c09b3c909 100644 --- a/Resources/Prototypes/Reagents/Consumable/Drink/drinks.yml +++ b/Resources/Prototypes/Reagents/Consumable/Drink/drinks.yml @@ -48,6 +48,34 @@ - !type:SatiateThirst factor: 1 +- type: reagent + id: CoconutWater + name: reagent-name-coconut-water + parent: BaseDrink + desc: reagent-desc-coconut-water + physicalDesc: reagent-physical-desc-milky + flavor: nutty + color: "#f4eadb" + metabolisms: + Drink: + effects: + - !type:SatiateThirst + factor: 4 # Coconut water is 94% water + +- type: reagent + id: CreamOfCoconut + name: reagent-name-cream-of-coconut + parent: BaseDrink + desc: reagent-desc-cream-of-coconut + physicalDesc: reagent-physical-desc-syrupy + flavor: creamy + color: "#FFEABF" + metabolisms: + Drink: + effects: + - !type:SatiateThirst + factor: 2 + - type: reagent id: CafeLatte name: reagent-name-cafe-latte @@ -406,6 +434,26 @@ - !type:SatiateHunger factor: 4 +- type: reagent + id: ArnoldPalmer + name: reagent-name-arnold-palmer + parent: BaseAlcohol + desc: reagent-desc-arnold-palmer + physicalDesc: reagent-physical-desc-sweet + flavor: arnoldpalmer + color: "#d8cc5d" + metamorphicSprite: + sprite: Objects/Consumable/Drinks/arnoldpalmer.rsi + state: icon + metabolisms: + Drink: + effects: + - !type:SatiateThirst + factor: 4 + - !type:AdjustReagent + reagent: Theobromine + amount: 0.05 + - type: reagent id: Pilk name: reagent-name-pilk diff --git a/Resources/Prototypes/Reagents/Consumable/Drink/soda.yml b/Resources/Prototypes/Reagents/Consumable/Drink/soda.yml index 63ae5b25d5..ba5adc4f2a 100644 --- a/Resources/Prototypes/Reagents/Consumable/Drink/soda.yml +++ b/Resources/Prototypes/Reagents/Consumable/Drink/soda.yml @@ -8,6 +8,23 @@ color: "#6c2828" recognizable: true +- type: reagent + id: RoyRogers + name: reagent-name-roy-rogers + parent: BaseSoda + desc: reagent-desc-roy-rogers + physicalDesc: reagent-physical-desc-sweet + flavor: cola + color: "#262019" + metamorphicSprite: + sprite: Objects/Consumable/Drinks/royrogers.rsi + state: icon + metabolisms: + Drink: + effects: + - !type:SatiateThirst + factor: 4 + - type: reagent id: ChangelingSting name: reagent-name-changeling-sting @@ -116,6 +133,35 @@ metamorphicFillBaseName: fill- metamorphicChangeColor: false +- type: reagent + id: SolDry + name: reagent-name-sol-dry + parent: BaseSoda + desc: reagent-desc-sol-dry + physicalDesc: reagent-physical-desc-fizzy + flavor: gingersoda + color: "#ccb87e" + metamorphicSprite: + sprite: Objects/Consumable/Drinks/sol_dry_glass.rsi + state: icon + +- type: reagent + id: ShirleyTemple + name: reagent-name-shirley-temple + parent: BaseSoda + desc: reagent-desc-shirley-temple + physicalDesc: reagent-physical-desc-fizzy + flavor: sweet + color: "#af2221" + metamorphicSprite: + sprite: Objects/Consumable/Drinks/shirleytemple.rsi + state: icon + metabolisms: + Drink: + effects: + - !type:SatiateThirst + factor: 4 + - type: reagent id: SpaceMountainWind name: reagent-name-space-mountain-wind diff --git a/Resources/Prototypes/Recipes/Construction/Graphs/clothing/glasses_sechud.yml b/Resources/Prototypes/Recipes/Construction/Graphs/clothing/glasses_sechud.yml new file mode 100644 index 0000000000..de264dbd58 --- /dev/null +++ b/Resources/Prototypes/Recipes/Construction/Graphs/clothing/glasses_sechud.yml @@ -0,0 +1,25 @@ +- type: constructionGraph + id: GlassesSecHUD + start: start + graph: + - node: start + edges: + - to: glassesSec + steps: + - tag: Sunglasses + name: sun glasses + icon: + sprite: Clothing/Eyes/Glasses/sunglasses.rsi + state: icon + doAfter: 5 + - tag: HudSecurity + name: security hud + icon: + sprite: Clothing/Eyes/Hud/sec.rsi + state: icon + doAfter: 5 + - material: Cable + amount: 5 + doAfter: 5 + - node: glassesSec + entity: ClothingEyesGlassesSecurity diff --git a/Resources/Prototypes/Recipes/Construction/Graphs/furniture/toilet.yml b/Resources/Prototypes/Recipes/Construction/Graphs/furniture/toilet.yml index 7daf9ca22d..d9a4cd02fb 100644 --- a/Resources/Prototypes/Recipes/Construction/Graphs/furniture/toilet.yml +++ b/Resources/Prototypes/Recipes/Construction/Graphs/furniture/toilet.yml @@ -24,7 +24,6 @@ conditions: - !type:EntityAnchored anchored: false - - !type:ToiletLidClosed {} steps: - tool: Welding doAfter: 2 diff --git a/Resources/Prototypes/Recipes/Construction/Graphs/structures/airlock.yml b/Resources/Prototypes/Recipes/Construction/Graphs/structures/airlock.yml index 3cd22bbfc7..5529514fdc 100644 --- a/Resources/Prototypes/Recipes/Construction/Graphs/structures/airlock.yml +++ b/Resources/Prototypes/Recipes/Construction/Graphs/structures/airlock.yml @@ -46,7 +46,7 @@ conditions: - !type:EntityAnchored {} steps: - - tag: DoorElectronics + - component: DoorElectronics store: board name: "door electronics circuit board" icon: diff --git a/Resources/Prototypes/Recipes/Construction/Graphs/structures/plastic_flaps.yml b/Resources/Prototypes/Recipes/Construction/Graphs/structures/plastic_flaps.yml index 9f8497ac98..776c1491a6 100644 --- a/Resources/Prototypes/Recipes/Construction/Graphs/structures/plastic_flaps.yml +++ b/Resources/Prototypes/Recipes/Construction/Graphs/structures/plastic_flaps.yml @@ -13,6 +13,7 @@ - material: Plastic amount: 5 doAfter: 10 + - node: plasticFlaps entity: PlasticFlapsClear edges: @@ -24,3 +25,73 @@ steps: - tool: Anchoring doAfter: 10 + + - to: opaqueFlaps + completed: + - !type:SnapToGrid { } + steps: + - tool: Welding + doAfter: 5 + + - to: airtightFlaps + completed: + - !type:SnapToGrid { } + steps: + - material: Plastic + amount: 5 + doAfter: 5 + - tool: Screwing + doAfter: 5 + + - node: opaqueFlaps + entity: PlasticFlapsOpaque + edges: + - to: start + completed: + - !type:SpawnPrototype + prototype: SheetPlastic + amount: 5 + steps: + - tool: Anchoring + doAfter: 10 + + - to: airtightopaqueFlaps + completed: + - !type:SnapToGrid { } + steps: + - material: Plastic + amount: 5 + doAfter: 5 + - tool: Screwing + doAfter: 5 + + - node: airtightFlaps + entity: PlasticFlapsAirtightClear + edges: + - to: plasticFlaps + completed: + - !type:SpawnPrototype + prototype: SheetPlastic + amount: 5 + steps: + - tool: Screwing + doAfter: 10 + + - to: airtightopaqueFlaps #test + completed: + - !type:SnapToGrid { } + steps: + - tool: Welding + doAfter: 5 + + - node: airtightopaqueFlaps + entity: PlasticFlapsAirtightOpaque + edges: + - to: opaqueFlaps + completed: + - !type:SpawnPrototype + prototype: SheetPlastic + amount: 5 + steps: + - tool: Screwing + doAfter: 10 diff --git a/Resources/Prototypes/Recipes/Construction/Graphs/structures/shutter.yml b/Resources/Prototypes/Recipes/Construction/Graphs/structures/shutter.yml index 70d1c12d84..db53de288a 100644 --- a/Resources/Prototypes/Recipes/Construction/Graphs/structures/shutter.yml +++ b/Resources/Prototypes/Recipes/Construction/Graphs/structures/shutter.yml @@ -44,7 +44,7 @@ - !type:EntityAnchored anchored: true steps: - - tag: DoorElectronics + - component: DoorElectronics name: Door Electronics icon: sprite: "Objects/Misc/module.rsi" diff --git a/Resources/Prototypes/Recipes/Construction/Graphs/structures/shuttle.yml b/Resources/Prototypes/Recipes/Construction/Graphs/structures/shuttle.yml index 457fbfede5..f29629043d 100644 --- a/Resources/Prototypes/Recipes/Construction/Graphs/structures/shuttle.yml +++ b/Resources/Prototypes/Recipes/Construction/Graphs/structures/shuttle.yml @@ -23,7 +23,7 @@ conditions: - !type:EntityAnchored {} steps: - - tag: DoorElectronics + - component: DoorElectronics store: board name: "door electronics circuit board" icon: diff --git a/Resources/Prototypes/Recipes/Construction/Graphs/structures/windoor.yml b/Resources/Prototypes/Recipes/Construction/Graphs/structures/windoor.yml index 64809ee1db..de89663467 100644 --- a/Resources/Prototypes/Recipes/Construction/Graphs/structures/windoor.yml +++ b/Resources/Prototypes/Recipes/Construction/Graphs/structures/windoor.yml @@ -107,7 +107,7 @@ conditions: - !type:EntityAnchored {} steps: - - tag: DoorElectronics + - component: DoorElectronics store: board name: "door electronics circuit board" icon: @@ -378,7 +378,7 @@ conditions: - !type:EntityAnchored { } steps: - - tag: DoorElectronics + - component: DoorElectronics store: board name: "door electronics circuit board" icon: diff --git a/Resources/Prototypes/Recipes/Construction/clothing.yml b/Resources/Prototypes/Recipes/Construction/clothing.yml index 89f22cdf30..8907a47c6b 100644 --- a/Resources/Prototypes/Recipes/Construction/clothing.yml +++ b/Resources/Prototypes/Recipes/Construction/clothing.yml @@ -96,3 +96,14 @@ description: Comfy, yet haunted by the ghosts of ducks you fed bread to as a child. icon: { sprite: Clothing/Shoes/Misc/duck-slippers.rsi, state: icon } objectType: Item + +- type: construction + name: security glasses + id: ClothingEyesGlassesSecurity + graph: GlassesSecHUD + startNode: start + targetNode: glassesSec + category: construction-category-clothing + description: A pair of sunglasses, modified to have a built-in security HUD. + icon: { sprite: Clothing/Eyes/Glasses/secglasses.rsi, state: icon } + objectType: Item \ No newline at end of file diff --git a/Resources/Prototypes/Recipes/Construction/furniture.yml b/Resources/Prototypes/Recipes/Construction/furniture.yml index 2597877187..a5cf53107d 100644 --- a/Resources/Prototypes/Recipes/Construction/furniture.yml +++ b/Resources/Prototypes/Recipes/Construction/furniture.yml @@ -606,7 +606,7 @@ description: A human excrement flushing apparatus. icon: sprite: Structures/Furniture/toilet.rsi - state: closed_toilet_seat_up + state: disposal objectType: Structure placementMode: SnapgridCenter canBuildInImpassable: false diff --git a/Resources/Prototypes/Recipes/Construction/structures.yml b/Resources/Prototypes/Recipes/Construction/structures.yml index 963a289bab..bea97beaaa 100644 --- a/Resources/Prototypes/Recipes/Construction/structures.yml +++ b/Resources/Prototypes/Recipes/Construction/structures.yml @@ -86,7 +86,7 @@ canRotate: false canBuildInImpassable: false conditions: - - !type:TileNotBlocked + - !type:TileNotBlocked - type: construction name: clock wall @@ -1590,6 +1590,57 @@ conditions: - !type:TileNotBlocked +- type: construction + name: airtight plastic flaps + id: PlasticFlapsAirtight + graph: PlasticFlapsGraph + startNode: start + targetNode: airtightFlaps + category: construction-category-structures + placementMode: SnapgridCenter + description: An airtight plastic flap to let items through and keep people out. + objectType: Structure + canBuildInImpassable: false + icon: + sprite: Structures/plastic_flaps.rsi + state: plasticflaps + conditions: + - !type:TileNotBlocked + +- type: construction + name: opaque plastic flaps + id: PlasticFlapsOpaque + graph: PlasticFlapsGraph + startNode: start + targetNode: opaqueFlaps + category: construction-category-structures + placementMode: SnapgridCenter + description: An opaque plastic flap to let items through and keep people out. + objectType: Structure + canBuildInImpassable: false + icon: + sprite: Structures/plastic_flaps.rsi + state: plasticflaps + conditions: + - !type:TileNotBlocked + +- type: construction + name: airtight opaque plastic flaps + id: PlasticFlapsAirtightOpaque + graph: PlasticFlapsGraph + startNode: start + targetNode: airtightopaqueFlaps + category: construction-category-structures + placementMode: SnapgridCenter + description: An opaque, airtight plastic flap to let items through and keep people out. + objectType: Structure + canBuildInImpassable: false + icon: + sprite: Structures/plastic_flaps.rsi + state: plasticflaps + conditions: + - !type:TileNotBlocked + - type: construction name: bananium clown statue id: BananiumClownStatue diff --git a/Resources/Prototypes/Recipes/Crafting/Graphs/improvised/flowercrown.yml b/Resources/Prototypes/Recipes/Crafting/Graphs/improvised/flowercrown.yml deleted file mode 100644 index cba454b663..0000000000 --- a/Resources/Prototypes/Recipes/Crafting/Graphs/improvised/flowercrown.yml +++ /dev/null @@ -1,26 +0,0 @@ -- type: constructionGraph - id: flowercrown - start: start - graph: - - node: start - edges: - - to: flowercrown - steps: - - tag: Flower - name: flower - icon: - sprite: Objects/Specific/Hydroponics/poppy.rsi - state: produce - - tag: Flower - name: flower - icon: - sprite: Objects/Specific/Hydroponics/poppy.rsi - state: produce - - tag: Ambrosia - name: ambrosia - icon: - sprite: Objects/Specific/Hydroponics/ambrosia_vulgaris.rsi - state: produce - doAfter: 10 - - node: flowercrown - entity: ClothingHeadHatFlowerCrown diff --git a/Resources/Prototypes/Recipes/Crafting/Graphs/improvised/flowerwreath.yml b/Resources/Prototypes/Recipes/Crafting/Graphs/improvised/flowerwreath.yml index a0a87a14d8..b8e580230d 100644 --- a/Resources/Prototypes/Recipes/Crafting/Graphs/improvised/flowerwreath.yml +++ b/Resources/Prototypes/Recipes/Crafting/Graphs/improvised/flowerwreath.yml @@ -23,4 +23,4 @@ state: produce doAfter: 10 - node: flowerwreath - entity: ClothingNeckFlowerWreath + entity: ClothingHeadHatFlowerWreath diff --git a/Resources/Prototypes/Recipes/Crafting/Graphs/improvised/hairflower.yml b/Resources/Prototypes/Recipes/Crafting/Graphs/improvised/hairflower.yml deleted file mode 100644 index 76bc124290..0000000000 --- a/Resources/Prototypes/Recipes/Crafting/Graphs/improvised/hairflower.yml +++ /dev/null @@ -1,16 +0,0 @@ -- type: constructionGraph - id: hairflower - start: start - graph: - - node: start - edges: - - to: hairflower - steps: - - tag: Flower # TODO change to "RedFlower" or "Poppy" tag, so you cant make red flower from bluesyellow etc., when it will be - name: flower - icon: - sprite: Objects/Specific/Hydroponics/poppy.rsi - state: produce - doAfter: 3.5 - - node: hairflower - entity: ClothingHeadHatHairflower diff --git a/Resources/Prototypes/Recipes/Crafting/improvised.yml b/Resources/Prototypes/Recipes/Crafting/improvised.yml index 7414837592..38d254c141 100644 --- a/Resources/Prototypes/Recipes/Crafting/improvised.yml +++ b/Resources/Prototypes/Recipes/Crafting/improvised.yml @@ -98,32 +98,6 @@ sprite: Clothing/Eyes/Misc/blindfold.rsi state: icon -- type: construction - name: hairflower - id: hairflower - graph: hairflower - startNode: start - targetNode: hairflower - category: construction-category-clothing - description: "A red flower for beautiful ladies." - icon: - sprite: Clothing/Head/Misc/hairflower.rsi - state: icon - objectType: Item - -- type: construction - name: flower crown - id: flowercrown - graph: flowercrown - startNode: start - targetNode: flowercrown - category: construction-category-clothing - description: "A coronet of fresh and fragrant flowers." - icon: - sprite: Clothing/Head/Misc/flower-crown.rsi - state: icon - objectType: Item - - type: construction name: flower wreath id: flowerwreath @@ -131,9 +105,9 @@ startNode: start targetNode: flowerwreath category: construction-category-clothing - description: "A wreath of colourful flowers." + description: A wreath of colourful flowers. Can be worn both on head and neck. icon: - sprite: Clothing/Neck/Misc/flower-wreath.rsi + sprite: Clothing/Head/Misc/flower-wreath.rsi state: icon objectType: Item @@ -239,4 +213,4 @@ description: An improvised explosive made from pipes and wire. icon: sprite: Objects/Weapons/Bombs/pipebomb.rsi - state: icon \ No newline at end of file + state: icon diff --git a/Resources/Prototypes/Recipes/Lathes/security.yml b/Resources/Prototypes/Recipes/Lathes/security.yml index 432594d4b5..b3100ed70b 100644 --- a/Resources/Prototypes/Recipes/Lathes/security.yml +++ b/Resources/Prototypes/Recipes/Lathes/security.yml @@ -87,14 +87,6 @@ materials: Plastic: 100 -- type: latheRecipe - id: ClothingEyesGlassesSecurity - result: ClothingEyesGlassesSecurity - completetime: 2 - materials: - Steel: 300 - Glass: 200 - - type: latheRecipe id: ClothingEyesHudSecurity result: ClothingEyesHudSecurity diff --git a/Resources/Prototypes/Recipes/Reactions/drinks.yml b/Resources/Prototypes/Recipes/Reactions/drinks.yml index 7608369b2c..c810ebb0ce 100644 --- a/Resources/Prototypes/Recipes/Reactions/drinks.yml +++ b/Resources/Prototypes/Recipes/Reactions/drinks.yml @@ -54,6 +54,16 @@ products: Antifreeze: 4 +- type: reaction + id: ArnoldPalmer + reactants: + IcedTea: + amount: 1 + Lemonade: + amount: 1 + products: + ArnoldPalmer: 2 + - type: reaction id: AtomicBomb reactants: @@ -76,6 +86,20 @@ products: B52: 3 +- type: reaction + id: BlueHawaiian + reactants: + CoconutRum: + amount: 2 + JuicePineapple: + amount: 1 + JuiceLemon: + amount: 1 + BlueCuracao: + amount: 1 + products: + BlueHawaiian: 5 + - type: reaction id: CogChamp reactants: @@ -90,6 +114,24 @@ sound: path: /Audio/Magic/Cults/ClockCult/steam_whoosh.ogg +- type: reaction + id: BahamaMama + reactants: + Ice: + amount: 1 + JuiceOrange: + amount: 1 + JuicePineapple: + amount: 1 + Rum: + amount: 1 + CoconutRum: + amount: 1 + Grenadine: + amount: 1 + products: + BahamaMama: 6 + - type: reaction id: Barefoot reactants: @@ -182,6 +224,40 @@ products: CafeLatte: 2 +- type: reaction + id: CoconutRum + reactants: + Rum: + amount: 2 + CoconutWater: + amount: 1 + products: + CoconutRum: 3 + +- type: reaction + id: Cosmopolitan + reactants: + Vodka: + amount: 1 + JuiceBerry: + amount: 1 + JuiceLime: + amount: 1 + products: + Cosmopolitan: 3 + +- type: reaction + id: CreamOfCoconut + reactants: + CoconutWater: + amount: 1 + Sugar: + amount: 1 + Milk: + amount: 1 + products: + CreamOfCoconut: 3 + - type: reaction id: CubaLibre reactants: @@ -638,6 +714,34 @@ products: Patron: 10 +- type: reaction + id: Painkiller + reactants: + JuicePineapple: + amount: 3 + CoconutRum: + amount: 1 + JuiceOrange: + amount: 1 + CreamOfCoconut: + amount: 1 + products: + Painkiller: 6 + +- type: reaction + id: PinaColada + reactants: + JuicePineapple: + amount: 3 + JuiceLime: + amount: 1 + Rum: + amount: 1 + CreamOfCoconut: + amount: 1 + products: + PinaColada: 6 + - type: reaction id: Posca reactants: @@ -680,6 +784,16 @@ products: RootBeerFloat: 3 +- type: reaction + id: RoyRogers + reactants: + Cola: + amount: 2 + Grenadine: + amount: 1 + products: + RoyRogers: 3 + - type: reaction id: Sbiten reactants: @@ -700,6 +814,16 @@ products: ScrewdriverCocktail: 3 +- type: reaction + id: ShirleyTemple + reactants: + SolDry: + amount: 2 + Grenadine: + amount: 1 + products: + ShirleyTemple: 3 + - type: reaction id: Silencer reactants: diff --git a/Resources/Prototypes/Research/arsenal.yml b/Resources/Prototypes/Research/arsenal.yml index b17fb0ce00..3b7284c749 100644 --- a/Resources/Prototypes/Research/arsenal.yml +++ b/Resources/Prototypes/Research/arsenal.yml @@ -76,7 +76,6 @@ tier: 1 cost: 8000 recipeUnlocks: - - ClothingEyesGlassesSecurity - Truncheon - TelescopicShield - HoloprojectorSecurity diff --git a/Resources/Prototypes/Roles/Jobs/Fun/emergencyresponseteam.yml b/Resources/Prototypes/Roles/Jobs/Fun/emergencyresponseteam.yml index d54baba3db..22d0a4d77f 100644 --- a/Resources/Prototypes/Roles/Jobs/Fun/emergencyresponseteam.yml +++ b/Resources/Prototypes/Roles/Jobs/Fun/emergencyresponseteam.yml @@ -66,6 +66,61 @@ inhand: - AirTankFilled +# Chaplain +- type: job + id: ERTChaplain + name: job-name-ertchaplain + description: job-description-ertchaplain + playTimeTracker: JobERTChaplain + setPreference: false + startingGear: ERTEngineerGearEVA + icon: "JobIconNanotrasen" + supervisors: job-supervisors-centcom + canBeAntag: false + accessGroups: + - AllAccess + access: + - CentralCommand + special: + - !type:AddComponentSpecial + components: + - type: BibleUser #Lets them heal with bibles + +- type: startingGear + id: ERTChaplainGear + equipment: + jumpsuit: ClothingUniformJumpsuitERTChaplain + back: ClothingBackpackERTChaplainFilled + shoes: ClothingShoesLeather + head: ClothingHeadHatFez + eyes: ClothingEyesGlasses + neck: ClothingNeckStoleChaplain + gloves: ClothingHandsGlovesCombat + outerClothing: ClothingOuterArmorBasicSlim + id: ERTEngineerPDA + ears: ClothingHeadsetAltCentCom + belt: ClothingBeltStorageWaistbag + pocket1: Flare + pocket2: DrinkWaterBottleFull + +- type: startingGear + id: ERTChaplainGearEVA + equipment: + jumpsuit: ClothingUniformJumpsuitERTChaplain + back: ClothingBackpackERTChaplainFilled + shoes: ClothingShoesBootsMagAdv + mask: ClothingMaskGasERT + eyes: ClothingEyesGlasses + neck: ClothingNeckStoleChaplain + gloves: ClothingHandsGlovesCombat + outerClothing: ClothingOuterHardsuitERTChaplain + suitstorage: AirTankFilled + id: ERTChaplainPDA + ears: ClothingHeadsetAltCentCom + belt: ClothingBeltStorageWaistbag + pocket1: Flare + pocket2: DrinkWaterBottleFull + # Engineer - type: job id: ERTEngineer diff --git a/Resources/Prototypes/Roles/Jobs/Security/detective.yml b/Resources/Prototypes/Roles/Jobs/Security/detective.yml index 00c44c34ab..b1aa326971 100644 --- a/Resources/Prototypes/Roles/Jobs/Security/detective.yml +++ b/Resources/Prototypes/Roles/Jobs/Security/detective.yml @@ -28,7 +28,7 @@ jumpsuit: ClothingUniformJumpsuitDetective back: ClothingBackpackSecurityFilledDetective shoes: ClothingShoesBootsCombatFilled - eyes: ClothingEyesGlassesSunglasses + eyes: ClothingEyesGlassesSecurity head: ClothingHeadHatFedoraBrown outerClothing: ClothingOuterVestDetective id: DetectivePDA diff --git a/Resources/Prototypes/Roles/Jobs/Security/head_of_security.yml b/Resources/Prototypes/Roles/Jobs/Security/head_of_security.yml index 1c361eff50..4d5c86fc63 100644 --- a/Resources/Prototypes/Roles/Jobs/Security/head_of_security.yml +++ b/Resources/Prototypes/Roles/Jobs/Security/head_of_security.yml @@ -47,7 +47,7 @@ back: ClothingBackpackHOSFilled shoes: ClothingShoesBootsCombatFilled outerClothing: ClothingOuterCoatHoSTrench - eyes: ClothingEyesGlassesSunglasses + eyes: ClothingEyesGlassesSecurity head: ClothingHeadHatBeretHoS id: HoSPDA gloves: ClothingHandsGlovesCombat diff --git a/Resources/Prototypes/Roles/Jobs/Security/security_officer.yml b/Resources/Prototypes/Roles/Jobs/Security/security_officer.yml index b631e2de34..5c67859fa4 100644 --- a/Resources/Prototypes/Roles/Jobs/Security/security_officer.yml +++ b/Resources/Prototypes/Roles/Jobs/Security/security_officer.yml @@ -29,7 +29,7 @@ jumpsuit: ClothingUniformJumpsuitSec back: ClothingBackpackSecurityFilled shoes: ClothingShoesBootsCombatFilled - eyes: ClothingEyesGlassesSunglasses + eyes: ClothingEyesGlassesSecurity head: ClothingHeadHelmetBasic outerClothing: ClothingOuterArmorBasic id: SecurityPDA diff --git a/Resources/Prototypes/Roles/Jobs/Security/warden.yml b/Resources/Prototypes/Roles/Jobs/Security/warden.yml index 8d83745e58..72936cfb56 100644 --- a/Resources/Prototypes/Roles/Jobs/Security/warden.yml +++ b/Resources/Prototypes/Roles/Jobs/Security/warden.yml @@ -32,7 +32,7 @@ jumpsuit: ClothingUniformJumpsuitWarden back: ClothingBackpackSecurityFilled shoes: ClothingShoesBootsCombatFilled - eyes: ClothingEyesGlassesSunglasses + eyes: ClothingEyesGlassesSecurity outerClothing: ClothingOuterCoatWarden id: WardenPDA ears: ClothingHeadsetSecurity diff --git a/Resources/Prototypes/Roles/play_time_trackers.yml b/Resources/Prototypes/Roles/play_time_trackers.yml index 242dc81fa8..402d49e90d 100644 --- a/Resources/Prototypes/Roles/play_time_trackers.yml +++ b/Resources/Prototypes/Roles/play_time_trackers.yml @@ -46,6 +46,9 @@ - type: playTimeTracker id: JobDetective +- type: playTimeTracker + id: JobERTChaplain + - type: playTimeTracker id: JobERTEngineer diff --git a/Resources/Prototypes/Traits/neutral.yml b/Resources/Prototypes/Traits/neutral.yml index 9e7f765507..ba9bd8d886 100644 --- a/Resources/Prototypes/Traits/neutral.yml +++ b/Resources/Prototypes/Traits/neutral.yml @@ -16,3 +16,10 @@ - type: MothAccent - type: ReplacementAccent accent: dwarf + +- type: trait + id: Southern + name: trait-southern-name + description: trait-southern-desc + components: + - type: SouthernAccent diff --git a/Resources/Prototypes/Voice/speech_emote_sounds.yml b/Resources/Prototypes/Voice/speech_emote_sounds.yml index 01fabbadf3..5556afa07d 100644 --- a/Resources/Prototypes/Voice/speech_emote_sounds.yml +++ b/Resources/Prototypes/Voice/speech_emote_sounds.yml @@ -298,6 +298,24 @@ Weh: collection: Weh +- type: emoteSounds + id: UnisexSilicon + params: + variation: 0.05 + sounds: + Beep: + path: /Audio/Machines/twobeep.ogg + Chime: + path: /Audio/Machines/chime.ogg + Buzz: + path: /Audio/Machines/buzz-sigh.ogg + Buzz-Two: + path: /Audio/Machines/buzz-two.ogg + Honk: + path: /Audio/Items/bikehorn.ogg + Ping: + path: /Audio/Effects/Cargo/ping.ogg + # body emotes - type: emoteSounds id: GeneralBodyEmotes diff --git a/Resources/Prototypes/Voice/speech_emotes.yml b/Resources/Prototypes/Voice/speech_emotes.yml index 8e33f483aa..3b7ffc0107 100644 --- a/Resources/Prototypes/Voice/speech_emotes.yml +++ b/Resources/Prototypes/Voice/speech_emotes.yml @@ -66,6 +66,19 @@ id: Honk category: Vocal chatMessages: [honks] + chatTriggers: + - honk + - honk. + - honk! + - honks + - honks. + - honks! + - honked + - honked. + - honked! + - honking + - honking. + - honking! - type: emote id: Sigh @@ -264,3 +277,94 @@ - chirping - chirping. - chirping! + +# Machine Emotes +- type: emote + id: Beep + category: Vocal + chatMessages: [beeps.] + chatTriggers: + - beep + - beep! + - beep. + - beeps + - beeps. + - beeps! + - beeped + - beeped. + - beeped! + - beeping + - beeping. + - beeping! + +- type: emote + id: Chime + category: Vocal + chatMessages: [chimes.] + chatTriggers: + - chime + - chime. + - chime! + - chimes + - chimes. + - chimes! + - chimed + - chimed. + - chimed! + - chiming + - chiming, + - chiming! + +- type: emote + id: Buzz-Two + category: Vocal + chatMessages: [buzzesTwice.] + chatTriggers: + - buzztwice + - buzztwice. + - buzztwice! + - buzzstwice + - buzzstwice. + - buzzstwice! + - buzzestwice + - buzzestwice. + - buzzestwice! + - buzzingtwice + - buzzingtwice. + - buzzingtwice! + - buzzedtwice + - buzzedtwice. + - buzzedtwice! + - buzz twice + - buzz twice. + - buzz twice! + - buzzs twice + - buzzs twice. + - buzzs twice! + - buzzes twice + - buzzes twice. + - buzzes twice! + - buzzing twice + - buzzing twice. + - buzzing twice! + - buzzed twice + - buzzed twice. + - buzzed twice! + +- type: emote + id: Ping + category: Vocal + chatMessages: [pings.] + chatTriggers: + - ping + - ping. + - ping! + - pings + - pings. + - pings! + - pinged + - pinged. + - pinged! + - pinging + - pinging. + - pinging! diff --git a/Resources/Prototypes/tags.yml b/Resources/Prototypes/tags.yml index ae1f8c0d19..961912d609 100644 --- a/Resources/Prototypes/tags.yml +++ b/Resources/Prototypes/tags.yml @@ -418,6 +418,9 @@ - type: Tag id: ConveyorAssembly +- type: Tag + id: CoordinatesDisk + - type: Tag #Ohioans die happy id: Corn @@ -911,9 +914,6 @@ - type: Tag id: NoBlockAnchoring -- type: Tag - id: NoPaint - - type: Tag id: NozzleBackTank @@ -1034,9 +1034,6 @@ - type: Tag id: RawMaterial -- type: Tag - id: RCDDeconstructWhitelist - # Give this to something that doesn't need any special recycler behavior and just needs deleting. - type: Tag id: Recyclable @@ -1180,6 +1177,9 @@ - type: Tag id: SuitEVA + +- type: Tag + id: Sunglasses - type: Tag id: SurgeryTool diff --git a/Resources/ServerInfo/Guidebook/ChemicalTabs/Biological.xml b/Resources/ServerInfo/Guidebook/ChemicalTabs/Biological.xml new file mode 100644 index 0000000000..6f1a4e630b --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ChemicalTabs/Biological.xml @@ -0,0 +1,9 @@ + + +# Biological + +These reagents include chemicals that you can get from certain materials and from living things. To get the other chemicals you have to use machines like the electrolyzer and the centrifuge. + + + + diff --git a/Resources/ServerInfo/Guidebook/ChemicalTabs/Botany.xml b/Resources/ServerInfo/Guidebook/ChemicalTabs/Botany.xml new file mode 100644 index 0000000000..832e32d644 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ChemicalTabs/Botany.xml @@ -0,0 +1,14 @@ + + +# Botanical Chemicals + +These chemicals are used by botanists. Some of the chemicals change the properties of the plants. + + + + + + + + + \ No newline at end of file diff --git a/Resources/ServerInfo/Guidebook/ChemicalTabs/Elements.xml b/Resources/ServerInfo/Guidebook/ChemicalTabs/Elements.xml new file mode 100644 index 0000000000..3a1c587304 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ChemicalTabs/Elements.xml @@ -0,0 +1,9 @@ + + +# Elements + +This list contains all the basic reagents used to make other chemicals. + + + + diff --git a/Resources/ServerInfo/Guidebook/ChemicalTabs/Foods.xml b/Resources/ServerInfo/Guidebook/ChemicalTabs/Foods.xml new file mode 100644 index 0000000000..aea68d74ce --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ChemicalTabs/Foods.xml @@ -0,0 +1,8 @@ + +# Foods + +These reagents are mostly used in the kitchen. Very helpful for Chefs and/or Service Workers. + + + + diff --git a/Resources/ServerInfo/Guidebook/ChemicalTabs/Narcotics.xml b/Resources/ServerInfo/Guidebook/ChemicalTabs/Narcotics.xml new file mode 100644 index 0000000000..0dbb5ad359 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ChemicalTabs/Narcotics.xml @@ -0,0 +1,5 @@ + +# Narcotics +The reagents listed in this category includes stimulants, hallucinogens and other drug-like effects. + + diff --git a/Resources/ServerInfo/Guidebook/ChemicalTabs/Other.xml b/Resources/ServerInfo/Guidebook/ChemicalTabs/Other.xml new file mode 100644 index 0000000000..31ad4ef3cb --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ChemicalTabs/Other.xml @@ -0,0 +1,5 @@ + +# Other +These are the other regeants listed in the Chemicals page. + + diff --git a/Resources/ServerInfo/Guidebook/ChemicalTabs/Pyrotechnic.xml b/Resources/ServerInfo/Guidebook/ChemicalTabs/Pyrotechnic.xml new file mode 100644 index 0000000000..9941e2ff36 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ChemicalTabs/Pyrotechnic.xml @@ -0,0 +1,5 @@ + +# Pyrotechnics +These chemicals are flammmable and causes hazardous effects when making them (Plasma gas and explosions). It is recommmended to make these chemicals in a safe environment. + + diff --git a/Resources/ServerInfo/Guidebook/ChemicalTabs/Toxins.xml b/Resources/ServerInfo/Guidebook/ChemicalTabs/Toxins.xml new file mode 100644 index 0000000000..19ab91cbf4 --- /dev/null +++ b/Resources/ServerInfo/Guidebook/ChemicalTabs/Toxins.xml @@ -0,0 +1,5 @@ + +# Toxins +The chemicals in this list contain toxins that induce certain effects and can cause death. Use responsibly. + + diff --git a/Resources/Textures/Clothing/Back/Backpacks/ertchaplain.rsi/equipped-BACKPACK.png b/Resources/Textures/Clothing/Back/Backpacks/ertchaplain.rsi/equipped-BACKPACK.png new file mode 100644 index 0000000000000000000000000000000000000000..4bcff09c29dcc40bca6b9f629012361f6a19a8f6 GIT binary patch literal 806 zcmV+>1KIqEP)+#Rp7_XG7l~GD{=7g$ooO1|%f!pV22z~+1`5*Vob`_LT zmI`RCS=;vaa6q2t@H`Iy(ChWew$*9{05HZNNfM0543JJOb&2KcQTpOI;gJwT|z)9 z^&-=2ty$NzKOT>nbF$kC9qvBQ^VYi%!wFLT=IHX)@wf%HEE${!fzp&Lm#rNMn;Pcn%PVY6=1%CbfVgZzOcvqW?qR2*3bo7-` z)x+s0_yvA^|5)l?2W#>w=Nv+atr~oF_M<4W%jJ?C%lPWpQc7Dbns}bqSS)D_0b>lp zFvNU5hwu9@I_vlQ0AMdKFQK)@VzKDd8F3t2DJ32sAJOmkv0N^0L zwAQsUPS;+q*LZ~PtidQ|jA=Z3!x%e=@l_`<#u|68EXy#P&Dgswz1K4DA(nlePOt4q k$JB`+2!bF8f*?+W-_fgZDzF}qVgLXD07*qoM6N<$f=n8HDF6Tf literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Back/Backpacks/ertchaplain.rsi/icon.png b/Resources/Textures/Clothing/Back/Backpacks/ertchaplain.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..02b99ef372dde424ee315c9f738b6eb24df38fb9 GIT binary patch literal 553 zcmV+^0@nSBP)e&0gJ`r+IH__m&CK#?E3S^Cjh{gZ_g6H zjTJ>P>XP%ZZD9Z)B24Kc03c0MS+8S61OV5ns#+8H(55&M)yeVo`!4{%(`JLuFE4o7 zY#MPQLKucZ`aO)=5|GnQrvQL33?){d*f}SAcDr3GIa*2Jy_eHjYoU~qVl|iVpj zzu$wIF&>X`KA({!35ueC_a4j)V+_i&6e9*ffc1L)?;g-vOG~}?P)dQBk>@##F|seu zbCIem?n+>cL6&8I_yGXQvTQt+Qn1#-T8q_ch1ZkwR|J;J<>+`kBFi!mQDgMpLLA44 z;~4Y#Tuj;PW%M4RC~9=27XsVuwlP|@(V{5AWHOP0%-pGP>${+yhTAsRL|*&CS}U=` r;V|lrz*}F%d!O#%mu$d*0bTGL{=3+lXtJwH00000NkvXXu0mjf8H4;% literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Back/Backpacks/ertchaplain.rsi/inhand-left.png b/Resources/Textures/Clothing/Back/Backpacks/ertchaplain.rsi/inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..f6bb073134283cbdc680fe8c6efca3e239231330 GIT binary patch literal 654 zcmV;90&)F`P)AmOoo=x-z2!bF8f*=TjAP9mW2x2m<*K0ra9(PlB==A-Ims0x4 z2cW7dFQxQSN*|04S1F~hs_H5ye*OIB0YLBvaLz}2DEG0P4`a?b1b@Ku>uYbkG3KiE zq?G>i^A17?eENF6jS?`%AkT9+=kWA$!jH#CJiVOYoI{@HFvg(ky20x?=TMd24~EN2OzwroO9ruLn#I49F$Vv zocEex`C8}z@=)+stp5ClOG1VIo4K@bE%5Cjp0 z6rzThc8nsB7+cg3Q;QHa04YQbm$V4i67BzbDW&I}LkNNM`H!gKcsyof1R!V;0AMzo z^>bn0a4uQb^~L?~V;UDk4g39mv@^ZfT7+mN(6()+wMGh2Lrg6~)C@=^Y6$fo2wH@2 z{~AqF)Fzlh)DT;Xa2M0CRHBBMT7;+>kV4d;l)`*IzZjsQT7;WCwqC7PzG<4i4+tTk owFZE`{)aZ`D*MF0Q* literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Back/Backpacks/ertchaplain.rsi/inhand-right.png b/Resources/Textures/Clothing/Back/Backpacks/ertchaplain.rsi/inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..d527a7daf963ef3d4a0fa825573ad24bd4cb8453 GIT binary patch literal 708 zcmV;#0z3VQP)4E4r~CqGR`dg{&vK7Q|G6lz|~tMo?HA z--P52m0hm<%k=^z?fa8Zz>ebh_4~XQ@&gbAK@bE%5ClOG1VIqQKgDo3H1&G$3z1S9 z`}zLx&U8ARqwjgUuQ3cmvtF+O01uz~czZu~R{-FgS8}!6?Y7x$HtzidZ{X|aI{ifPA0BE&Zt}jhf0D#sSN-0E97l3+1VIo4K@bE%5ClOG1VQ}wT*5O@_82!sZw$lm ziSc0jDy1~r$Li;1d)$iz;FM?JQvCS#!2odMmNB+hGyvE34A`S?A;gn0UwTe)TjZvy zcm}lA2!a69=@g8yQVwYf*MMt#29hN4vMj@Lxh!q+g)?AV|CVcb296mW&YA&L@eIUq zT>2O{&sqIzdIq*lPxgAT04Sxm1hOmx q0H^;t9-VuClZyK)H2o2%DL(=0000_ukU zm=#5}=6M1880TF5Bx|Q>h>k=Z8(J^cip~g`ZnRjksVeu#N4gRRh Ud0?3-o&W#<07*qoM6N<$f-yIu{{R30 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Head/Hardsuits/ERThelmets/ertchaplain.rsi/icon.png b/Resources/Textures/Clothing/Head/Hardsuits/ERThelmets/ertchaplain.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..32457b191649cfc7adf9e99ae9eae333bacfa4d3 GIT binary patch literal 386 zcmV-|0e$|7P)%UNfL zyIagR%Na8ER)W;K^5X#Y%01V?Zht^^O%+191J%lR`vW}Jx#&bM0M*Kh%IkNWPMwdU z6@Wa7vunMW%H!ut<9gfg-m5@l>HAsixlZGHFJm|y4yC=_!Z*#U`_eqe*I)q7xzWo{ znC5x;91wzlkj7kZQ&1RHjRQhDnJWX#lLYf5>72g_fOBqyVF<<;eAC1#%gWp;%ix

L6z8)S)TZ(g$7Q zW($f_X+UuZiFELwX^;p$F?mgU9pYWzvzC%)?v{Q(I9~1^?|uL8ySpUtKfnjoQik*M zIzRpNg!A({ua+_#nh_eb#}OcHTnhxQ&=${Bf`1IOvQH z=_$hHWPK*za{t?}13J8!970mJ7F92^_~0CsI#t^fdXTs3>G8NAGA@uhwy$L@>|V>+`0Kyd-e zM<)Ts7|#`pcr!OA$8*IZ7-J|Oodi@SFXB&UmSCEu9A}Kl`^vXKHk%EIFFp7E7vriC zaTsH=T_?V8(UxV&-`r#}sU>-WAP9mW2!bF8f*=TjAPBAe%Y4-34);?-uwMdnpAYDl zhMo%$P2{^abz@()YAM5`iM+Oz*iQ{T+v8|85uIE??Zcu+5L!)rd$H9-G?7Pb`{{2D zlPiGT&`^Nz2w*qhskY0XUrmLBk6*Wbs>pja6%I-b7e$cR4PQ2S(3cVsNX&Y8MB3J> zl6Sw`uB=_D!4KCuA>w8#v5uHwVBIwNBgT|iW$UKNpFMboisN8wyFc&jxd6h44;{Aw z05QYx9GFl|JQ4wHTNYfHvz^f)ynT^Wy9G9D6WD9b$bbN3^1>}vjc}wdCl7Sb4s6yY z)UAN_&cXn@_x#7h#k|L#Urwi`pt#}!xRcKni*j68kjX=q3~jP^suDUxqq}uc z$y6F>@ZgV5c|-AFLIibH)7Qb4B0FGPLMndd{y<2+k0;(ax|R*^00co01VIo4K@bE% zEDN1Rne$&id8bk4!Y=;y>zha-y!rf=iD!bp_<#XnL`;b9T_tXU6u0=?)*+nc(Y-N6 zHPE&9@x1U}nl~TAAu#9z8;|bJz})#!SdZP(;Sh>y_zTWy_0aQ!qNh!Wo7fF-T5tX9 zr%xVFd|sGou?dNf-GD;XM*8|1sx03dYq>6Nve{4u{twoZxM|CEp~^Dyih>KrLCbX) zHn8zdn>ijgYjNN3!{sFaAg?GBXRkhw?}Hr_sy2$dXE-RHqquv9Le<8n?h7$GpxJB! z04^NI?|@)^7VUOhVvKRaFp$Y){5oUIA7APY7z;qnG$-mc(*$E|Apw<2Me;;@N3bpg zmSyqHREn3gnI|%6$Nk{ zY-`6*W!Vp3++?#e!xby@E8rzgro{uJa7EZ4g>W4Z6d%kXcv*tqUtT|0Sp%{sCqSv> zi}%749#KLRLK*PmEqI literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Head/Hardsuits/ERThelmets/ertchaplain.rsi/off-inhand-right.png b/Resources/Textures/Clothing/Head/Hardsuits/ERThelmets/ertchaplain.rsi/off-inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..2b20dab1727e465f099f29f3af67d69bbbe1e3e6 GIT binary patch literal 707 zcmV;!0zCbRP)4E1FeGbi?xm=nyH{DBrA2{ya@80im-|xLgF1#N=5ClOG1VIo4 zK@h~E(5>e=|8>H<^*r~TeERi?|3LyEo}aS$pWjIyGe9I0T;lsj7n&eVCdZRy7_Ew@ zqoS42Ydpi9)N3io;^WCOFdPEr0EjI8KLb;rKkON0IE12=oP>B{Tdc)DE*|ihFp0+i zqy5rp-@bLzbuA2&V$TupF(6fJAa;BVO_n_!+m?l&D=UH5KJN<)PYbp!3z{rrT~W|9 z474pvh!>wKHc)?+n0bGa&}87v!2tkZT~Sc3GnNFu8F~)eQRD!CiPMk63+@CoEMgw50T6J~Ws#d`mn>s+y zC=?2kE!sZDhGz7~!0TCFD3m*6}|vrMqt>2z8GK@bE%5ClOG1VIo4 zK@h}Mv=BRHu{M0+!^Ko@njjjPfuN@ zz#Lo=10qX+(RUY4j1?eMvXRiEx8~o4T>_2?w(!xly)Q44cwaN%yaI&#iCt*2j9pdb z4;hmd)_{{AeW#KH05n;46;v$rufTq96^G^q0666`w)nPXIkf~LG1pYBWFw&)_g?$~ z;3`1a$>kgq9xN|Iq$S|%L3Lesee|fRik(~zz*#YcNZaXQKS{s8Jiaz+^3UJz;={)# p*L9t%s)}##ve)TP13?g?@DInYUutRUbie=r002ovPDHLkV1o6VJ68Yz literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Head/Hardsuits/ERThelmets/ertchaplain.rsi/on-equipped-HELMET.png b/Resources/Textures/Clothing/Head/Hardsuits/ERThelmets/ertchaplain.rsi/on-equipped-HELMET.png new file mode 100644 index 0000000000000000000000000000000000000000..c626307585b4001e40b7efc5330c250a9ed26489 GIT binary patch literal 796 zcmV+%1LOROP)c2h(z=x zVK`Wy!TYKJ5o|0N#OC=f7N+M>?f116z_=?eFzN%FM@NI}`L6eRv#yfFQU$H=?Z1x1 zQbm0QoSvQn02Zd_Wd*p`RdehlkXaZ#=pY#WR* z)M_9u{yG`B~lsZhg|59dzJCLbL0dF9e%3W1OO>fi-rl+2uWTfT!^z5kqFA~;%bk; zPGbhgPEr~KZo5TZM?4iYG4tjj1Q^CLUV4IHQLw8Ctw|iUVDg&0Rtl zcT4HeV30q$G&iIkoDf4@)%5LPOOX;%TSg9&d4F(NI`Nu&9-VZ8djN)E7=~dOhG7_n zVS+-ZULg8)N}YOvLOb}2FK^}&Vb#-x44(=1;2j2d5#bWwJ6^a6ir?as>pK`UcduPr zOO?=VY~xApy)vyHqY*Id1FQEhe}Sp>^KjR9OGhKDrAqdIlbMR=dZ*~CCiso-1`Jwn z?c+xeAGpqE=Bn5QiTB-r+*Sk8lM|#Ok!#mlrit@J!jplw!O9~3v}KwAfW5Or*ZC|4 zp8o9J*m7HqV6Ol|2r>+V(yB^CM|MlADj9}BLI|2xuj@JqAtJ~|3BL8wj!mZQmKS^JZ|?(Dedclegq~0P_ETn{pDH> zQp%YG6pKa05^XhSe<;v(-8F@ET@UP+oU%w0tYb~n!gKc+hG7_nVHk#C7=~dOhGBxl zv~6;)+vqFHWWqcdf>0We%v8ofir%r^I`sm1-ipT}@&UKOu#aS>f^K8`(vknsD9mL2s@cL8u;qSNp@iz$8Opi5>P~n=%KXngK*dl#gZ6GEIE)DJr0Z z%>ZD$_1-c~q#_YJd~u#gp#Clc0G@(Wp<4xR5)T01h8y_UeY)JMfK$9PhhSw1et&*_ zXK4*MIQU_kV1+K6%oCyrl>y&BY~Cx^_WwvJp=p}3@#2~C{PEY&y~`Me2@d}N{%4EZ Tbx!(200000NkvXXu0mjfk>frD literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Head/Hardsuits/ERThelmets/ertchaplain.rsi/on-inhand-right.png b/Resources/Textures/Clothing/Head/Hardsuits/ERThelmets/ertchaplain.rsi/on-inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..dea3b36335664d515bf11ca6e18d20c6d8b2dca4 GIT binary patch literal 706 zcmV;z0zLhSP)#A1mh-2f?w z0WncU%0H%BqGU)>qY|vZV`yybI88}da_Rd?me1#Vr~5wN$+qqR48t%C!!QiPFbu=2 z3Y}Vk=*J;-Y6V(2`1sR<#XDI7@pNp>KYlmZV}ML1_{8`2&ox1r434ME7&Iz@hHHru zy7fo6k$J8xv-o(r42(v=un$Dm|DJ)V;|~XV8I7=(D7gXg)Q((>-zy#nm@rAefI;ht zTfTnns_$AFCdHm1K43s*tB&Zw0TQYjXxOrCeBanudhPQ*u<*3XmTe=Us(5j9gw0qC zE!&pj!DqJWs69>1ygw5m1T~vYN@^N;NopE3n@tizEcKf}2tlT4k`RKDnnw9(l#-f8 zLI^SpW9s+=GoaCE001^)F?R-d>zA2!yRBH3MWs>+x~{wRmSws3Cu2fWI>2_d>T9%J zt-`XbsU0jE#bQx$L_3GK{+}>S(>H}o)0FBi0UuXuLm4I+3^$ZDB1rd>= zD9XwjaQLm~W|9CvLREbU6)XJ~*z4ZH=iyxdaMNWR@h#hSa|vW(uBlqdMM76@KmG;4 zmw>RF&$}jkJUM|(OJJda8iwKf=+Si@yZJnT(_{*nw$sCl1pRz}|I)Zf@4nu|>o*_B oFbvXl9baDMF7r~y#N3J literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Head/Helmets/scaf.rsi/equipped-HELMET.png b/Resources/Textures/Clothing/Head/Helmets/scaf.rsi/equipped-HELMET.png deleted file mode 100644 index ec1c408550ddbd67c5dce0f1b60bc6193fd5275a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 890 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEV0QF$aSW-L^LEzxY+*-{>@u?EHH>ssvg1t2TzL_}|RJFEkJ;*Z@| ztr$FxiyJktpMO8UCw8{43$yt{ozINw(j}(_`t(a!q@JqT$(LQ+bU68X$!hIQQ$%`; zgk2f#u)KB$opOD_ZQKqg)L8#czcVCCsa*1opST; z@{hshXR{l9#Jofu58V9Xnsl@F$#?&P_y4{w-17X4+Mr-E5+ zPZeWCoYay(?ftNQ81tNKf3{xwy)bNN z?G4xSZx)1da&LXP#OT1L-!G7_dUj(yHXcKtlb@XVbkFm zhDWb|d26^r)awG5>Y5|{chpd`QdN$<;Y!Mk>7BP91Eb~ROCE(EmW=Onnj|l(&GQKSOiY-fh5oZk(jSE5KX>Rg T#`x_4<|zhGS3j3^P6=G`P)3`CH9;`SSPy~(>A?;iym;smbn6#Hf1rbS3PFnKAW{h7sXx(Ah#>3|vA0+P zp*C2A4lcVJ3W2q;9dy=l%h_2gjPSiU&Wzvt%=dlH2=#g$lhn*a-KPLkfWH7B@@}lu ziVn}dkRCzlxGeC-75wf2VjN2?a0N6~D-Z;;1eIFRiKP~}%uUsTsagPlH|Yh{y+f{y zjm!WsUtL;c22eD^HKrBPBhWiGPEL=QnPB!n=cbG6nGf+A%3;BH63CEMLbD7=`9bEP--tcB&lxZ7&F=2w>w{n=S&?1^7Qz5wBP zGH_5uGky-B+iG$J;@#&JR}YAC!>zq2H{6D#%@gT1LV5(I+6F-X8@|zm)xAS!dnW;) z3*Z(2pkxi)%YzfYqu2TC8)+z-fk(INd!OIBhyYOC47bBg^$xKteM`pOy3a4a0sx*L z+1<|tpm%J{OM~yGYC-9PkTJbRM9lq8?+fsiOx61IIC;%^jEQ`o<6>doA!#Kd4-GvZ zV ztd}BQN|8{ZS;0#$i@U<2U?WTqn=x+OWYwL;U3?!9f9)IJeCNFx+4lf~AP9mW2!bF8 zf*_WSfYSjaNfO}3{A4m2NA^K6ZkRbaJ!1T|Dr*3M!~N3KVsm?LJFERH2#42vO+0z=7pkmT=5sNZXRqF+EGNzPf_OSMkqVyN1Oa2xv!LihRL?K*`px5!2;-Yz zJRO57YnIXF1YrV%ln9Up5~~;J)PbGtn~?wZeFcft3ji_Wx_idpA^-r^6DBbX+o33z z0SGtDG@ZsfP#y(ry_=k`ZnX2v14$r3mV2IGF^w6sG&~1f|F@nVq70)5jLVD<-H+xcq9x8-}^uH*cf;4D@hhPnYcxa{nMMK+54;Il& zkz6IT2UqB&q%2tjqOeie9yYVx?XESrYhAPN2LrM=KkVQGOxB4LY=S+S~r)$HNBkFRC+S>$^FfTM#lXX%&zBTPTj4oud+VmA5VW(aJ= zlTidC0hF?N*=zx)q1Df{|4aXh+2m%uqZ=aMgFohVya`Od8KdyfRKIQuhEF)s?0 zj3cw4l+DZWWE6lBxHfoJ3(T_Ev;6uhbPmX*b20#g{l>%=`byyCYEh@(a1hF*bMp3+dxrGs)&_>j zfU^vk1;aU@TrG0l+5lJGHFZo1{w`oz1n+9FW*9QSZIA(r7O-esZva6M1VIo4K@bE% z5bk5@%g<%MKQN7nt+Cs}dWFGAKz;V&*{h{_t8B@DQZ_FKV@lxKwluq-unb1bYyfMc zF|^%SX2y*XjyA#a7BK6;HZ{+j&P)bm(m8o!`x^Zgpxpw^dI!IDo`ZY(008iY+u*)@ zO4ufL9$3l%p+Clm9|8c{xM{KPXzmuI9$VEncPwuK!-8ku0Vwwi3YGVcuK_bPM#|M9 z=Mj7e`&V@x(vK82QK;(NkIw*5aKM2{<8aq5W z<~)K=&4g}kurwDdZL0x)U!7SNT;Cie0~Re{(YW4#-)#mij&_gLvH$=807*qoM6N<$ Eg2Gc?oB#j- diff --git a/Resources/Textures/Clothing/Head/Misc/flower-crown.rsi/equipped-HELMET.png b/Resources/Textures/Clothing/Head/Misc/flower-wreath.rsi/equipped-HELMET.png similarity index 100% rename from Resources/Textures/Clothing/Head/Misc/flower-crown.rsi/equipped-HELMET.png rename to Resources/Textures/Clothing/Head/Misc/flower-wreath.rsi/equipped-HELMET.png diff --git a/Resources/Textures/Clothing/Neck/Misc/flower-wreath.rsi/equipped-NECK.png b/Resources/Textures/Clothing/Head/Misc/flower-wreath.rsi/equipped-NECK.png similarity index 100% rename from Resources/Textures/Clothing/Neck/Misc/flower-wreath.rsi/equipped-NECK.png rename to Resources/Textures/Clothing/Head/Misc/flower-wreath.rsi/equipped-NECK.png diff --git a/Resources/Textures/Clothing/Neck/Misc/flower-wreath.rsi/icon.png b/Resources/Textures/Clothing/Head/Misc/flower-wreath.rsi/icon.png similarity index 100% rename from Resources/Textures/Clothing/Neck/Misc/flower-wreath.rsi/icon.png rename to Resources/Textures/Clothing/Head/Misc/flower-wreath.rsi/icon.png diff --git a/Resources/Textures/Clothing/Head/Misc/flower-crown.rsi/meta.json b/Resources/Textures/Clothing/Head/Misc/flower-wreath.rsi/meta.json similarity index 59% rename from Resources/Textures/Clothing/Head/Misc/flower-crown.rsi/meta.json rename to Resources/Textures/Clothing/Head/Misc/flower-wreath.rsi/meta.json index 2899868b90..c3dc06f19c 100644 --- a/Resources/Textures/Clothing/Head/Misc/flower-crown.rsi/meta.json +++ b/Resources/Textures/Clothing/Head/Misc/flower-wreath.rsi/meta.json @@ -1,7 +1,7 @@ { "version": 1, "license": "CC-BY-SA-4.0", - "copyright": "Kevin Zheng 2022", + "copyright": "Kevin Zheng 2022 | equipped-NECK and icon Drawn by Ubaser.", "size": { "x": 32, "y": 32 @@ -10,6 +10,10 @@ { "name": "icon" }, + { + "name": "equipped-NECK", + "directions": 4 + }, { "name": "equipped-HELMET", "directions": 4 diff --git a/Resources/Textures/Clothing/Head/Misc/hairflower.rsi/icon.png b/Resources/Textures/Clothing/Head/Misc/hairflower.rsi/icon.png deleted file mode 100644 index a87d0676fb4ce93c6344dcaa77a8b773c0d439ec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 259 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJQ=Tr4Ar*7pUfammWFXM+@c)&G zoh=8|3)$itHhkvV!)85u_w3GxtO8->wQS}>!X7=HE16$D$S~Y+CpY)fo$}oEE4SpH zp0qK_WH*z@0tQwMh8sI{R$aQlAkxTCaC81q(GQ>bcp_7}9B!;TUU*ZoO~+_6BSW5k zhwZ{QJUidV?2&%(OQw5mwey>k*YD^w+}$WRd(XS$N5qV{7kD`*3qSi;!4rIFC3ntK z(}McL4--9P7$1F7-JHuYVa_bi?H4#doR9dU8qxr^xrX6zkab-|&C3%&Uom*P`njxg HN@xNAZU}62 diff --git a/Resources/Textures/Clothing/Head/Misc/hairflower.rsi/inhand-left.png b/Resources/Textures/Clothing/Head/Misc/hairflower.rsi/inhand-left.png deleted file mode 100644 index f838e54e74169b230a7dfd569d5c292509d39f82..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 291 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=uRL8GLn`LHy=BPP4ZLn`LHy=BYSb0+;`ELFT~e<|;C_;WqY!iLuy zIs4a_R3Beioi@FM)8o>&D=kH*geJeqZ{m5tSCGt5-XP7qgZYlc0a>s$3|oXGTvd#gK50YKk1p2$CQP1XK-V7#%hG7Rr#J7-Jk5Kq z#t&tD%J_`80K73)0B-?!W2^w)0`SII0lWp^4L5DWZ+`n)1AsSc?_74;*a7L^3as2z z7LXQGS|Yh%oDXUP0Ey(nz&3V3`kanUVLCR2L~_A6$TchZ27$@~T7rtqVF`(?1)QE- zAT6e}gOq4!IxVKOmY^b$TtMcqgqEPP$iReZz6Jm|ZU5SZizXC)<@#RB6)I4&P5755 zP|erik$uMfmY`xfHf7vjip=0U?Z*dmgKqw%$V^Y0?)$X-_qqV_yQRnsT7n8C+r)Hi z3M*T4#z9`bC8&mQH2zA1e*C#YrRNxypUMStg$mU*tLt{a(kCmwr3JkFkkVc(K1T4e ziE6%vy5t?`-z`B!UGk!uuOWEZ#EZqpc=^HJWH<_bs#PE!3v~E=wQB-0|M$o~#A5-P zZmH3aU&%I&!wx@n96(T)yb%0uRMAN)D>tlNF+=dXAxq@EQzmks6_!t|CF1~qe+qvg z9MYSILuhN*q~%56Jl{aEjCMO1fw6R zI4l)FmXu$QuMyptgd#Tqz)%7~(G*Hd$EF}1Un7xhuhllDK@#27rEC3#Wb;V(=MP3d zqAq!jXYT{G(@4kH5d3b#!~uO2&hri9TCuFRdnic9?H7l)J@@pEzAnd|6%cD7s|I$g zIqr=Fcdxd!YQBc(qr2Ia_!vE#% zhKLg*J!*cY$bpP>vCC_^XJx101V6O}?5&Ef`qK&2pH849s7B-`D>r%^-oEFQRXD}Z zWC2Q6j|1w8x8r(U^1{=O5nv3$2Xlz&k$pyt!pcv*3jAO3$?pn}6~J2n-WV%@ zw*b5`Rse4Scw?*p-U9H(SOL5R;0@-DbaVRIoFV23J2Ej@!215C))G|smnX2YHRnhj z04vgBN?X~QgMV57OeTAXv|x4tkL*J=U&HCi1$QNomp?tZ=tn4l$D7HWb_=5Lel-aIkU1hiv2Gn%JGKhES$pUD>F-^AbWJr0@mRo+i#1Edv@4tzQ<{Hy0zl_Tm~(SSXAQ@e z!nByuNFI{BJeh+?I$X&%nfRG4pkK{^IWyzrq}UQvoagm(k{#-!^Lt8*cO#mkh ps#jpaxITcl0K73)0B-?!<3Eg!FlCpy$bS8ZIOuiNO;WaSt7Gc+jOJQy|UKv1_;d6&cz+V5ALau_UC9!4eiGzduzGKT4 zs+OdXt6&!N|Zvb!u(cj@8pS3Hw{3P)D;!?>Pe!3hm{uYLYT@30quBJ+_x}fKVbV%Oq+396 z2>M~@LFD;48hD-7%=>Y>@+Xkh(g6G_{bYT)W4^vjH^ROsQ*cvkQLfUpgQfTyOYt@E z;Wd)L7yUc%C~<%=v#UaXnQJGCkqUftK1&~dymuB7e@MK1oZUCY z))U*b5+SX0>huST>r$QLjT6a_fUg3_8z<6f_RP~!T8Z>zFIRc8>`t?1l8AF50{?=m zz~FllOm!eR+Rh6_ISOMXA~(|Vz+Gl=Rg42+1&+4!lCc@W*bHIIRxk6_%=^wh(5)L+ zm9Z2suR3|aFoT|QLk|+@<_LTe&mg4P-SEFB@D~W0__-qyB^dw!002ovPDHLkV1kcE BHk$wd diff --git a/Resources/Textures/Clothing/OuterClothing/Armor/scaf.rsi/inhand-left.png b/Resources/Textures/Clothing/OuterClothing/Armor/scaf.rsi/inhand-left.png deleted file mode 100644 index ce718ad3009dccde289173a2e65180ea65f811c8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 691 zcmV;k0!;mhP)Vr7Mmm`QAe~GQF2&f|-cY*x3J}uW;PFM7w%KGl zH3cbv2oAY<53LD!@p2IWGae$hFhjr`Cb&77Ce8KDZPQJ|PP4&+B+FXRAlWPDjujsoTom^9!i|FhwFoIpc zb}W@!n4##_SxilIub;mE9Oz4KJzr6;UnTyE-^rIb{PsnAf3@!dy@TwXwu5eCy@TwH zAI0Ed1PK7Ir6<_jdh3RC1kMDo@sveD`GBj$oW2yL3gvLP& z;9h430-1o0w%KIzyhX-{c1!TX3SzN0w~=4qH)mjoq#~j0HAyFWb)kq;32>XfIsI5?jx`XXq(Nxa|lBC Z^BcM)3w1J!rL+J5002ovPDHLkV1mIOQ#Akp diff --git a/Resources/Textures/Clothing/OuterClothing/Armor/scaf.rsi/inhand-right.png b/Resources/Textures/Clothing/OuterClothing/Armor/scaf.rsi/inhand-right.png deleted file mode 100644 index 6bfef738a454fd7a42912bc9b1233628db04c081..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 680 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 literal 21114 zcmeI43v?9K8Gr{kJc4NJgQ}>o2CHa0*_k`;NVO^|TB}$K7Aqi%TD28uQI6t+N~;GdhxVU+WN*TTi6O1^oY|A? z-ktgHfA9VNd;k0Ych1=#&YCgl*x{pwa~yZ@O=NlRK9;~>p(;R{;gnAFo$z@)X&SZVRz zr`Ht+qE>0~Jf%vgidWFO=;WmdI(zAi8nU#W7*_EGk>TN%5GZJ*DI92NY=|X8Ev3b2 zy&)*OmxINDv`DJHw7AS|FfhMrR-nR3(122+@OAZCoDTuT{$t^9DFM+u1lrjpJPCTm*bG+0fOPE&%=2}@uoV+)NwnX0CF>-0huh!<3pirPKsaqsj9 zfwn|@sOH|uR7=mPjH$x_EmV=9IOQa29H$|YnXa>Pwg^;Iq^DZaIdtmvWy;!gls3#h*ObhBd(>vc&s)Y%wJ?AJEv!;!f9|4&@CE~ z!ofn93)ZT1NRzuh%3_2j!5B%#NMNe82Pnt2U9aYDG(;ofM7_M+P^1a6Wa#A;Vi_tg zQx#Pa%E}BCP1M6dcddh9zV+-3$X?GlFv}rPE0piGKnSJ?fzMKPFr`Q>-W1@Cs8kRQ zN!A5}^ij2>Nt$3A22WLDXH@G%QFtO7R7bX@B4qYawTzJ^*qHK$jA&N1Eg{|(O>7}S zrh*{%QMIC*qOKx=rAtro< zRVbMVDXO7~ee5+ADb-b+29j0XUqGlqux!DUHe^M}&X9gujTBSUA}~XMbxw6Z`4DQ! z7Q(vi&XE2FLM0@cGO)Il>ov1hO-a8J;|>_Y$Yy{?TyD3jU0 z(nWARSjVc$ONwgqvMH;)A?OmXix$NMQC-%(Hvx!sN-WqBO;a$5Ws5wvsli){Z1aX; z0$0@(2q>busCaVCDYF&PGGsyJk*Q-|!LX6QhNtr?Qi&xHooI&9du3RMD2s@^3e}){ z?zGZmk+&rQ*+f7<0OF8Bn}6nN*Pw!pSdJ8uxRG8}RcJ~qnZgjUOsR~xgNp(w%TR4_ z{O*2$bY9YBa8DH2%O-_!6Dle)PKSS8tLMX#tm<6rpt^8qB7q5!jx1ib4AGsBl*bgj zfNfhMRZUE&oQX4`Ax7C@4b4nMA@#!zj7-i@8UbSv#o}$vR(MO272cG=^hAfyN0el0 zXq{szpysfqCP&@SuC;3nmJaP^)5Tq{=0m%5k`~8_Bz04e(&AhW(wWs|;<#)ymri9u zn7HX(gt&n{g;m+*YQ9^YHNzQ!=;7w<9fHHE_uNKv9gQ6+G03P&OZBWI>DZ}eoSTs-ts7UZmtnVNB4&Qi~D{5xzn%Dn2&m8_Ab}+ zS7zEPX5TV%xNE+b%ZCro4|B~3m-8d)XT_{K zzY&&(XW7T)iHH^Oaj`T!%RVkoM67_1i>2XN_HlV4Vg-C$EDg`HkINGgE8yc|X?T`> zT%L$n0UsAj!?Wz;@`T5wQY3E|!L8*~jIHh!ya0 zu{1o(J}ys0tbmV;rQuojad{$Q1$w9WmWF59$K{EL74UJfG(5{bE>A?PfRBr% z;aT=^c_Ly3d|WII&+-v*4bT719gV?{+cm?l*zLV|&@}i3ya1V8UBz)rzs+&&D>&}J zzv1%(j%yM)ZqFqg7wX`+lbstEZJ5Y$19wfSEURgG`=htlO*;*rGW73z>&K>s)jfP^ z@%|Mfq9<&*Wkl2Qx0a94L&H88vvpqC#=BSiyZwc-t=HY4-@l>as-1yH;(_IR?)!Xl z^8V6Ub?4t#bne{uum9P5ADi#K_V)UBODZm3_3`G?zh1s$=Bl=$aPY+Poo7xOG`i)R z+<+thh3|g&opTm!du(;dRQ0EWxgq19{9Xweb<@@4^>QC-LYfV&L6LT2IF+Bssff?!kjg2e$q4 zDuZ;E5jQ$>4WyaXYViCQOoUrZ+Ghl ztEX*pL;!T6K(8f9#xj?T?(ZOh;E;*tY1Mh12i-JhE6v&GlzAEgO7o z>48-fhgu7sIKAu^`pUNV$3OMOz?&z|d8TZ_g`a%%Vl6uL2fxSm>$}_9+7|!m^5vIa zy!?SJ?Pm3)$Ul!;R2&PB-Z%b0&G?4BQp+-JApgeP=cb;w;?3>ff^S#MyzB0c*IxN- z_lONwpSEu&dj4+@em3&@SjUrV&iO|BMH^?|GT^Px%FiAu~RCt{2+A&KT0Tc)D|J7^?vDKPf zM(bcgFC`zq#UbEV&^@PMAm~sWo%{gJa-Bst2N4U0n~UHg4WwBzn%?C|YSC`N*TLSA z1`Eb}2v`2U?JnHA$K%~)xIaKdL_|bHL_|bH^h^g>t6UjdGJJo|bzN~?SN?U)V;;Na z%GiH0~GTq{CxdAI^XMhuq^Az_i8j6 zGBcNrj?+I(gmotu2dX`*J_5Uk_5ET#g?7IR;9-U12(NGVt0?AE*gdT8$8K_j>HwVF z`uXx|DO&%H!S&cLz)-L2VPkL&0PyZsu)JD=lUqMmYxaK+)d2uN%f7_f?I{4@{$c?q zOWR|uKLA*kWt=Q+G**R z*VXDZq`d+5#5`cn*3j#E*tv0Iy|8v}T%*_ZV9(YtG5=6srAs0rA|fIpA|fIpqGZv^ z5U76{dMQ?>Y2y8dQj|dehB5?WNbCSYaWe#}pPFBiR)!$41JKG4{1=Y^@caxxq6eUn sAxP{15}P5=7B@qX*bN9VLqPHT1|Rkgw9Wv64*&oF07*qoM6N<$f|AP~KmY&$ literal 20591 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 Us`Drc4?w`)dX`nDrO(R$0PZK-2LJ#7 diff --git a/Resources/Textures/Clothing/Shoes/Specific/skates.rsi/inhand-right.png b/Resources/Textures/Clothing/Shoes/Specific/skates.rsi/inhand-right.png index 7886baaeda6342587754b9ad910a1bc27fd2c536..0b772c7c8560d855512fe2b03124fa84937f4611 100644 GIT binary patch delta 627 zcmV-(0*w9WpaF{okR*Qrb5ch_0Itp)=>Px%MM*?KRCt{2+P_O1VI0Tt_tk6)vDKPf zM=Qky67Uaj&>`T|UB^NW!9c1*$tF1X2eeE22MAppidZwdNWPxI}k;A@Px^pj+$#i^A=rRGNQb|or#aq|W?>eVn zo1_yFMrWH{e{7hpD-rcO50H`){q!ST<&~5?1NGBpx8#&-l z_I|ofK)q(O+B^rqzFJ~&c@BMZD}bDXp>J-nxIEWd{;Pk@^S%clbeVuuDy8ksZ*X%s z1Hi%MJ{98#ZJ`ig7+Ls%Q~4_68L#(({`- zOt&*yj;prEGxy5c^9(3lm|DGNV@&25nFd0B28>LDF`1`cvngDdp**aG5JCtcgb+dq zA%qY@JQ!Lb4$e3*IK0{HCU!_3nJ`0e1s%+mx6q=SD*{C4nR=J^be4qp6QeggdI4)5y=Ckp@o N002ovPDHLkV1h=iGGYJ# literal 20584 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 diff --git a/Resources/Textures/Clothing/Uniforms/Jumpsuit/ert_chaplain.rsi/equipped-INNERCLOTHING-monkey.png b/Resources/Textures/Clothing/Uniforms/Jumpsuit/ert_chaplain.rsi/equipped-INNERCLOTHING-monkey.png new file mode 100644 index 0000000000000000000000000000000000000000..3fb85861a1d50ebcc76e22f3ed71ba0bd9c6b2fc GIT binary patch literal 974 zcmV;<12O!GP)~L;ryO3%xEB_EMj6EjjLK zFI#%>p_heRbWkI#1Q{coQ8If-q?Hr1SYyj=>HA#7JjVLI_vVepwjMwb1VIo4@spy} z{eW%T5&+UP)&9@c6r6KuSr#0}DQ%aRmk>fAj^o<;dY#Dw#^jNv!Sg(D&Sl|{=Xp5N zGz=J%O$I+;Og_81nhPEP9LK@4t1Bgay-wzbC&&15Z~((F;JPk2=hAgu7>0o_2L~9Q z9G8h{V&#V?#~AJH!7vOsjx%>1?d>V)YjqspoMU@?yR>Cl2F6%9&hs2m6e*SBvigQ$ zpxtgG%QED74%0Nj7{g>T0f5^2=Cb0h>%uf|rx!t26Od&YOw)wtc>o~SnS?^Wn)oW! z@!h z{#q*F&)~z@<5>IW<8Si6dGFVjfO-A*8UWdDx95@) z$FcU;A4iSoKPbm{j~+?Rxtx4@Bdg<0oZFmpIbcjKx^CoqK&R7@tyb%SeL9`u;^JZ> z-vf4ccVSr;Ow&Z3=MX}aRap0aCVo(a5V*Oy!S(g^O7}5USARO4miAVwg*&@!vI?rF z!TsYd2m+~c`Y2Vvf^uKDEt=wf@SJlw8jX|^ud4+AJrV?g>~^~n1VIo4K@bE%5ClOG z1VIq%#&H}uU`)Q++4<&wLcZGBkpsr0<2Xvb=qkbcz7IVJ@OJnTg|MmvstZtD-wt0w z4+8kUujGT$djZB6(lo`>*QfA(9{}XHs6yZO@$~g6Y}=&Lv(rGyXyNs^%7@1xi2HC_q5UQhP>eI!W&Aq1pc zO|sS&`1`|)TPM04zdZSj^EL0DJ;u^5CQ=3cs9f7yC?X19^a0e>J3(&MPd>eAyaI}zgsS!`4`8Jiik(hJ-t_{_Js8i<&KhZus=_&!`}_M3`h>zTRO(OA zR2--_ECE=lK|wVMMUzAol@2w19S&_WcmRmwSR0SWYq^)MB3|vt`d(1&Pt;UP@V+h2 w^NsWf70;leZSVf#&<_=YAP9mW2x2+@1?2LtutcvRxc~qF07*qoM6N<$f*f+y!vFvP literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Uniforms/Jumpsuit/ert_chaplain.rsi/equipped-INNERCLOTHING.png b/Resources/Textures/Clothing/Uniforms/Jumpsuit/ert_chaplain.rsi/equipped-INNERCLOTHING.png new file mode 100644 index 0000000000000000000000000000000000000000..ef532d7232b175a3c1a55cb967d2cc3ef9f487c8 GIT binary patch literal 1393 zcmV-%1&;cOP)z}D6lmk)r0LaY0PzE@TgE)>s=}80#A>8o!>rSTw%d&V)t_o-Qecw;rXX8Bl(na2HG#cpj zdI-aild;H)qR7V#VHjdC7@*N;06?-#7M#Z)MG*i%RaJPN$D_~WS@}Pj0k^{tPap5& z)^M0gCqf7>had=2Wk4wvZViWc`gk9=PnFJ#5AjP0q_Yz9#jxdYgkQVL3`aP{idghgZ73^30MD8g(u!*n`bieJoHleTT+ z{$PMstA)RRzl~O_h5Lg6Y};PC<`?Dv_T4+!wvBIEt<*RVf2LHe)oMwlQo+W?1^{3( zneb}>7>!2g_xpuC3fJrPL{SuMZf^4Bkv$cT$76(H2+OiE@nqbPzTNr<9|uhHuOA>=({Wm!(mM}<3pp~!S! z1XRN|Y#3qC|-j zB}$YiQKG~J$hD)gPYCb6(t4fC-@bjjmK`F~G&#RvSzMmyY=W4_cv`PxXqvd8D0ubc zPVW7UW6>m=yW>ob&Lyj z07H@_h@uF+UJr2`uPp=OI7YA6Lli|wlI2e0WOCb&NrGR0`wm~#4Ro!q@%_(#@hG^i zyS53?bzR7^%=aM=|2#O=iQ<=^p5Tw7mO)+D6HU`V2tlXQ!IdjlpsFgb$#%P)`@G(w zXf~Tkv)M!t1c;&tp66jS8lll>!1sL&1_Kl}32K@K*LBhDb|DA?#^dpSKO~C0Rb3>e z(`o7~z<4}{APDGoyKr3>nx++30_VZ=JgBO=mTmF*5@6iRB2xz3bR0;Mgdb)z{uzcL z9(W#X+s5l>_X;=u^|O1hZ5t0f4`CRlbde+pH#444%X~iItZZv*i?6?w(!v|2wOTDP z3Vauj}B#feAyqk%*Ny@xW#1^==b}V z=74^`zqAv+_!7uH3FcjPRy`5^AM_|u;uFTdTz~v`=n(6x00000NkvXXu0mjf)@PH= literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Uniforms/Jumpsuit/ert_chaplain.rsi/icon.png b/Resources/Textures/Clothing/Uniforms/Jumpsuit/ert_chaplain.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..fdaf39cf4e3d1ba2d10afad0a4268e2fdc712800 GIT binary patch literal 421 zcmV;W0b2fvP)C`i*ZodA(i}Lb%NkUdlR~ z&7$K=MT(*Tz&Qu-=j>Zmp!sOix%d7@8`?N;6+pZoM9jE33qpuad!W-TAw(>Fk|dp- zcM9NqKGST)Z~B`BuqaEMb1Zi|thKy6EwI+I-0g7Au_(*iuHxx*T1zPz4u=4oPNygX z9FIq~+wE2>Z+=m|9g6RdRp-XGfI}u<}m8X P00000NkvXXu0mjflr+R; literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Uniforms/Jumpsuit/ert_chaplain.rsi/inhand-left.png b/Resources/Textures/Clothing/Uniforms/Jumpsuit/ert_chaplain.rsi/inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..ed878f2d3103e4c5a3f2cefeac70f50d2a716422 GIT binary patch literal 551 zcmV+?0@(eDP)U*}1Z zAc~^1v(M&5QG_H(&dyGo@ZU_p<7$Q1mnW#j0!`DPsw$*uYO*XdP18Uv7I=Mm!sBYy zDKE=1lcuSustR55{^h|&$lLqJhiTguVHje&-C{T#Vzb!*09HS~0SK+-9iQ9a*}4PP z>ot^8XxkRM-427n0He_eWm#e}nLuleqA0vu=iTHE&{{(Xfx50?jDeIA#u(If4Iu=y z)_2XjY6FB2D2l=pLLiP~D5apahEfV~9G^YEN8Z)H0st_d&p$3arLf=cp|ysT68(N3 zWm#f89%H#&diTn^iRUmhv+2})pUuql)BeS`-WC*W`U2mo+696tU3p>q>pdmq8c39z|8;JJDS*xDa(@>js-{(y50 pu)ROvxi|q%?hn|;{Q)8?egb{&cSPq9aohj^002ovPDHLkV1g5?14{q^ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Uniforms/Jumpsuit/ert_chaplain.rsi/inhand-right.png b/Resources/Textures/Clothing/Uniforms/Jumpsuit/ert_chaplain.rsi/inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..7cc2bc1ce223aaeb176ab190a665d4cc6d642d26 GIT binary patch literal 544 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEV0`ZB;uunK>+LPau15|cY!Biu zPwNPCQkv9sFD*6fX371f{8wl1^ol>ccD0Ox@v(-GrjG7eu9qjQc>7{Sz|}wZ)dD&{ z?RQ@)P{SYy0}KkDLd83#rOve6n&*8_=kyuX(k);2|2EQm8u)SFduK1s+p|7Qz5cyc z#_VBy(dv2EcYdGxKjz+K>jU3wTM|1g`mD3xs@+%;TVow9 zbDZPwhn#zh+4ign`%zKf8l@9(-Sm=)spq5_n{)!Nn_fw3?EfAPlnfK8pRrxXTg5X8 zC_DX0t<}~azt2BE?0Z>(gDGcwbdQ^Ij@j&Uwb6GbZU27PdTZSJg;Sg^o7{L?Cc)P( z(SKZ{i|O)9k*Mq^mG?G3<@s@ckNSCrwWcisD^_tGlkm_?>~RbY6>xIM&b`XFL-l~Rp7~Q%_b%ps(}7d*P3xYjD#5^}`Ps(I(_h2~@9{QfF3)WM z^7wBut~<+fXDf(|dHnJcd+cn<9U<>$86TKBv$1^+Lh{aEQHDFSB`Y}ovHO2{{D*aQ XbCJ#2@RbvRG0))X>gTe~DWM4f5(xZz literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Uniforms/Jumpsuit/ert_chaplain.rsi/meta.json b/Resources/Textures/Clothing/Uniforms/Jumpsuit/ert_chaplain.rsi/meta.json new file mode 100644 index 0000000000..dca2585d6b --- /dev/null +++ b/Resources/Textures/Clothing/Uniforms/Jumpsuit/ert_chaplain.rsi/meta.json @@ -0,0 +1,30 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from TGstation: https://github.com/tgstation/tgstation/blob/c838ba21dae97db345e0113f99596decd1d66039/icons/mob/clothing/under/security.dmi. Modified and recolored by Nairodian (github) for SS14, monkey made by brainfood1183 (github) for ss14", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "equipped-INNERCLOTHING", + "directions": 4 + }, + { + "name": "equipped-INNERCLOTHING-monkey", + "directions": 4 + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Effects/rcd.rsi/construct.png b/Resources/Textures/Effects/rcd.rsi/construct.png deleted file mode 100644 index f4be36c9bf4363ad314986a38dfa3dd7a506ea6b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3612 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 a+X}&kW$HhP#uT9I6EM4EfvPrgjs73@Qy{Pa diff --git a/Resources/Textures/Effects/rcd.rsi/construct0.png b/Resources/Textures/Effects/rcd.rsi/construct0.png new file mode 100644 index 0000000000000000000000000000000000000000..d83fa0506c6776eefcde77cb0a4e5203f70efe98 GIT binary patch literal 1095 zcmV-N1i1T&P)003YJ1^@s6nkRXg000CINkl$#fB^)q-zTO16ndjAkeLp zjP0PEoi2mTrh4kT-tWy|NKw%=YIWMvO7F8xvW(@0AVuG0<0{@0E=>PI_>0r%jWu zH;nY!CbwI$-!{fLPTHWaudii5$4Q%%XE)FGsaAvh#d-7a9 zr86QTf_|W1jY$9Gp8oY!O4Wd`t~@!q`6bzxuSG;8v$ZLg`#W~q@7{>>bZ`UE5A>^@ z@68W3fAnmjk*67-RDFhRGI6CR->4|EV_HwHtG<2SC4JvW1d$17-^) zcSK*&fGg`8=TiG4a=E|rubVzNv)(>h8_Wx#KdNti7#`BsVtwOWRzyUO)zx)g?WC`@ExxM3R=i;!M+1jjzXouFf%{YBkmm+H_~ok2C|u zVIGhSIGuiIW8~`%mkc;X1{4vs4CJ#6`eB(zKdKBEn;}?h9xNCF!t1-a-HI!{wtG9T z<+p9=hwhmsUC#shkZZQj9Q-zNCs4X7Cb(4PHK|@Cm4`D zA@S0WWJ!LU_Jpi-TSc`D)@>C9{i0e1^!2sqwu-C=jGMk~Vz(ZUJsIo?(exe}kPN7s z0htGkmwvWT3aaUBq2w;Q%{<_8&I3MfeeFka8VBQyWFYj_^i?w;$FrfYslPhU9M0X> zQSL7tzIit1vc`S)B>h>g=b_ImQvZL~73MQ{iWW1j9ZFxj3r0WL`m5SI<28wczUGsN zIItoB7!VR`K<$UoN!O82OM|4TvX@Ng~@jF>f6ek%WOV>1&!~W;r2`h94FHE z%4Xi>I{tS|y11y91r6UkP$KE))8T-G8<1asDi{C*0tN)YfB*ng!2kdN0000000000 z000000000>2FtMkfF6(@5Hw&<2w*_KfB+Z}Fd#(`L<+~VaXgzUe*t3ehmV#4$AbU> N002ovPDHLkV1lq$_jCXN literal 0 HcmV?d00001 diff --git a/Resources/Textures/Effects/rcd.rsi/construct1.png b/Resources/Textures/Effects/rcd.rsi/construct1.png new file mode 100644 index 0000000000000000000000000000000000000000..0b597fe1080de7a05f31f43f2c38b85a9bbc90c8 GIT binary patch literal 3663 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 BrtAO! literal 0 HcmV?d00001 diff --git a/Resources/Textures/Effects/rcd.rsi/deconstruct2.png b/Resources/Textures/Effects/rcd.rsi/deconstruct2.png new file mode 100644 index 0000000000000000000000000000000000000000..d2144af3c78b41f5a6844dbdd01a23c9694b3d50 GIT binary patch literal 4964 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�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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Effects/rcd.rsi/deconstruct6.png b/Resources/Textures/Effects/rcd.rsi/deconstruct6.png new file mode 100644 index 0000000000000000000000000000000000000000..70771150669b4abb1da6f41476099d5299f097d4 GIT binary patch literal 8158 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�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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Effects/rcd.rsi/deconstruct8.png b/Resources/Textures/Effects/rcd.rsi/deconstruct8.png new file mode 100644 index 0000000000000000000000000000000000000000..79d724e6ba2e76bc3ec4bc2bead42ee8fbc006a3 GIT binary patch literal 7941 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 Yg`;!s@;^-gdK+}^^aZPulh+^rAKYv^4gdfE literal 0 HcmV?d00001 diff --git a/Resources/Textures/Effects/rcd.rsi/deconstructPreview.png b/Resources/Textures/Effects/rcd.rsi/deconstructPreview.png new file mode 100644 index 0000000000000000000000000000000000000000..2d114002fb288ad27decd3b2c005be23cb013b7a GIT binary patch literal 47364 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Effects/rcd.rsi/meta.json b/Resources/Textures/Effects/rcd.rsi/meta.json index 5004a9c4fc..c9e8320c60 100644 --- a/Resources/Textures/Effects/rcd.rsi/meta.json +++ b/Resources/Textures/Effects/rcd.rsi/meta.json @@ -8,7 +8,65 @@ "copyright": "Taken from tgStation at commit https://github.com/tgstation/tgstation/commit/d75cbd0a2900fdec4c12cd5ba986b52ccff03713/icons/effects/effects_rcd.dmi", "states": [ { - "name": "construct", + "name": "construct0", + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "construct1", + "delays": [ + [ + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "construct2", "delays": [ [ 0.1, @@ -45,6 +103,357 @@ 0.1 ] ] + }, + { + "name": "construct3", + "delays": [ + [ + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "construct4", + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "deconstruct2", + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "deconstruct4", + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "deconstruct6", + "delays": [ + [ + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.15, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "deconstruct8", + "delays": [ + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "deconstructPreview", + "delays": [ + [ + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05, + 0.05 + ] + ] } ] } diff --git a/Resources/Textures/Interface/Radial/RCD/airlock.png b/Resources/Textures/Interface/Radial/RCD/airlock.png new file mode 100644 index 0000000000000000000000000000000000000000..7b1e0e9aa089b0179f3f63a6348e58d5db13725b GIT binary patch literal 710 zcmV;%0y+JOP)_w=D+yqbaBpyWE*{gqm{sHbX|AOI8!VZH7 z8+d8ic5p#*C@ge^K{`7GOCXFf4>sAdCRr-Fdf0Qz^Yi;Y-}imqHzS*yn+#J%8M0gh z7&?HPamuBorPD^ELAhLJcXyYk3k%$ungZba;UOPaSGhkk!K%brERFcT& z^H`P@>NQQH+wCT{GtM7ietsU$^Rn-OQ%M2{lPQXV5CW;EPZCLz5JI3RN+kY|HesPq zh$M>>!!R&SGu9S>E))v?$0?9y`Dy_qaXv7BxI}?2t-VPr&J3V+QtwN2QMa%+2rf%I?q18WN+;(=Hc^! zC}=a)M?t$sOA-Zb_ST93yk9t>z6f_7Ux@je6uf#{<-?oki^{Srs?{p>#l=jMFp&ap zya@-T2nCc5kbm5b^#}0An+QA0466VQ;P$PT>qL~0~j`dU$%iKY0NyE!vFvP07*qoM6N<$g3SC$xBvhE literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Radial/RCD/airlocks.png b/Resources/Textures/Interface/Radial/RCD/airlocks.png new file mode 100644 index 0000000000000000000000000000000000000000..1195d79b58bb2196da79fef53d163110eed1d880 GIT binary patch literal 776 zcmV+j1NZ!iP) zO-mb56o#KzWAvKZN;I*7Qd1apilbc!UAZWA5V|bdO*e(E+Et;O?(2V$7P@mG)s@gf z$f5)ZwTc9cA;_pvgw%Xkr3q6(>~vv_rkPBVw!w`DW^vzp?mh24UvuD6F6Dy7W(JOp zjTxGzAnAG??(uM)9EB0j~70t z(`jkUOn*5VMK30~W56_c=`9+@2qg{m@M7XsmMxN7575zuwLEaq~# zitxF)xtfey64*KZ3Q$yve`3?q(}gm$a{G&SQdt6xW}xr>5m!B4vPnB|lt=A(?C4x0 zIMJP&ShRfk$jAu6V6Z+pFg3BrKr+dv-QAMCTQ`~k=;`UH%>(hzcAU<3QmItI-MX&h zcDu=)t7{%r(JA1S> zpS=3V;bFen+sLHTwGpVs?Pf9WYHK_5PE!-DEe1QO9N+i%YY%~beH#+qq7dLs5dN5~ zxzrxro+KE&Q(F?=ymGI!$^3=!|JDglJDklhDi0Zk!BG`@mN~Guw?{IWEc{sB2!PW| zD_<^vjbs)oc&xEp`xQcw^o+U9x#?%}iQFk5$zb|8e{)kuc+ zRvVHeRX>#W_VyZzqM&ISPx@E?Y2uw)?YA6CFXd7$Tz&)TKqMS2eiK#z0000|)|!nmY^~*`d-MAtmv~Y2ZP<5hiLNcb+SWq9GB9x_0&{%_ zkijQ8lzSU|0w`AisEE?XQnW<0Edy&JjLkx939cW}1AuaXPjUcR?{k=d-H8>@0H~l` z0iTSgK@apk#|R)wpZ#_eF?~GrS%vx|YfWG0D(HhMupK*wvu+<6t_dTL8N(<6TiN^% hoM8$?fFKCF^8$1Ha?PK@$TEX>4Tx04R}tkv&MmP!xqvQ%glE3U*L&$WR5rf~bh2RIvyaN?V~-2a}in2u&K2 z6c<1NmzipIj037> z8L4*mUrKu)ve@B2KYqcS*9Bn@jCJJ zrloVJzVjIhC%u0qzJVhK)RE_e5 ztjh}LEzWAW%9{7&FAU|i?Y{ z03*jdDo`Oge(*o|JzKLdIpHRSVnE=8f^XD6qK(j^EZ5Y1m@fn}dwLI8wp=Fl{!l%%IG#@IdAXpOD4&HGY{ zYMvR1%{ljZo^w{u8WI>;!~~eYGy&~1n~L{dw?OyoZ@6&j!YT5L6e(5kUHn2i1F8tbN*b>~(_};{Hk3lFR-*-v znH^#&x~_wB4r`3Mt|6Usczyc>037z`n}pt|o9{>eZ<+=bRvz01WDM+$`t~(rEqkNx zbd2fiYair`tPKFb>G%aAnqnS|mE!LoGP-%0It>v)YYl5HwAObyCAhUV$)JqcCQRZ9 zc<=(bIL{f{GFgO?#GQAlDuM6jaAuZ>rZwc;1#+F};(d<^{F1_BjLa5cNM$MQAoqdHWzFz*j%u=;Qzb8 z+o@0En81^9aZ}1YTyC?Oi)Xt4fH>^W0)Xg^64!2a!j|IME(lMBD)A* y{4nvU`%7GW6LLK~x+a?D1)^T(Lj{8gNSVl5IF!@_duo84O6IE zsR+ISR7zdBtRS07BbD0a5;n~d`hy`Xqm zb$|IiuRw^GxM9>oiLz8W4Gv%!b@V!|Pyh^rF$Dnd)9rGJALerGHLx&I6q&?r+vY36 zWpP4CAo2Np?hD+P*LXaRL?RIgU^1CtI-Q0C;5ZIuvsoYj$8q@jK)xWM*J;7FZHS_X z@p#N!1Nnl4@2?O40G4GzuW69W3fiAduD>8(kf7HzSeE4=&WPke2}2Z)*Sm002ov JPDHLkV1lxd%lZHS literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Radial/RCD/computers_and_frames.png b/Resources/Textures/Interface/Radial/RCD/computers_and_frames.png new file mode 100644 index 0000000000000000000000000000000000000000..0f17ab5ef1d42abf861dcfa6161dfc21ecb6c3bb GIT binary patch literal 775 zcmV+i1Ni)jP)ok{PLVm2R zo!GcgRD>v2(sjQ#o-+af27}?)HO7JhT&|JaHKKow>-C2()f)`hY%NSpy*PADFc{2! z2aHA|CX-23_a_n|911Zx@kCW$d*wQ%rJ}YF#9}d`(P$dJ6^~OP%Y)p1R#gGExXbSIAX z{?Hr%Xliawn`o9X1*J9fW& literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Radial/RCD/deconstruct.png b/Resources/Textures/Interface/Radial/RCD/deconstruct.png new file mode 100644 index 0000000000000000000000000000000000000000..ca9548e0cf932a6f099c84b8585b262696df86a9 GIT binary patch literal 1200 zcmV;h1W)^kP)_7Q_+9?!o%}C@8|vI z`{wige7@h$BR-#x`#B8m^LSw3z8kP719$G+sX973SY=tVCpDF-%1ZL`^8pBScWZA` zleqi(_&ge=&NNSLHH?g^%F1c^1qCaWQdTe!Nbxo`?SDHOow+9^rE}M=T?1nokYrV` zZrwVy%CaQep449+5SZri$chy!biHYU$RdvRb!(7sJi!bFcKZX)sQJ#M+832NV6LWuD7Npc;s@p zv>N`Na1HUz_Z&6aho&NO2JA86sVgrKUiu?P60>#KKC3)YOC1GiHJ z>GAtpiGZQ?XBb8aq7RHF7yXl|?sgek09p^FKn#(Y1`GmEjV4D^dLIEe?{@dz4FejG za4d$1d{bPQrhzX6UR6qYfK#Id1F1R!P~!2VPsl)UM&uSOFe9Qh=tOz0>D}`Ns6HY>>3#O|ue~!Xm$q4Hf&kr`oA-C3A<>Te5(}e&Zi7~jnBo^*+ z)zv-WbUNSET5oJ=X>s@pt_F_*IR|SW?^&|D?M|0Kat^r_fQZpOOutDhTbDxFoK9zL zYisL~o}Qk;va+)DV{2~i1IZ>IGXkxLAW&G0v2-MU;$$)YD}6{j7vkI*Kqv5S*OW)g z2c8^g@caE|gTY|I!i5WG0~aS;1x^=~&GFxYm(B6xbb-@_%yqFX&h4DLSS@lc)~WMm zU;I^TeN03ie!soFQYm#Ip>-T|_uO$62#A0!{>)FWn=Jm`LTj;u9053U=FBJM<>d=b z)Yk54YipaF(1w)CSSH&nbHH^g_nQzs8gGeG--tgJ0twp>f_ zmn~cN*KPL$xt&>(1WQKUnmDU+JF`E$XAQ|Pci(D}VxS6P{arKQztV@drbc^fYIHJ< zh8H(m7WJmdB)k1OT7Ny95e_p=)4K4C4hOxfl5l3-?Q?h&a`1^sqrpYSHf(Sg5k@4U5 zJhB&%cqA4H`~o}{3=hnEIwPY4k^MkkFdY3j6WkMCg3{7b_L?T)Sd4HiHX<^KOT#um z3mjEYiq=aJIiO(^O66;<_i3&7CA6zouf8$v2%J8Bnpv}EvA3gxP$&fb{lh;`0{ZFi z?*nABWdU>m4iWiXDU~N8-N0mr!|~&n@B%D4LOdc4xm*ZbLQqAvkA?^|Y O0000T~J=tB9o2v45|A@`Cn9t<@)B1Zf6^*VbPFV~Z6$S=c!KF)%PN{Q32R ziICcxS1(3jvxga%<%-&-KlPJqAH2PFl|wJK=&78g$9oYSvrlhtUFERMZGZUo)>RJk ztma2@mLBhs#jvSmdjE=>nc;85+t)AGpxecQD+J_xlODg`vs`ZN+NB>E7#R5B65dO{ z78X{bienQ)5|{H$dUXHlX%%et;B>&F>gCe3Kpp2S-a8CzU^giJzUw0{(NEp0000xrWIA literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Radial/RCD/firelock.png b/Resources/Textures/Interface/Radial/RCD/firelock.png new file mode 100644 index 0000000000000000000000000000000000000000..5b581a2aa373e2a7a7953aae0ccab5c8f2c75a3e GIT binary patch literal 637 zcmV-@0)qXCP)R4NtX3V{0nb^t7-Is7>4S@u3Po3`KN1;N5Eq&d`86_O;O zR;zgfa7kV50(X*8tFQ^YxSz3z);AA^^t#%`WW4|Y+9xLffbGLy;5p97j9w2s$008W zLte=X!jP^JWyG}Q3Bd1DBM%o-3H&)XVu!|JBX1+{yt$^a7~;2d93FQ~Tb|PJ+1>TP zf^d{AM*v?oZiG9KtUY!p9J)Tfxad0iF7!smz)#+Y;JucL#njbeG~PJ<|1Aia48UM7 z*lVfRJCXrF>qy7@P6q&R{7pk9H)rl0d~O4PDRbiIS1Bl^$khLOivdwI#<15d6J&QojvNo5)b|Z?%@0jhP%lI zLWB*xw5&V0ACg01qbms8%n()rWsG=`#AQultBwxYyXE`)zTfYg_g>!bCAGG;MlbCW zJ+=!0Jr{5#3Y?#x_iD8oxm=FT%}pN8&T@5l7=Um4`@CCPVtQhNPwVR#hC#Vpj^s>D zO<~(MilQKdU}0e))sX=Ia9Nhob)B6?gPlerSl4wu#82Yf93SUPt%j_3^V6#%Glmb{;S@DttNRkwAP1E#*5M;C2 z?rQ)blgUsl7E?*ihGAe?7KUN8t(_F@I8N`s0$G;-qdwplR3?)-I{}U3N-XAwb8&Go zl>a23u8J^w=ZOB%u{K=4JI3Me(J#RI$@Q&&bPUrpJx$X9s8*{ycy`L?tZP8iG^*7q zj^p49={f@2t9_)?gG?8~_}21BTO-UTgxK=yq-O#G8f_VFH`X3Ri3xc!xNPdf_y$tWo|Cimb*@YJ5Xo(ei$!* z_=^1fMkF7=9jH?(y$rf%p-|w>`xlxWnSXfPCm9(5Aq1+bV%s(c2M374Q7x-aO}gNDm><)Bt_6#DAUF=$lkD#%%2+J!j@6eR_ae z>!Y8%@%GI}bqPZcoU!wfuJ*v$`m_gDcfQxv9$4M^URQYlIe;8M4j>1R1IU4Y6nP)EX>4Tx04R}tkv&MmP!xqvQ%glE3U*L&$WR5rf~bh2RIvyaN?V~-2a}in2u&K2 z6c<1NmzipIj037> z8L4*mUrKu)ve@B2KYqcS*9Bn@jCJJ zrloVJzVjIhC%u0qzJVhK)RE_e5 ztjh}LEzWAW%9{7&FAU|i?Y{ z03*jdDo`Oge(*o|JzKLdIpHRSVnE=N_=^lXd^2>?KY z714cfIhP!Xx4VmC^F8Y>ig6*^6+zKO*^q|?WO*fh&$^R$%bn$wL{VwvDnio8h5ez1 zqHG?U0VGeTGf3X`E6PTx2nvfso6Md8e!9x{w--2`Z(5Z~r~`}(puvi4cNdAoWBv=B zo_~GUO0UPzwZ)-Lrhdj^iX2Oh{Tu3I`zucQXbC`a#s&DEMKBx21*DPN+W{DpMlLWe zwD!TDGf2YO65xcl i@8@K0U|?WifcORW6SO_Bl^qn~_51CdINneh{^%T^eR`f?pwaaCY)gQDYtvFl zDQy6Kuf1NkzVg=A)(uIB8r55Xhkz$B>fS)n??p(c+KX70&I55EB}7+cJsda;5NPjc z0^S0C*LD5#$%*m7%}LZszy&;jsXmG@9cy+K!-{D+1~dY`E#ODqy>Q_vMN#5jk0FLlRyZxPNwdyiV z6J6J_TCE5n?pck0czBp_I9$`f5-^7_zDBC~wT>Ba1$u5hbNQC(ER*-th1xT zIdJYxGMNm;ViD6cqmvWk;kLFmB9RC^Jv}>m3I70oK`}-U<_8$o5{3;F^Fx&C$H1>} zB)1CBWwW7br4q~M^UnJEdVD?~CypOud3iZHmKY7MUfSQ^|BuGd3p@l4LR&E?vI70lrz5S_XvZ%1Sws1N;cHyzKmnA8%|6ziX|`xkF0n&n_%HbNkk;Ude zBoe2q)oQGvp~0zX8cv6UAFf^d*YKUhufF)w%TIKMP8Z_wxcqr;PTokRi;Ig`ESBg* zQrorIxBV9Ax_&gD&$}EB2bD?%tJNAE*Ajcz^R0C9RC8}rbBkr b&|c{;rGF|O5qow*00000NkvXXu0mjf4SBQ| literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Radial/RCD/lv_coil.png b/Resources/Textures/Interface/Radial/RCD/lv_coil.png new file mode 100644 index 0000000000000000000000000000000000000000..f83ed75325b3aeb23335db6ac95d9413a414a80e GIT binary patch literal 850 zcmV-Y1FigtP)EX>4Tx04R}tkv&MmP!xqvQ%glE3U*L&$WR5rf~bh2RIvyaN?V~-2a}in2u&K2 z6c<1NmzipIj037> z8L4*mUrKu)ve@B2KYqcS*9Bn@jCJJ zrloVJzVjIhC%u0qzJVhK)RE_e5 ztjh}LEzWAW%9{7&FAU|i?Y{ z03*jdDo`Oge(*o|JzKLdIpHRSVnE=+ut>5SzMB&TEbHtBSF zPw!3#;Nalk@ZZ6vHlJUfjEVK(s`~2&TL@FmOnL9GAKH4oR51|;86U-@Km`EcCmyrC zZ@rY9h|8kVVq3oHL`i|F?+A%*upPN>E#SCAwdI?Rd}#M^hl)hSd87%6^9auS3kg{6 z0Feh7pCktW2vg4JTv=3_BP1+LIs1D1UM8SET-C#)5AEq@5P>CB9{U?`@)nnDG=g38qEO8iStOy zx%(S7*mjNMC!V%{-e0KBYFK;f^nT7=0_I*oo!*{qqd_DET2I42O+q4|4)5;g6dZB~Qr81bgi9LIK^z(k9VA7%bQ1rxXd#2p(BND_=}-_MNVk?k zh8_WHF&!EQgZ(q4RyuU*&?H;^CC4om8i$x`Q?1%uXb|$Id*Ao_-S>O%_ujiZM<$b@ zmDWLvtu3JC0y<9%j76iBW)i)go_74RfU#(_GCKMkS(ckZUMLh8i$*KI6Vds%&56Vt zTjV1nPZ~Rd<2Et=$k7P-iQGxiAtr? z*)vcq7FhedWQ*7z2;+9kjUPdm)5-UzyLeZI5kdg48(GA=GEDCF95><@DEmT4l7tWf zNs_F++uNV)*8o6|K0q!qSLX`^J^BEUw(#TRO)Elx)vN;9$MgpCIM>ranvVXVYOsF@ zgy3*FS?%i@-po1B8_d%i%(I$RDEmT`eIX8)lL#RYLf~9a^JVg&4*&4}a&t1^a=9?g zJpg3+9j568z*JSXvWr~zcraC!OE`{~bz z_&7Dit@&r%*FvzwQOr&TQu<7te>d{L!n(V=L7zFobcqzT^)saO>iULipja$eZFq5F zAAcZBm(yusnqly5|6U#D4}|dt!f1wpW*AnicCUuJ;L5CrovC?vc-6wv2L~u}0=Q;j z`TW=Fg{s!ZpS>d}77M6q9{@XSp{jirc1P`l9Cg@9Q<9HP*CbuH!tnqA002ovPDHLkV1g9tF*5)F literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Radial/RCD/metal_tile.png b/Resources/Textures/Interface/Radial/RCD/metal_tile.png new file mode 100644 index 0000000000000000000000000000000000000000..14f1ce2bd9d63cc5a257255ebae0adeb4958a546 GIT binary patch literal 297 zcmV+^0oMMBP)hMT|COj%1gaOlFq=cz7HP zGIw~*GNo%Q%M$mh!X=8p7}F97A#ls{558cj;n8)g7hd8RbzOrohG*YHN@?W)bz!3| zxibM<;064y07A&0JD`+;av)%K5pm8(k~O@fgb>1rsA(E=0cn~VUCKE}k|f5p#sW-M zv2CrB47i$rQwRv0z3UTEgpe`7x*${A5nMYnCErcJAsLw3{!LZ_R}R=ZvFR<4O6@ZR vOIvG-VHiLtMNt$8!%$n_wypmHc$^b&xLasC2fjuj00000NkvXXu0mjfypVN- literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Radial/RCD/multicoil.png b/Resources/Textures/Interface/Radial/RCD/multicoil.png new file mode 100644 index 0000000000000000000000000000000000000000..9e32919a7baaff69fd7af50625709fcc08970d35 GIT binary patch literal 976 zcmV;>126oEP)EX>4Tx04R}tkv&MmP!xqvQ%glE3U*L&$WR5rf~bh2RIvyaN?V~-2a}in2u&K2 z6c<1NmzipIj037> z8L4*mUrKu)ve@B2KYqcS*9Bn@jCJJ zrloVJzVjIhC%u0qzJVhK)RE_e5 ztjh}LEzWAW%9{7&FAU|i?Y{ z03*jdDo`Oge(*o|JzKLdIpHRSVnE=BjE6vuy8 z7gN{N2?aq6GIYt*W^p@t$dC`9QKfY6(oN7TT|3`b=+=OO7mpo01Y9r;>X0R1FbNhk zREuL*iDM$JgK}=%$i;HU-fz=;clZAHfA<6igTe5>BeH_e-#=Tp;qb!|0K2>E>UKN~ z6C9`X`@GND`(J&G=DzReRlND~i2~SrSH6?;{a69i>qW8bdAS6f_r_{t+X6t!VigV( zyqyZ&lPkhuvYG?B_{O$Hzd7LTo6?<|I8I5lT9?YU3&{2ed%b{LPaTo%RG70>V(;*0 zJ^|;wv3mS;jmeLzrJQozGXA%idaWpAd!%j(imCK->TN#RMp3uD9(1?B8vO6YBYwGJWCn(sEX>4Tx04R}tkv&MmP!xqvQ%glE3U*L&$WR5rf~bh2RIvyaN?V~-2a}in2u&K2 z6c<1NmzipIj037> z8L4*mUrKu)ve@B2KYqcS*9Bn@jCJJ zrloVJzVjIhC%u0qzJVhK)RE_e5 ztjh}LEzWAW%9{7&FAU|i?Y{ z03*jdDo`Oge(*o|JzKLdIpHRSVnE=@pMqo?bA%z>?!JzJS0bv|s^r|(MKUhx6XgX=Nn$hfP0TL1t z622X5Y4djb-At_OrysAa?LkV;w(_pmzhHgZtC)zD%4RV{=K%nOIJ4OMPJ79TxGWz* ztSF9yC`9MSj*w_;` zK5&GDNy*vn9;oZ5zg&KxX zk(1?Azoj~kzv9-JC;>!{=mz_w$Alkn{F8w6-4_M~HC0syeE(pVpo_ zeVp@_fVCG$$(b>&Z<^O^5FxtgY5373Bm(O2@&2BdCnO{!BoO`q2UEGHuY0KG00000 LNkvXXu0mjff4_KD literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Radial/RCD/plating.png b/Resources/Textures/Interface/Radial/RCD/plating.png new file mode 100644 index 0000000000000000000000000000000000000000..d3a63acc610c5a0b0bdf72e2850f18200f539cf2 GIT binary patch literal 436 zcmV;l0ZaagP)?`jEiRV}hGB>ruBr-M*CpkM2z6b1@4Nvp zGlpS6p663`&uo3j^W1yxoP!VoecuOPQ>SWlyWMa+9%twOvnHaMOxw07iXvW~RDFHU zmtu*oj5W?X5cFcL{cHg5!pBPxoC0QsF$TsM@4YbwS(afOM+hN;axVoSgg{kQN#*jws6#P18W@B%R=JI4lpqIX5w(k6`{1k=7bS6qEyi>-8G^ zFW%CGFw9@XDYcrDn62+E!Lw`Iwtd-g(=@QwMmMJ902f7(+<1KZ0RZfF zyX2>)Lt{fk==*+RF)8I_OiBr6MwVrGJRURWN+~e&lsORvM^T5GrmpKneX!r}7xBQF eO}$~ms`vrJ)ueS~515(&0000 zaB^>EX>4U6ba`-PAZ2)IW&i+q+SONCb}gq4{bv*z0uqR3I0A~bGJ`k#Y*CF*e{H|~ zj9hX-G#!$%-qE|5IThf56K3J#Y>e7`WO&rjwY@0_E|x$V|zOz>zr zB5FCCPBz%s;PS9OOL#I~0iD-V@f5GV1M=a!Z+JRYVxTe|MH-|uXa@cWziL8t;jS#B;cP<`83G@-B93Jd3eeS&^Z zA#!;f4B#Tj7AQjj2>3)nD3Q<1nFxL?07#)ZhsX^GkO&Vb$uWe)E^}d%jc+ooy)2yA zrcs*!gdm$Tu&F@-R*Zu9$*~}Y6uA{eBuSRyq>84HVv>|nPFCbJha9uylyfe*W-Xz_ zA|;hvN~uLF*MJ%*HPu{8tyPtsLXd)&V!vXhaSJUrX{qH_T5Z}9K0S8nspnpL?K*gb zfif}D$fJxpbR)N+QfzUPEp2%#TitXb)@GP-%1krQGV9a}wFA|s=Le|Kff_HQY+t@m z!>r5sWI6(C_(L`G$?MS%0ATsEb!{u z5d8Iuqdg-c3Q3!2qo*!HQS5BL?Q?3!nhYIu(e8HenT{LW*TOPIv&pM9ifM=dglS}h zI1#Up6f{TJY6g=MBx^<7n8jVYH%FuW@~^vbTx)OG2;4s@_8K}HXY#;yxi(qKm${zCwT=$d)$N@n>@2P+Y2Hq%R!JGpp zb=_oT92`?_=;lyY`5e5V%e#-!)TI!lx@hs+S9nCrB(?N~QYl-0JX!G80C!qY5a0@4 zhBa_UXwdFZx}nX>i$?S#P;kt6t`<#cbJke}2~pOzCt9GW*FB_>N$=EmKhpn$`tA?< zL*Jdm$MKc5C+%#2g4tR3RIr2zi#+nuvKFJ2vLAYf%xgu}4i+EG@U2BY>hPY*%_!< zEO0+H;j*AbOE!cyiYcn!I5$I+bCxZ#k|AN2oqcu)A~@fXE$+b_0w0lV zo&78Nr<==}C+EfLHSNkbHkJQ}k?H%ByO#U)CG9`RXyQ&?adQ3xr`dpXA~fqR0004m zX+uL$Nkc;*aB^>EX>4Tx0C=2zkv&MmKpe$iQ$>-Af*C|aGE^rEq9Tq`#UfZJZG~1H zOfLO`CJjl7i=*ILaPVWX>fqw6tAnc`2!4RLx;QDiNQwVT3N2zhIPS;0dyl(!fKV?p z&FYu{G~G6nv8a^Eu1a062thdj$A;7vWj{=l&eMYR+OnKq8)F zhG`RT5YKGd2IqZZkric?_?&p$qze*1a$WKGjdQ_efoFY30SOAKD4`4+5n6RpEF@_^>f;}B z{Rwg@l#p&jMd8^PI;|J|*I1CTHkjPAX;2E`Y-lb3u=_nYc3Gp1 zbME=(n?IXob8Hd=0MNEAvMl>O4P#JBA-mlGz*){Yj4@v9%Lx#MVQ>ko%>gh;I)=-q z+i(*DjIrp+Lw7!AWS0(5wZDQ=2-kwiIzUxUg+@?Hp%h}$6;evSCi>p3k*ouq*3lND z4jB60CAG#tQUYrX& z&5DCC6opTW-lUX3mcu+q-+$c)kt~H)A?9xuGnE-?qPB%H;Mpje96xTnCjoZtdb8Nv z!_(=MhzOkXMFVRsgb>9sAq0%$i1Yb;_q}><0ukYOJfiD5D5bK-LJX0%S{D*GMT9tG5VH{8L{vr+RlA?f^vq#=ciF zJz$)EdE9(9wILBr2HyM40M0oO(bNg!IIah<*8U+UqS>HXYGG?F0ALt~>3-D`2q7kV z0Mm7g;tz022}G3LFRIc8;=MU0M5CGbHIBK##nY6 zUJRn^^}2WqVM}`6z|&gc6|Y)HoMwC3X;+Q0000$WMY{4Pnz--^ZPIm{kTgYu)`~hp2fDJ0rofCs*!U7Q zY`*W!y#Ensxm=>nve0tf1zHzi|Gk_{COKmawr$q}QA#0-_Lxo|NlSn+hHkfuLmWeR z-c4|MIw9J`7>)+|Ct%w)4snc!ejnj#1@1Uk!P6wc=k5gGALHryMPC2_gy-QS4AJRy zz!*br2qysR^$xy2HlKk@Ij)N=&tWqLrIe9C5QLR*?G%t<_qy;#VrT-dUBDDxtH3qz z+61nJm!`mVU09X{BEok`0)imKa5N~)`K7kot-e5#Bsd z%}W$v9LGP;%c4&D7DjF7HIgm~=Y zmf4GCMQrLqWv1D#y6f)v%=2{6UMOd4cLF>3z0LERdA^@{elIhysZDLLgkRv$$@7VS zX>|W?fA@OpmY;dc=_?2+5mF-27*hVA)*1zbOmp>G2s||A+WRO0ppZ%+q(nOoKw>=z zs~EMmEY9q2B<9!%Awa{#%sgYy-_WwVnf8WS0Fu-5Bq!g|7H=SA8tkm8q_85HPG`CE z;sb`(z8<~+)u!TDM+3JWOo3KJBN6bt)u0_?HkDyGmHFw33O*(00C2}=koi2)w77V% znVX5p(g6UJ=V2Lw*wT9v1A`^yy!+^JGFuz*q=%bHmkyB5dpMCW0EwYN_FcSoy%c~% zU+;}QXRorgB1$9@^}Ww1wn^&aeBkQOWS5J^eE~v3P+MJzVVQvdzAWWYwp}`a1cpb( z5dNd$uk`wLvb+-^|2d!`8nOb{fME($ku>@`s1^5n?vD1HVyLh8Mk&T8&Rt+)A;VJ6Wo0>6IzT}Q zW*2j~*&Hvk5bwGCTZbB^2?i((>|a{$Z9b2-L*$euTx6X40&Iy!=^sgP>A)_k92>M? zI=#SRuE0cciq4KU>bE-p%%rnCdG?CVjy4Pdb=$Tux0uDWECxnX5OvD<9J>XYW81hr zoWxWT*7CS46;8^LqEe*<6El4t%H&Twm{(>$m@X zUH@G-un-IJ9|xIjAtf#I5CAyR^57rtf+$(IJ=vxEhpxrn-NUR2AcRm&i2wj}b(%Rd z3eCyUZUTVVm#u_v$PEA(9qKy}H9$&Q=AlQP-V2^r;-TTN7={^)5sQ>_Fq)!x9WNHC-o8ZXZpcw)&0Nqp!A&x{M1fD_CP7XzJ?DNh#}!W?i2ZAb9mRwtwHwdAZ!;_&8z5j&16Acb58^g?SMi|E7*W{#i~cc}$_?j&e+r83dRH zWi){h5xDbYwlzgs`&h`}mSlNS~5KMod1CSXjzy&zvPMJ-0(hO?t>mI5FLi zuT?y^r=*Jw&DLGdKB48LIv4@&FE&Hx<-P=L` p97^rZ<>+d?aA4sNun_;t_zU$3&3t!sy?g)w002ovPDHLkV1f(}F3A7@ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Radial/RCD/windows_and_grilles.png b/Resources/Textures/Interface/Radial/RCD/windows_and_grilles.png new file mode 100644 index 0000000000000000000000000000000000000000..e51ab094233f2f46c2da73f27f0ab409d4f0abea GIT binary patch literal 1205 zcmV;m1WNmfP)Y}j6o#KWo*6ri?HSt>w~ZS56_KV%NN7t3wIBpYRV4(K%1`JX7Oc8~C1S~jU%{qQ zK@~_<7bWe`R1g9wO&bV-B#k{2&)A8-J;Nd&O+sARUC>R>?#!KY=e_5==e=jd&6_uQ zo+j~}?FE464nW@P;l+y=gV*2v0Nb`(1{#LZ(fXswajssyD%t|jKYEsf?_8oQn?*~d zP<@{U0U;q#uaxmTmrPF&G221YG!#X_CqP0_Yc}w_JbKC?QYfOUDxr8B!!X*((R4+M*j$KOj?&W*kdK)sPB2uGQnony+WB5b>5wps#+ z1~tM#f!~UUtlaFhsU_m97K@|~9Gp1hVmxwRuv2^B;eH0pRrM zQ#<@Zp|Hc((!rO^2&99L?W@npP0C}!7&HDDH{g;g98)_g{_ZmW?~b}W+tX5rvMO=grs(nI&gsU zv*H#yOf z4j4w7uDC`#p;0cZJ+-;vfZJTb}p;YW%KZ%f^TJznUh$<=x z+aXMYVzB^1>UxVoU>q8FCLPc=PChs?Y6U!l4ul8@fb84@6JTKMBvD1>)>ofh zk18tJg{2+-^yJi*fA;(Zq*{e!MB(1u3A0hHbgl!nK#*UnqK3QZQocFkhjXk{Wdgqm_^`oj zfVgPllu8s!CH!sa^Z^3!%WH^`#KgqUIBRr157e6h|1`q9b>ff}QyOO9{vKS{WpH@R zx^;WpJl5CCNN+dChexgPJC?be%`34PY;4UY8g=W#BF5E6obMgV0(Xo`ea_u>8z zT>0p7do$sgp~L)f|27L7HO;y%)ou6vUh{z8V%^zTKQnZ={S3VLF?j*t|FnMrHpwI= T(z-m800000NkvXXu0mjf=vzYl literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Radial/back_hover.png b/Resources/Textures/Interface/Radial/back_hover.png new file mode 100644 index 0000000000000000000000000000000000000000..7378a60fef4f78362e422ba5659a1497a87fb5a3 GIT binary patch literal 495 zcmVfN`NmvpMPcmu$Y=bipvZDB&j-L-&_Pd zZwFPafr$7>1`yPneMi@n2)ErIu=#q6dn3tVuIGdb~DsV_AVeI5K%xx&@~0C`NR&-Kt%FtKCyL8L8CXcVrmuFh8(#NB1r6I zR)&=jLKNGEtbnd5KyT;(K%+ObbWOqLFWMlEy^8`IApnFmU~}}m7+W|2&i86QF##lN z07N8r#*VYyA8t}Wx002ovPDHLkV1lJz)-?bC literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Radial/back_normal.png b/Resources/Textures/Interface/Radial/back_normal.png new file mode 100644 index 0000000000000000000000000000000000000000..2c4a20048c6b4f75a7e8c7415b01e5766c7f4fef GIT binary patch literal 525 zcmV+o0`mQdP)As=6vzK9pJDl*w=4w{UV0tcz1ub+{=6gcH;+AYC-j!KwHO-24WeoLmI8 z$brEi4qftWNX0}9bZ8y~l6U{h{oc#FcjRt5o#HR;9)D~ZKn9QjXh}rna%E>2d92q< z02sx{Ur0M1zvpfSpv3{eF!FeMdR$!6d*1$}Etf01IEYvPTKsrC^Z-DqL)?@e0BG7n zljhz8uwE}=7Y zc-|hVwqnoQH-j^wees1qk*Cv&$K&^0{~q8Qbm`z{o`@+0 P00000NkvXXu0mjfftc^@ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Radial/button_hover.png b/Resources/Textures/Interface/Radial/button_hover.png new file mode 100644 index 0000000000000000000000000000000000000000..49885a26c37de185dd882df53e6cdf4fea744873 GIT binary patch literal 211 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJS)MMAArXg@6C_?X2+mYiQ#0+A zo3^j&s}A>JMuXFzZ>3$l^2swaQ=>1zaav2{z8$+i3F_+f>*h{BojseioTZIf0tn2` zzN$EK{=C2N{rp*1Kc3KE>%4pS3j3^P6KYxF3FM83J;26GS!GbRxVf&sxe_sFP!9iQg6hj{N znm<1#uFGs-?bgoBdieW$zNDLTf(Z*IQP6$>DEl=R679^D-K+w?{pp#{#|}Wxs$F`eiLT0w_6z#d-q#&B z(Lk5l`?_PaU7$v>nuI2`>jB19W3>;awxhUD?WXQ%-@QtNWw}MlfVgS^h?4Zl#E(zQ j$aWO}`8sxRaB%nrkAA6lY1Zx400000NkvXXu0mjfgC?>Q literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Radial/close_normal.png b/Resources/Textures/Interface/Radial/close_normal.png new file mode 100644 index 0000000000000000000000000000000000000000..99417f28295d3d2693f15493944818ffc2f036e8 GIT binary patch literal 391 zcmV;20eJq2P)I(57Hhkii}DTN(@<^A#TT6&V8^@>>}akcneK;u2#>m&g^umein5)qz0R zC%vcB={+DIAmG0vav^2e`jfMUpxt#A`ZF|pLg988|ITnlOor!b0Da#X`NizXZz;Y@ lsJ7#!i)yazI3OS(;2W3Ut002ovPDHLkV1g--t;7HT literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/VerbIcons/paint.svg b/Resources/Textures/Interface/VerbIcons/paint.svg deleted file mode 100644 index 78a56e3570..0000000000 --- a/Resources/Textures/Interface/VerbIcons/paint.svg +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - diff --git a/Resources/Textures/Interface/VerbIcons/paint.svg.192dpi.png.yml b/Resources/Textures/Interface/VerbIcons/paint.svg.192dpi.png.yml deleted file mode 100644 index 5c43e23305..0000000000 --- a/Resources/Textures/Interface/VerbIcons/paint.svg.192dpi.png.yml +++ /dev/null @@ -1,2 +0,0 @@ -sample: - filter: true diff --git a/Resources/Textures/Objects/Consumable/Drinks/arnoldpalmer.rsi/icon.png b/Resources/Textures/Objects/Consumable/Drinks/arnoldpalmer.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..81261d0f54f589b5acb8b36b90ae2edf528fd3bd GIT binary patch literal 4790 zcmeHLc~BH*7H>h0Fbm72vYu^IvXV{D^z<}ybQln4I7S^r80A=9>FMslUYUdLh8gfG zaHFdxY&;_b6OXv=YP_&CRzyX>;FhAINj7TKL|qgW)Lj*g(d;)ffKZ#NEo;~Rn5v%c ze&2h)_ulWl_tku}EF(QNIB0kf1VO=uG<_zx!|p54AAAdCWe>rvsmzokW>QYr!P_ld zAq$J84i;uzoCShh7p)o7LK@+~=QktYuJDx^FIBmEiLOK&Zx`B<}UdD`_QxFYd@@86MoN`Fvfpj+{tyTSJvrr zc31FEPPU9s*xcHB%Pffwj-EJ-k0QqWX2{yI(Nsr!&;#G-j7P1`)$>}uI`A2q5^ml$ zGT*aWQBoxqjvke#YUeB8R0O+yC8n z&E~I;9nZ}U$W99V5h^NiWQr@pfBGOYugT^3_D{~P(aw9&rd)RWg$Q3$3x00d!SyG1 zFE7syjG7o)zp-hGwkr2jgE0ScWAon+jX(3xgsz*nvV&rL=Oab$wl7JpONu|lwbyhl zYy9-B*ruCJtNmxa|77Kz+LQL0$sv+>MIm$kUrm&G@0Z86>^Rtd?EUu>0^4~Cg0#8gCHN-@XowOrm`7)xTS^MLb%EV-8)yyFn z|JFwTA*-$j{IvM$h!>m(>CK z4uawnT@H$#%Zjj>E#Pcg7Cc11ctznSFgrImA z2>`6DNWm^^p-muNTEv4(f@il_hQJ;bajq80F=oIzJI}&|l#pU*vWqLhk%S;Po@Xp% zraq+`0=#LFIilzwWiqGJDRnBOcD_I+*Jv~{442_J3N%om)Fx6c)Fwo`A-ouRR-k## zA#!#b?8c|I1=w~ei z6PQw2CM(#Bd74cwVQpe`UkHZowRaTrg`RX6TE-T#R-h^XukwB_Qw_$9UJEw`1)SC4 zu>xfG(-b+&OS1aK=3eon(>D-c-izB$yC-*#GSD&_Nxhvec86!sYZ149lCjeqLwX+7 zxEx~{21jv z0-y?99;d?OYFt6fJx~lyrr3Ea1&k;TgXIO#i*8goCRGp~b9Z4#kPe`h za(5~K@W??nq>g7P(axLf_ChV0Pz)tfdP-ygD25XxhLdu&Nsg1ahQyR8 z7Dr-z^z961DgAHS?(u=+y+u#s1mM5aBl6Bv7F*4Fna;hFW1s#MI{&j{?2_$bg(sBg|l0>+#K~Qx~ z6c7f824ix-EuZkPQGt0A&Vj!|1}!$|lT0~{9cz!K`y_=fJ$hkrKG9UU^z1PBKuk>2 zN2wD=L`Y`WpKdrk>F(W6zx+eM{i(+!_kCg_QzTnr+UhTjl2l$FEa_}G=gRt>#d-AU zb4%OCKO!&Yov2&39W{m+emm4JzgBytx;!_i{>Fn6pS>o@xuB7=4v+l;I+(b;Xj@B1 zz3|H#;p(D6PpVJ1i}QADy*>Qb@BQ#?*SfZtwFgFCNw|1@!zLgP$$1*x!tUR=#vl#* z`c3w+N*a7iub*~yTI;Z>^G-)Y>SyVZ7r)VN;ImQpT8^& ze@AJBs&BXP`As|gpw{{?#>8A{-q-M%`cXl7AToW)^X$P(&7m_lH(qYLpcq57jHqw# zoPpJq?rCx4U#p1d2)_R!?CbR5kLu}&itT3Ihv5sF@`YX3PC-b6bI$e09~^uhcjw_h z0x(4HyW&<(xoc=kE%ffjm4BY`e%s83szuGTAHVK%42qWcohZI^?9t&_J5841vO9r8 dr|H9>#FI5kRad+Anm~mhLvp%)*Tnpae*@Dd%6k9+ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Consumable/Drinks/arnoldpalmer.rsi/meta.json b/Resources/Textures/Objects/Consumable/Drinks/arnoldpalmer.rsi/meta.json new file mode 100644 index 0000000000..f76e611841 --- /dev/null +++ b/Resources/Textures/Objects/Consumable/Drinks/arnoldpalmer.rsi/meta.json @@ -0,0 +1,14 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "Modified from https://github.com/discordia-space/CEV-Eris/raw/f7aa28fd4b4d0386c3393d829681ebca526f1d2d/icons/obj/drinks.dmi", + "states": [ + { + "name": "icon" + } + ] +} diff --git a/Resources/Textures/Objects/Consumable/Drinks/bluehawaiian.rsi/icon.png b/Resources/Textures/Objects/Consumable/Drinks/bluehawaiian.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..d192a884616ee9ae73c071829e15f2a0efaa0db6 GIT binary patch literal 4796 zcmeHLX;c(f7A|BJgBpa0d(mhHjJ+>(mo&)UjW!~nEE1)ys6a4ri%|hVqt3XY0dyF{C>rKZxw+rT#KI(934Xd2CCpq`G{d*Q$*A)k!Ym{`mryh%#^YYm_ z&lMr1Up8%K9YSpk?(6+~G)u~>SJYK@@&aF#h41TW^?RP&o;B~+@jH!p0UP#(UKFko zWGkxTJ^VuxHd>A6E zMjeQpyU#E&?QF!Kf7wUNKadw(8PVogf$U6pVJn-u#bt8n>A&2*-6X$ux-l-sKE{9I zODN5tjid^l`**m+H<+|HHXD0q8oQyram1nPldPjJaDK`?vGd%~yia2s+yW+^`n+M0 zcvsx{Gx}9G>zi6?JTLvzxA(!r7{~XmSJBcocB~7o_4lbEJ4$+U>yOOyYIxAF)$YTB ze-}QkI;SaFIDVWDHx<9q(}2pqzS^jpe5`7(^QDQQE=%{Xa(_^DCS${~_=;n{il2`Q zv{lWiPcOzKiDRW@a6rfm*J#u|>~Kh4F0Zpm{BnQ3Uoc}=f-6fm?{hoXE&s6Z&$)H8 zxUs{_+snm1b7g8DHr?TuF%|1nAJ1wxJhpk_XB`vYv@&IkzO>96iNEXM)@sN2YJPF8 zeL@%HvA7zSbB=b={7k%OS}S#&On0Vij^%wFpY|V;u<-@FsZbl>LAF+&!k1M6oP`~gpyQ? zY27t-G?>K2v>3jOCDR5HNu(rGM?__YM`M{Omclq)_a&C1~7sMJ*FeI6sb|eW=vGBNvFg# z8j!=U{ZnaWvLSf2evk#g2h)UVnQR7&sZudVTIi`@0{|Ix=yxsj(V$0}k%V58uEU66 z1EHooMnd4&ki9ltmud+I$CyMap#rLUuqykFB}1jMh#?Cz1xiw-wO9eN-_WE;#V}cK z_-2+^!WroZFdxEwL;H2?7GsfP zvFUPDK;Rq^MtHM@BOn&*NKln%>PWB5P&k0%vjiLrmymj}euiagpr@jUw1LsUFqO146AWA00zt8X5cH^lz%70PtN{_0 zgsPPU*gpmf_VqmZJH^1lP@K*7=F&MrJ_i(ow}LLj6d0W+;t7S`e2k3>1~NE=uGc6i zBdR0(m4HXU6(~>(SFq<`s=VIx#+XEy^8hHLvpDo&%D6P!v=t8W1$_M@ufaV0kxRhv=pt{$?2n1U88ip6$5Xj zJX&4aWelCFjgyx(?ig>N#@%M zDlTyYllGKU7Ht1;jI+~3_Y;X~B?OI0mInDp$JTdlUo3G!-M%aB-JSNm;wC>bpo12$ zGyO}3^qya}r|HR0<%wgmcUbz07@RY|@hrdmX zE3WBVeXHF+VVj|4%5~&Iw}9K-Q+uiQR__I9Cb;@@+uGtUrk6VA7Bl~<2%dE5yCmkO zrkd*5we`YT8}41*5OATQ8ah%9op-#I&#FP!XZw8X(_rvCJ9qlJ%gsf{iyZkY`)VDJ zow47wX#Sp4I{dR8lUFE@ZVjDwIr{ppn3Vfj1z~D@chk=y=!A{x(gn2At~;saRgb4R zo$I&i(fd8UG2Zo^67H0q`ImJaMQ!m}S&2Mf(}S>UTc3Kj?{3nQtG9`4q53OJR4pHK z=cXXvr+-q{eDzLyx0`C$+P+SwYc5>V+54;cCuYe$ z@+-D(zQ6u{(^R}NyY=`4tj_f_s9^8aLy`GKEsaOqAVK65&*rm|v0kqEIqof2evEgg z&!K$)O$#u{E_D3e4od64TOuK5Z(A0T%ngbU^Q_prEdcRwKhW?g*D2wuxU#YHPVV-O z!X5Y4CWlks{Am_da+rEVR=0hvkiOUvx9miS+Yg%#9>ydAo-R{b>RR^{mfP&KEt}^~ zyNDG0xF}$I?~0?3GM?>udbC3=DssA&b%%Ajz8>5B((0rD3NC&(<{&6UNE#d-^i@D& G_J05u#{S9x literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Consumable/Drinks/bluehawaiian.rsi/meta.json b/Resources/Textures/Objects/Consumable/Drinks/bluehawaiian.rsi/meta.json new file mode 100644 index 0000000000..f76e611841 --- /dev/null +++ b/Resources/Textures/Objects/Consumable/Drinks/bluehawaiian.rsi/meta.json @@ -0,0 +1,14 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "Modified from https://github.com/discordia-space/CEV-Eris/raw/f7aa28fd4b4d0386c3393d829681ebca526f1d2d/icons/obj/drinks.dmi", + "states": [ + { + "name": "icon" + } + ] +} diff --git a/Resources/Textures/Objects/Consumable/Drinks/coconutrum.rsi/icon.png b/Resources/Textures/Objects/Consumable/Drinks/coconutrum.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..4adab5cb6e6b935cc3878d2c6e533abe8fe82dee GIT binary patch literal 4451 zcmeHLdsGzH86S|BYe-SC0Z-I%r4bCXJNtm$9a#`rU{|xS!nQmPIWjwQ7e@BQ&ak_n zz$sW;kYY5g4-Tdnv{I{)O3blUjLOR#lF-K5w2&xCY<&f^O(GJk_RjJ&%{e`s)BMMt zGdnZ){=VP$eZTL!_w3yoLt1LEV5tB>kYJrwlL7B2e+31=Z?>%LOL)6fX3XX?NH^+m z+Rcmwpj@c~puoeJ5yaDPH6$+TK!eVGQ5)}*W4f>UwZ7o%>iD-?A{Gw}*S*;KzTl6K zE7Z6Dg6eept~%d2uq^jY?N=8(O|G=#2iHbK^c^J*R(a-EP>1(^_U}#UM=zc^mfG8O zd3dFz%^-g?)Eilma<`>x7rut{3tum&Cb~b(v$WT@4#jnJA4=K64kV1;8Q2>A_RuC^GL>;*IgmSmkkF$e_dFAq&B(L&@VVa?9cn!U%zxu=yRzTPY(|E zn66&z%E=1MN(^~~6uTT5-0nqB_J!tldK@3^a*r%`-$M@NfMb7KJkR)^^n;o+`+HB; z{x~ZrY<b%+cYQW2{JluWvRIj~p7u^&{5JrY4hjn4x{T+mMt-oD>wW$rM5;s)T4gXT%V9EI*_*n zcSbh_EZOr};FId>A2)Q}j#5O029|BMj8V@AeeQc=hqZFWfa|W`{e*d0xjmbUeA!ldmuD^yJMUjrWU~*IH^w75ceacM zD3yLMZ1_d{@IQyo4_|w%zA}6-P?qWZdGJ^HS76h*7}#9d`j-gGZWWQV-2_A)s{?i& zg2W|w93)i)IMf6R7@Jyn@9f(`l%dtatQbA6cO-#AMqB0tnPq84s;r1o(ZYmyL7azx z1XjS2sK;utv4lr0^zst$nI9GlQ7?omQVX;71~kd;1gKmj7vWg4hjB@T@d7l?Nt=lb zP09oXd{YYxInF_d#csD-hy*w3toZ(#_I4| zL9w4ga*TOetfyk*XT0gm34M#Br=SQH3LkJ$Eq-u z!X(3RnM$RIl>)O|9^<8=DI&%0w34u#jFl_^Vu!83JHZQ1BpP&Tp;UxVj~FZ@XNCrF z4KOy^?q;W_jEogzawM;(M1d=%u`(HqTPl+&71N*}0VfN4k!O|QBAMJf!xx5t=|E{o zzEdHAcN}IzBsl@e*_}qa-J%xqL7}|m)U+NhD4OI*4aosWic94LE+r&NBd#Q5v4kuJ z!(#}12Hs9H=FE>063;HnWUJBhWRQ;h0Lt{20Lpv zb8gZJ5(}V?P%GG=Uaio`iBd&*Rhx>&T?qI(K*=y%icL!vD-=&8E9Q5M$!z1q|D{Kq z7cgUsfp+6#aO;9Qp?GR5oX`vU{w_Zgb@(n_py-^FS?N0`*PL9lQeal#x$c^iYgP)( z3Ov_c|2Me=(}yWwgTH{>@Tl}BqCW{9vjR*TQ#D8`QiyEbQyt9z6ENSQ&0!H_!D9aM zK^hvv;9wx9(X7q z8NS?1fzfV=?H(KJI{9jz^m2WZZ7GE2w_JZ~Y~RU9@r&^>Mc44S)v=Ft>GSI9jD7wQ z{vW0Xyr!tEDBs(8x4ZJAcjY^Mvt6C5(>L7TRkaBhq+E>T2@s?v-Ow7PHC8~q5M6Sb K=8g6FRsR9yS6zSr literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Consumable/Drinks/coconutrum.rsi/meta.json b/Resources/Textures/Objects/Consumable/Drinks/coconutrum.rsi/meta.json new file mode 100644 index 0000000000..f76e611841 --- /dev/null +++ b/Resources/Textures/Objects/Consumable/Drinks/coconutrum.rsi/meta.json @@ -0,0 +1,14 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "Modified from https://github.com/discordia-space/CEV-Eris/raw/f7aa28fd4b4d0386c3393d829681ebca526f1d2d/icons/obj/drinks.dmi", + "states": [ + { + "name": "icon" + } + ] +} diff --git a/Resources/Textures/Objects/Consumable/Drinks/coconutwater.rsi/icon.png b/Resources/Textures/Objects/Consumable/Drinks/coconutwater.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a270180dcd4e8dc61cd9fc37ae61a2f98118fb46 GIT binary patch literal 4497 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 PW`NkN8!ac-71#U+x9KO& literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Consumable/Drinks/cosmopolitan.rsi/meta.json b/Resources/Textures/Objects/Consumable/Drinks/cosmopolitan.rsi/meta.json new file mode 100644 index 0000000000..f76e611841 --- /dev/null +++ b/Resources/Textures/Objects/Consumable/Drinks/cosmopolitan.rsi/meta.json @@ -0,0 +1,14 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "Modified from https://github.com/discordia-space/CEV-Eris/raw/f7aa28fd4b4d0386c3393d829681ebca526f1d2d/icons/obj/drinks.dmi", + "states": [ + { + "name": "icon" + } + ] +} diff --git a/Resources/Textures/Clothing/Head/Misc/flower-crown.rsi/icon.png b/Resources/Textures/Objects/Consumable/Drinks/painkiller.rsi/icon.png similarity index 53% rename from Resources/Textures/Clothing/Head/Misc/flower-crown.rsi/icon.png rename to Resources/Textures/Objects/Consumable/Drinks/painkiller.rsi/icon.png index e1e80b9293d449cd5f31588a33d99fcafc8e8f20..caa81b36f0adb1d9dbc5c964dab994c504eea8b1 100644 GIT binary patch delta 1618 zcmZvaX;c#j6om&8vfzd^vUr4sfK-&hNixYyVj}{H5Rpwn0a0PHU?XH9!~`iA#nuHu zg|woAEhyW1b zFlUP5wCgZERjpAa%Tr}k?KZWHD$9^313*THA~I@jBb78`p{&TUjX@7=td}C~BNj@> zh1N~9hL2v5%Vx&5mp20ogjKNVgA{_`dEK4{cei}Mi%=CL)|~h_z;a&0QnbzgiTC8h_WPvAS>ug8 zHHUW(DQ1Ouchsp@OPy3ZnhVU?-fmUh9%~QHDrVjzJB_L$i1(eJ=;J-s*so#(fXyy> zP*9{WDCl29RvRVR1-y{PRg0Puqs!MVJ*jg@Yl%EQc#?LY+%8w}O=O30FaBMFPQ6ZB z;P|$PvfiAbetb}Gao4{BPQ=S99=(GTeb2bRul7jm*SR}mNiKm7*GtW7c}L@KH>78E zHa54_FS#?i($d=(YwwNAqNU~a?-pDRc)woWUt-zUc+S_y+-o)xHXeFiFi_R1DhZuC z>wRXb^ud@J6QBRFN#k5yb;9wE!6BFub1KWDx2j>={_6Fn>fd;ivx4jtiyOBdlY}IZ zg=N&h)ou$!n8%v0R_E@6hnjiQrw;fF{Elu|0BL+n2@49J6W{K7(s`_@-v{xb5Hk}~ zrzDF=gSMvK3d6fU>jv<@`r~5PHz%gprhid}aM$;cT-phKl`D>2CTyU!QW#j&^ssYL}CuR1Ia9tOVj;ZkZ&YDBgR`r&oqYhOZ8Hz2Q9=enn(PYx3tz zBt58pZkK6e+(U$n8;MJeHAKCE&cP5&B85OY#zsLH;fO($!xn=un}Hx4CKE#-3C*5L zrDiD9VPRaMGF^))B{CtON3(YPxjCPpDTgm6Fx9m7DF#X>+1iz5N)$#60o!Z0Z; zX8lJZLL=WSS7NDrm1L{JXd=z?l1e4X9I^E>%$Crt3=AfSC8H1s!ze0)Fb*u1VMZa@ z-S`X1!#7s0l&bXUe+dQ)!y>sNxk47L#T05DjgCMlgAK7*D2L8qu<6F-WLF#5C?-b* zz+8yIrK2JU;ldni0YWS;1pSM}4O2q?-Ajbbp8^_6eypmCjfk(vc@F>p1aW9EAMggKfa^fd!6~Eu9d|>Yt>bLEWA2c;8~|(=3;6+}xW=Kw*HS1^ z4$b~!>^cXJ9FkK`xmqX27DnALTz|=Jh3ALQ-bu;9Umyjdb24&#&PhColk?`L^2tlj z%;$UFdM5j9Y^@TRdOj4_;^wuttFq<;%URtsI#cyxg^I9ywkxA7;zE>2L79lyY}nBD z@PaPv+7CmoDY~rOYjy=r{cUyWeYV1Jn|yZKw5*c%QSGb8MK||%S)TU~Fz)`?Y!ZNN zFDq`O=O^s1$Un)RNpdUgCys^r$Ekk5v84uIzC}RX^mda&{>e+55)%AZRt$XmaH8Y) zY<*B?cmmS7)w;}8&uJOacfW4E^435eC|!tq%J-}PJmT)7?lY5oKiVL{=I%XL;4<%E z(q`Q0F-H=*=n8Fo;V$QA0pERlsjE&)cs1aO58#Isy1>#m6JDW3cTQJv3S*pwwV%un zq6E8mwr9*ca@!x*>3jQl#tx?VoAUyG{Oc^%#89;SX%acLHq3E*P@&UE7rWZftSr2U zdt<_n`0b+rO?w5bgn?q;8dc?S$vG-Npg8J14}0AbO45rKxb8BJc%IGox{-!Y!HK|6 z?nUKES~lW)cL_sd8D-@=@s^48(SWN?vyHoxsr*y_O%s s$4m6_@pZ*=*IUz+-mBy}lZn&#(WT4FhOeH|SicGo3c~r7fk`=k0A_umMF0Q* delta 2074 zcmZuxc{J1w7yg+n!+eTtV{J&bzR_=fvzU>68RWGO85FbDh)hgF#GqtJq$%5*B#CT= z@RE}Dk|jjK8+m0XsVL%`-tT-gEB#uKU#B{7!+mUNps*=Sho1 zal^ydoDdd@cY@18v7$I^0El`w@8h2_L4^NYF=9)LrMI;&Avk=ny>MK2g+EXge6!qt z8C&jKlj;IQ0DG$h8yR0zwDfixR-Cw5q7fC|aY-F+SzTISuK9hgD|vC($<{o#E{UfX zgD%eYws&mimX^i~jvT)FMc>+DA!&nO^wIx*E4&%s-f*~gS(y@M{cr#_0()0qRZM9t zZ0sJucRq7nkM3QlZN;yRG`7Wf6*=VQoY$DLUxlo`wL7W7E!X}<1`|3XH{Tj*e9kJo z;+AAz_M_Zsh*M2-Z6pg+ef_`KHeFqe~AMmjjCQ&JP`+;2FY zOYA3YRRb~0`$AB;QthN^dccY2Pxma6+w{Ek&a+hY=cub3L_zQ@rsrly(TVN8d8l-L zz{&cOTN`pU0y{=hH4vNi6`z@c#?EBD5n$TSMEAyB8e zCvzW4zZ*t=5;cJuY>{|i?_LF-5r+f#?IkwJ7Pvo$e&6kLTM*u!g}yvp%~y|bYY-y=jXTX<6m z8&T08V0Jh9Sj5UqRk)I(OI3;ASHB}ix(88BV~dh!`b{IJn~uzs_^%v{QHK|1C1*e( zt7XM5S0E2db{-+Ne^42Hy62_yerm(XH*a7?$`^E!$~ zR&97YR~-J>)gHzje{XLbI(0u~IA++wCUk*u_;Sht>K_Hs@Y-#&?dmZ@$s>0$KZD0A z#v8AOS#Nq-zs_3PJAdBAadb+Ps&c4#!k{5dAS)dZJBgCb;)ME8a^6hBD+i#Quc}xl z{rwdQo5b(Pm2wZFCNkF{)0wbT^Adj=;h zwCm3kGVAs!DGqf{@OxHe`WCPCKBdTZptu7$!32c{PQ>xh1ehM95|gp(9(g{ZIyG2u zMn>g+!G~cF@BO>YYpr1AMaH%hTk1XQ_Vv&^GCq**)U$>WGu$0DzD42ZGA5LkQ{pOj zs-dS&$0j7n%2(oChaQ#9XeKGF-PEg4r+!KD^E*4*d(XO4%iVb!;uEZXSTj+H+tpHx zN;o22y)>Vm`hG{RzACF{#GF|}y#7=W;ZQY%0ZU6TBP)$3 zftHVT&^mm%V=3+h|4vCG1}mkxYxl`indS!kkZ@7Eps3=|RzEuWOh^=y74X76d0E>x za}@m^M{$QUBUiK{7Xd->LkgC-wJe`?T_~;nyT4L%puCM-ERt+TzhR-DW*C)mD`s^y zT4j>@=j4Wl{H`$QfxcW9G;%w|B&E~@U9fC%?BXTeq}9t&udX7tTZSLte?J%Tnr7LR zu9o-3?AS$L1ODydwn}E%V}aLWjQtyf_l3u)V=YgpReip*SJsopS{iC!9nZIQq{}^UC|Xdu&3cC z2F6>2bu@jOi6bMUDVN#p9F{1&Nz1q)z{TQk!!L-FeL z9>w?-?2j87-2%jy%BFku-;VtNm}M1xvRp1aUD+^ZWPGHk^Un?Q-kC)yqw?^yvDAZa z>*8V2VnQQvBjJxNppYUSsY@g>SR@d`M&t2V92!SwD z)Fq6`VV|(0@mQi(5c)rC;YG=0T_%$V5olN@nux=TMugY|G@ZZ}S;v#;I1H;y9pSn3l&tZeT$W{1n&8kYitX&QKI8(}K3Icii^Q zp5BZ+eq*!XTKXm}`0$7LR%ayA-uW}qV%aru@5lEsK9c&zl4mMfkw_j9DP?Tj_|nEE l2=#kl(S)9T?oEdi) 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 OKoW7V|B;!Cmj4b0zCE`9 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Consumable/Drinks/royrogers.rsi/meta.json b/Resources/Textures/Objects/Consumable/Drinks/royrogers.rsi/meta.json new file mode 100644 index 0000000000..d16d731d7f --- /dev/null +++ b/Resources/Textures/Objects/Consumable/Drinks/royrogers.rsi/meta.json @@ -0,0 +1,22 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Modified from https://github.com/discordia-space/CEV-Eris/raw/f7aa28fd4b4d0386c3393d829681ebca526f1d2d/icons/obj/drinks.dmi", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon", + "delays": [ + [ + 1, + 1, + 1, + 1 + ] + ] + } + ] +} diff --git a/Resources/Textures/Objects/Consumable/Drinks/shirleytemple.rsi/icon.png b/Resources/Textures/Objects/Consumable/Drinks/shirleytemple.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..88fdd5e79b971275c4012ee5afd12513bc377fb6 GIT binary patch literal 929 zcmV;S177@zP)EX>4Tx04R}tkv&MmKpe$iQ>9WWqIM8*$WWc^q9Tr^ibb$c+6t{Ym|Xe=O&XFE z7e~Rh;NZt%)xpJCR|i)?5c~jfc5qU3krMxx6k5c1aNLh~_a1le0HIlBs@W3*RLwHd ziMW`{uZn?J2pB>Tz@WrTJ(*d|!gGAx!^hXVD9`df_vh$W3MK=5B5{oAhDE$VJiBS> zocD>ttSl+S=fsl+U6A;Z>$1yloJ$T1JTq)$)APh(VzJc4au>6*p%Tv!M-)|~d?Dwu z!g-6cTCKD8J^2em1#Kn6b(&*HUG?f@fCx@1U>T3B0I5-3* zN|e3s@$SCv-u^w)?(YXPQ*w>*4?Up(000JJOGiWiuK*wbAP5)L5C8xG32;bRa{vGf z6951U69E94oEQKA00(qQO+^Rj0ul`cIh?r=B>(^cpGibPR9M69l)q~fQ5?iS^Dgnw zBU*0|%d}R4h&I|p#8MkuTPu4-j3D@8!8A!zc3s_28rcPpwS2bMu&&h;w`jKc~(ps zj6gzKVVvi9p1304zW?9{gJEb)!1EiIR)4?!+`pM+$0A^O400000NkvXXu0mjf Djq#tS literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Consumable/Drinks/shirleytemple.rsi/meta.json b/Resources/Textures/Objects/Consumable/Drinks/shirleytemple.rsi/meta.json new file mode 100644 index 0000000000..f76e611841 --- /dev/null +++ b/Resources/Textures/Objects/Consumable/Drinks/shirleytemple.rsi/meta.json @@ -0,0 +1,14 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "Modified from https://github.com/discordia-space/CEV-Eris/raw/f7aa28fd4b4d0386c3393d829681ebca526f1d2d/icons/obj/drinks.dmi", + "states": [ + { + "name": "icon" + } + ] +} diff --git a/Resources/Textures/Objects/Consumable/Drinks/sol_dry.rsi/icon.png b/Resources/Textures/Objects/Consumable/Drinks/sol_dry.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ace08a9ffb0069ae73de8e2063cb25563ad34865 GIT binary patch literal 4764 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 KGk%m>Q28G+kH&NW literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Consumable/Drinks/sol_dry.rsi/inhand-left.png b/Resources/Textures/Objects/Consumable/Drinks/sol_dry.rsi/inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..3c03c07742b267655d40be9d93adefed258463bc GIT binary patch literal 4557 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Consumable/Drinks/sol_dry.rsi/meta.json b/Resources/Textures/Objects/Consumable/Drinks/sol_dry.rsi/meta.json new file mode 100644 index 0000000000..8bc80009c5 --- /dev/null +++ b/Resources/Textures/Objects/Consumable/Drinks/sol_dry.rsi/meta.json @@ -0,0 +1,53 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "Modified from https://github.com/discordia-space/CEV-Eris/raw/9c980cb9bc84d07b1c210c5447798af525185f80/icons/obj/food.dmi, Sol Dry from /tg/.", + "states": [ + { + "name": "icon" + }, + { + "name": "icon_open" + }, + { + "name": "inhand-right", + "directions": 4, + "delays": [ + [ + 1 + ], + [ + 1 + ], + [ + 1 + ], + [ + 1 + ] + ] + }, + { + "name": "inhand-left", + "directions": 4, + "delays": [ + [ + 1 + ], + [ + 1 + ], + [ + 1 + ], + [ + 1 + ] + ] + } + ] +} diff --git a/Resources/Textures/Objects/Consumable/Drinks/sol_dry_glass.rsi/icon.png b/Resources/Textures/Objects/Consumable/Drinks/sol_dry_glass.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..c4bf829e5d159a8501c10a5388bd153f99343453 GIT binary patch literal 4367 zcmeHLdr%bj9bc7Ka8L#hLriMdwK0;qce{6cugx8=y8})+BycI9wz9Vm*l>4y+%DXK zT8)g%K-36nCxntTh}P5uYawP573F0yRmZe6jY&=G7)QLsVC>6SjP|$3dy<(BGtGb8 z%--&PAD`d%`}ux<-?`t_=jCR_#V(75ASlkBZOsRFSiWMSz_(aa^G|T=t8o@d`BVV* z`2~)5v#?a{V_`PPa}X5#*pru@&=1F)9BoKRe{OZkAQ8&h{{C_+4TVXY0FP zeY&r`wke{x;d+Z0abWGiy0rGTxZJ0s7Vlek_E3!>GNZnt>tIXwgVzrY^&F`ydp9XG zw5xLI;df5oPr7^V@)MukzMlEPp5~lv@B245;)UpksyDZ^wpC?3@rUZ08-H@N+td40 z&RgQu7;fpKJ4PFOJP~o7`|(a>m9nJg!qI)(w~+CtK005V(A!*g7J}y0@)k>;-C~)@ z2ISDXt@VZpWI&+UvW0?m7DvKy$2g?NAo_8?I4>s{U_3~tV!{3R`0PZ zR|Z`l^qwg$j4n)%zXw%R`SPX4ga7ISlcN1bQ;_y1D$dBm5g3ko+3ZZ4lM z{_=pH+;A->=~9&P$WtvRqc@E}E7u=qviDv)l&pBZXY`S61C}rqrO1qRUwccCn?r*NogcaTi{NKrLP;nw)E4Bc)JRG!Z1OW4 znQzS;hX8M8q)d{0q)HVC1e5`dQt+3maHG+v!qh6Y8U+@pSnZXlAnFxY$`E51R#v3_ zyieiE~BM8vL6Y+U`4#y8=Q<+Gwt>8Dv+73-B&PKRLVNq=9Z-yKeep;fG#^#D^5tcuTAGRyABoAi(=DCIrA zuoobEhNZ-FQ)JDEP1c0dnH~smpTwPEJ&}9Z7+5(Rq*b6RSV1G#X5g8q@{` z#c7R8?ZUMN1BZv97@Eu!{2mIFllM@itjgyt4J%~A$@DzC8Br^-DM_B2k~rW1_5kl? zgn&4ua`GOwK%!(maXn^G>(mAXQGP&Cj}@! zn_dcd1YCgz4RZyr9xqk$O#46?E7t)~hGJ@TiZTLGjVG&;C&om!Ce=6iFog}KjTqoJ zCIh1jOhVP-ZY9y;IQXS@#I;R*nHZjo8>J4e?XU9)0fR>pJPHAmO17?_puTzCE7 z=!%^>OtD_@3n&1NN=-NF-vGy~DA&3yE0hJ5L0g(?zc*68egc%y=ck1i_+e1P3W=i zIhj*$Xb_0KTkjQdP&<4?l*3`aK2-p=gaLe ef36FM`ZNULrpz@oTD}Y<0@-c3)*~4uJO2wSlrY-> literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Consumable/Drinks/sol_dry_glass.rsi/meta.json b/Resources/Textures/Objects/Consumable/Drinks/sol_dry_glass.rsi/meta.json new file mode 100644 index 0000000000..f76e611841 --- /dev/null +++ b/Resources/Textures/Objects/Consumable/Drinks/sol_dry_glass.rsi/meta.json @@ -0,0 +1,14 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "Modified from https://github.com/discordia-space/CEV-Eris/raw/f7aa28fd4b4d0386c3393d829681ebca526f1d2d/icons/obj/drinks.dmi", + "states": [ + { + "name": "icon" + } + ] +} diff --git a/Resources/Textures/Objects/Fun/spraycans.rsi/meta.json b/Resources/Textures/Objects/Fun/spraycans.rsi/meta.json index f34820cec4..0f883ee280 100644 --- a/Resources/Textures/Objects/Fun/spraycans.rsi/meta.json +++ b/Resources/Textures/Objects/Fun/spraycans.rsi/meta.json @@ -58,6 +58,9 @@ { "name": "spray" }, + { + "name": "spray_cap" + }, { "name": "spray_cap_colors" }, @@ -67,22 +70,6 @@ { "name": "equipped-BELT", "directions": 4 - }, - { - "name": "clown-inhand-right", - "directions": 4 - }, - { - "name": "clown-inhand-left", - "directions": 4 - }, - { - "name": "spray-inhand-right", - "directions": 4 - }, - { - "name": "spray-inhand-left", - "directions": 4 } ] } diff --git a/Resources/Textures/Objects/Fun/spraycans.rsi/spray_cap.png b/Resources/Textures/Objects/Fun/spraycans.rsi/spray_cap.png new file mode 100644 index 0000000000000000000000000000000000000000..01d2d49bc0fe5bdc830392750205b8cf8a36fde9 GIT binary patch literal 246 zcmVH=tx2X7U8A;nEvG=NTxeNJV7FiDb@}tVsWL9Qxep_<$e?f*|}G z&bh+e{o=ud@ZRr?zG+8zGDBw!FAJcx-keiP)H~D{7-J4;N1z(WIb#@xoyI^lur_6l zEA$QkK;QQr04&QwFXX8Pu7GMlDFpzCF_urQ6{>-Gp5La`xN5D?I}k!(M>pKQ0}`NP whMaT7TD#GvX~H;;&F@hGYKZljF&6;f1$#d@3sMJ{VE_OC07*qoM6N<$f-h%ecmMzZ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Magic/spellbooks.rsi/bookfireball.png b/Resources/Textures/Objects/Magic/spellbooks.rsi/bookfireball.png deleted file mode 100644 index ed18010a728992f4539425de5df522f572bb96cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 652 zcmV;70(1R|P)Yr6%<4e@y`*&19%Vd z3WDeXDhPruyn*7Ti!KB~bRib;&qA@NOf_u?)0mmOH?x@cZA#K6zxTdOrpdflMBoww z5V*tu1THb)zaJb;PkirH#;i_$d{HkTr?~m421M|k-4zUdzMwK$?jBg0ZGR4oOlgl@ zTiixox!|W7px|50Cp0z>VWQQ`15n5XKhqp=K3>Xv!i9%7P>YkFc@k`0H?{kh%Y!(1 ze*Zn$Oa)x(#gEH|pX*;hB|o<@0@TnkLFwc57CvRd&t*V6=|u9}ijO!785@ucz;*Jv z5tm0s2E+qUa+!RG_m@1?NH8)W3P6eaN|?kzITEbq00r+`s$x!U)co8ARD5FtBKX(o zV<(7{eRl>>^NkI-s=cse+vy)A zSr2rlu=DvWNd*c9(=j))53%)FiBXEfU2wY+S0+$$oz$FGCa7lka7P#~WNPmFz z2e8%Wee-iyhjrrW574o7``G#edKD$9YxY^$6h%_2!bmdtD2OxgNynyG9=9uupnKKh zK@_XQ;FNCEc`1w}ho0*if!F>3>iWEIzVru}9w7Yz(jOrG0n#5J{Q;2v0Oyka04Bcl m2c&%|{Q&_;3_#!t-hdyeSrmMJI}Nk|0000A7D0p{dIGiwHo~5d?&#IkmiN$By@c|L;qm!&x_rowYIZoNc-;i%%Krv zLjYkuJe7vEB9K&EzcPN-C02~D=&g{tm7y|b>vibyEQ!)VcAOCRo6c2zn4cVLr z-{z9l^Watj4AcrHt z^T(6AeiXu4eL$M$Q!DCTSlQJ=I03*C#u&s_#sGNs(j2$8QLw8IAakx-e=BZF0QdEQ zND^{n3?MRGWV&tzK;QJ=?*nnH05SlMf)Zo)WB?3-`y5$)0O=u<5X=vX$A(S zbWaz@kcv5PXPxyr>>$#be?Xq4-ogBl{0p}le)C#}yE_8zaK!!+dc@5UB)}s6Xj`{V zjgWcXtS&u~Ka7Fg8p7pS(K-iw|6NmoS)So z$S-blYmbdO-`d68n;Ki{mKi6!(fl3w(ek$9?HyN+E51m&*neGYDyO^sbjI!BTi+!= zeqNPZ-MM7r%JXIiI;!Iye=n6_Tcmd5+HuJP^DiwZ+PE4ho@0KWf5kOj=lj#`nR8w* zW{J_cRk?ei(Zd&;c`a`CZ=0`ptBvvM`6s6iY_s!HIImLtV@juQ?KZ|qw_}~;RUJ;9 zOkwzL|1J6V%$!F-_E#B-&DGBT-SPcmruKJc)i1%k8T0Qw|0O7WHW}z%yK@Xdd^`$I z4DTIL z@4K%b{jy-LIJ|l)ufYZ$k8jVCRg9VRz63JqiLK4CQ@A<1f8rUA9T(g=3)KHi&vE#B z=3IHAa=?nK~_iwzoSU*@k-QnB9tEbr{jHC@#n9D0q6f9WUFI2EGL-jLb zbJb@&`)|t`^CI2s!TPtVQzb#l6rL)`Pxz+z320M@yoAH4!2AQ| Zt4g;>*qvB)0hkUMJYD@<);T3K0RV#^GT;CJ diff --git a/Resources/Textures/Objects/Magic/spellbooks.rsi/meta.json b/Resources/Textures/Objects/Magic/spellbooks.rsi/meta.json deleted file mode 100644 index f9f1703f24..0000000000 --- a/Resources/Textures/Objects/Magic/spellbooks.rsi/meta.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "version": 1, - "license": "CC-BY-SA-3.0", - "copyright": "https://github.com/Citadel-Station-13/Citadel-Station-13/commit/f3e328af032f0ba0234b866c24ccb0003e1a4993", - "size": { - "x": 32, - "y": 32 - }, - "states": [ - { - "name": "bookfireball", - "delays": [ - [ - 0.1, - 0.1, - 0.1, - 0.1 - ] - ] - }, - { - "name": "bookforcewall", - "delays": [ - [ - 0.1, - 0.1 - ] - ] - }, - { - "name": "bookknock", - "delays": [ - [ - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1 - ] - ] - }, - { - "name": "spellbook" - } - ] -} \ No newline at end of file diff --git a/Resources/Textures/Objects/Magic/spellbooks.rsi/spellbook.png b/Resources/Textures/Objects/Magic/spellbooks.rsi/spellbook.png deleted file mode 100644 index d24f198f949f09bd26e513d9a8df051437a5045c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 743 zcmV?P)-Ep z4)8je6vhI$9gFGonaSVB-rg1s-z|VFM+W@r3}Uf+xOwLT0Sq1A(F*v3LA-r=7fL9E zU^t9sclOn4r(a|+S(rb`Pq6@v^r$A=RcVEIVMi_ARg=U+uY6={YT4dh|VUF$?W3F z)#msBf%y<5pBMTNao)}$lt2I)+a4YEW((l)GI2q$6yMmWV0BgLgJ`zfaB8*yIt?a> zeeEP}1wqE|ogfUofzAM|jElcoPvBuM^TU7j2gT9y3Vltz`LCt+ic|M z41CJvglOcV?qg4}6P6h*0a*0Y>NV6VEF90w;PcmK_Nfpf9KtV$c}D||YX8Uof+@fx Z?Khte9agC)|40A;002ovPDHLkV1kOAT(|%L diff --git a/Resources/Textures/Objects/Misc/authorbooks.rsi/book_aurora.png b/Resources/Textures/Objects/Misc/authorbooks.rsi/book_aurora.png deleted file mode 100644 index 0e34258138021492fc684b7fda2203714d8d63f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 358 zcmV-s0h#`ZP)3FcgOWT0<9yPBjV^C=YUem=@yeF<@pIp?ZOlAl2Ve*t+nJ@G5`QX zQPf#eRaKuMr{4uZ0BM>|2jI;^A%YS}k|fBS4e&ebkQCSn_}Pc1Fy1a89^Gt!EX%&0 zT(JO*F|FUD0@N2=efHdi_@BGL81sp}{>~A(9ZM<6&B$7d{C0#|?}uy0esHp$cTyP{ zpihr~16+pz&{~6YAAFn(0BDULAgqD0_1_ng8DI##08cz*&hj?w^#A|>07*qoM6N<$ Ef@9H>(EtDd diff --git a/Resources/Textures/Objects/Misc/authorbooks.rsi/book_cafe.png b/Resources/Textures/Objects/Misc/authorbooks.rsi/book_cafe.png deleted file mode 100644 index 7a3b6667cf86601618c0f5aeadd4ec999245269e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 517 zcmV+g0{Z=lP)#5u)V)i)9kZWHtj%jftCOu)Db+q^cs9NFaSW8T6?D8i8u-ZOc{`I94@b}h{s|? zbsd1DDHbXXPzj31VgT57ipTR2`E*f$&x-0gww+@4Xc&MdOGX`0`M zdtT!K&h8B+?hfeg(g1iaxL_EVrpd&=A#iV_bRVv(){C%2q2M2 zRMnPciCR=i_#w0`3)gjVUAOLVVSve@BmkPGp=nxGPgYVJQ6uhL3ZUS@Xn*oc?^~6g z8VexujR){wt{VdoR?DX%QQg`_7T26#&w~I;>({IW&}@J=_3nqkbOKgz00000NkvXX Hu0mjf%LU%y diff --git a/Resources/Textures/Objects/Misc/authorbooks.rsi/book_earth.png b/Resources/Textures/Objects/Misc/authorbooks.rsi/book_earth.png deleted file mode 100644 index 8e29c3880a48af951ae316342b6aac1dd0675db1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 498 zcmVd^$mMcDv)Sw`LA%{H1_J0LZ{O}fW&tuY(E!W(b*vD}Jpqkg zJ|Kh$tS(7@Q=?Hqh~>e*Ku4x&#!l}0e(c!T005~}s%MPnc{)=je+m)@&{~3yY}-ak z`FXFD!gbxh0Vo!W0F1|X#j zlkHVu_5@lV9+I7>RLw`0Wh4Lq%$?UUI^d(XcKM@U~xZe zZ#C_yv;mY-IIRjC+pwC3sagor3UFS}QA&*#pmWrmm1{6X_^@8Uxz9xUbric8nWp(^ z#oc_s^E`atr}21-nBEv(G5Rjob^A7+pZZ@`tX1jWo`wscQ{zK`yWs#>mPJ4RgU?q@ ofUX-5Vw{3eEAdS@21p#>9X*PTtyA@MdjJ3c07*qoM6N<$g6GxNUjP6A diff --git a/Resources/Textures/Objects/Misc/authorbooks.rsi/book_ian_antarctica.png b/Resources/Textures/Objects/Misc/authorbooks.rsi/book_ian_antarctica.png deleted file mode 100644 index 3843e20069633415e2005a2c6955a81d47a3150f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 756 zcmV##khG85lz}VQB>qG#B;CHTn z#Z}V<7uxn3D9WLGr>2%m0+s|Y3M}toA?vP6F(69q{ zY5)K~V-EpnS3T5*2WVG4d-UZ>StZylzWOG7^~c>^l(I9hWm;$xn|pNH#3oy2@xyzk z)SVuHdPxPqt@b<5Zhfq-r7V9!0Q=u4I@!RSzCdXBF?0F?(a8p9EtE_+Cz*M*Ok_QYuFn&1 z9Y1vMQ6kg@K{Ltwni^hf)7*Y&0&Dm%G0000 diff --git a/Resources/Textures/Objects/Misc/authorbooks.rsi/book_ian_arctic.png b/Resources/Textures/Objects/Misc/authorbooks.rsi/book_ian_arctic.png deleted file mode 100644 index ace42ee7dcb82d0de23fdd90465beafe8309c299..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 531 zcmV+u0_^>XP)HT-@Ed2!ddp z1xH86t`2n&LS1yKt95XSI_TgaXf_d%AU3w*;1Y-0*!r)zXzkJ;1nwU1?)ULtj$9Pq z_i3d%TI${gXafLUVUqIsyzjbhB!hH1t^5k0YQ8jmh0-$)y~Fhh{r%sr-P}BD2-pz7 zbzL+~WA9RXi#&bE_&Bd^D1Ly^)!h4855{< z<0f?|v!&cA@H{Y6^CXgbVCrW~5=k91H6Oq=4FKT&WEX%Dy&FGcGNO0a#bqVcf?BDu zLDX2()$fw7z@ztqSi7r>iM2Z(y_f$1(8qKDI`ygGsg27jQVZ<$0k*7tvV{`Mvwhg> z1Ch)jLIpbYDV`V4$refgWD6yp7te!A1PXa1q$_YXw1RErIJk9j90$WNu&f+HtN`1x z+sOeOi47JE0|3j)0btw52r*d!5gSZ26F`W`FUPg9a=9!85a~W(yj9`5xs0UW0mpGZ znO0-}0`M26kpZOoTfY8V0GV$*fd6y>jQ$=#(=?*o2d_#G06*Rb0hIQySsS3$0Iztd VjF`6Y<^uo#002ovPDHLkV1ml)=STnm diff --git a/Resources/Textures/Objects/Misc/authorbooks.rsi/book_ian_city.png b/Resources/Textures/Objects/Misc/authorbooks.rsi/book_ian_city.png deleted file mode 100644 index abd76a54704c2f69dec12e1b6e07a1f60a2705a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 538 zcmV+#0_FXQP)KIJT0>Ikq|n0IpLzm}X%-Jn>%MSR@D(y3y;K zm04157nmjt`2!4&sCLp=B*@^1%8)-`!~Gcmz{A-A06l6Wu}F{}wXq~FE2$QIR9i*K-a?n7{)0=j21w|7Cc`39l*RN$@JS;h|w>f^C*?y-FZNJtHO8pGLn7= zS`Ie=$WAVQiv0^fC6c-axJi}w6qUQJFo4829>99KtPnuE7dPj@tMev+AJ2mTO6}LI c22gE)SBTz%A9MHWg8%>k07*qoM6N<$g6rAiJpcdz diff --git a/Resources/Textures/Objects/Misc/authorbooks.rsi/book_ian_desert.png b/Resources/Textures/Objects/Misc/authorbooks.rsi/book_ian_desert.png deleted file mode 100644 index 9a2d2ad6587d53e4d53475db616226596f18886f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 557 zcmV+|0@D47P)%SK9Wh4fHq?h9SuG*cZ{aV4+Ar2 z?!EuVIrlPWT&8J~PZj0Wy#P=E07~o(T3PsMp2t#-45k-!*Si27%%?^Kt}o5-wJvi& zMa8Rg7iT820%ip`kEQTdl@eIr1NO2m_@JSgd0XRbl>p#dx!bn+W#ZQMSla*qO_ARi zM*9Ayx6g`uLO~#1jl5v1!?P0Xzw4e;64lh;9_SDfO^G^ zClsV!ac9J3B~^l_s;vG_Wwq1UkCM(n!nj4uo@T_v>?sMu{>FP3fYPV{P^@%W*VDMH z9F;(yt6@p|gFl>P{8t(JT#X}haFBswrHj;91b;XQfIplhH5RclVaeu^kj}vW+DUXR zz~7TIqR}X-s-kHDgqQ?YWtWo!_$Pb}t11AR763rkw-KT<4I+Fru<>yKKfGJOAOJ#i zzW6>Km-2Vk52*K9cOzgyE1a*00000NkvXXu0mjf-?{Hb diff --git a/Resources/Textures/Objects/Misc/authorbooks.rsi/book_ian_mountain.png b/Resources/Textures/Objects/Misc/authorbooks.rsi/book_ian_mountain.png deleted file mode 100644 index ee26df9e9ab6c3d7505c4c977216729652a7fc59..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 603 zcmV-h0;K(kP))pTn{RG4%a+$&^GTSjal-A z2fz2b-+R9g@ArG$ON3#_Fm+?7*+&2)0N|!fP_bAHUDxd?L8(+q^aapPzV+x23H=`2 zx*HFen7DN9+S-e*fL#Gx*CmxovGoez=zMh7`udVooKy(_G)6!3nY6T#w#_sGBl`Yk7f#<>ea-O-YA(Ccl1?I8_^UHYwH!uKzA8(_^nlZ-7 z)C$ZP<1xRgluFR4$*J2+PW8I_pOjDF*gM18IE?wMjYE#Tv;PBN%o+fU8H-|c`Ue6~ zE|+6-XLFhzdyj1XB|G*W&gOJa$)x})l}Zd^%vj`f<$&`3N#x%@;dJFdoP?0%l~8WN z_jgut>?*bIM>HA@Ow+`+t60`5@LY8}HGtRFHV;h`0Nbtt;5cuvtc3`~+J@i1lmL{P z(6%eWwyXs)F8V$YfVRx@Q@Ci}*|6>Yxk`y{ui|t%9qPJ{rfDRTN#U>8>%z|Ea>Dj~ zpCAbM`r#>Q^8w9fv%mMiW$H}YkCXs>-m`R#fERQ~Y*Ve8ZN0O-0-tJP9U4)Eoj p3vgxqL81uGa2M-UF__hWg;5X-kws*Ul0xwIikQ`)-tO#0)8r2evv1zK z_v5`CW>#}umqsem(CkfsCIHal=b&jCOi#PmcBlkyKCk^3KsEWFACqWp!_eMeJKx#) z?ow@J-Z#8IfNeu8Mr5S`6nx#Qa({gZ9s z;#3FbdQYh25TXK6k)S+xL^@jnAe}8yo;&g?;VIyjP_Dp1-zuh&Vf)giSS+IJI);%! z%2nXIYB)839l61*t^;5g830Uk7bzzyAaVl=haU&9T)t=aX)NW$oAas)bsx~5s_@>s zij=>Bj?GN~N=r+xY@Y&9kEG!N&d!4S-d)rgK;euBaPN=n1Q3f6=013`e*>2F&-);N g*8DYV0yG-nFF_}T3baD4H2?qr07*qoM6N<$f?9U(RR910 diff --git a/Resources/Textures/Objects/Misc/authorbooks.rsi/book_ian_ranch.png b/Resources/Textures/Objects/Misc/authorbooks.rsi/book_ian_ranch.png deleted file mode 100644 index 7f6b3e86ddc47afc7e6c2aa759a214c0f01eda62..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 530 zcmV+t0`2{YP)-3t~LS&Pf9EB@Gf>-}i%3(M@j zdGp?fH#5wv@_nCns;jNpI{+O3peM>fDFuu8RN^J@w|(_0fLii@Usq9mBanFau-`DA z9jZQmj0_(QPyrIqwXq)Q8kV2kugfnQpr%1V_CNKz)(-%jl)-hY@8h5D?Zra1H4OML zAc-j41+EKY)3c1G%^+#90HbM>vFX_Wu4w=OmwP_}cyIPnEL7XDT`JKOgw>yVOMfcv z=zEDPaP8ir*UArUdaca0d)pcSbJzr++nfxZuwANHQ{ZF<*s_0-&3i0OC2=ysr5}>G z0^Q~$Hw%Yk^Bw@%yvNPLVNi)cb#4i91rCN*aO@nv&n_sHN?4YKZRgN>1^6ZnCj;2g zo6K7l0Jfb2z;SlbdZG%VH{oizc>rJDEHlp>09sEx*)LVB`+)Vo3eSB@Bwho_A4veb z8Sjy;B>;^`8Xw?X;9EIuFo58U2k`$MH3%R9aqff1`&aNC#rDg7s`G2s0cbbC9p9dH U$$b4yP5=M^07*qoM6N<$g5Zben*aa+ diff --git a/Resources/Textures/Objects/Misc/authorbooks.rsi/book_ian_wolfpup.png b/Resources/Textures/Objects/Misc/authorbooks.rsi/book_ian_wolfpup.png deleted file mode 100644 index df0b2350ae7c580f13d2790fc4cddb46a7c1ef8b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 552 zcmV+@0@wYCP)1P>kRtwRZIh$JUy$f6FeRhu@IuIj{# zUl2$~=ic|>TwU&w5(ELG)Ps?_j{(L2z{98nMNu#eBXArikwK%;Q2q;`XZ~q#1?BN` zc=B{GA)UT;?BZfE5-<|LaU4`t<;7+TXhlxgQ?2$UR$e4PPpMQYwz=ndv2$Ys0KA<( z#C5y(?;gDj<3+y$bXVi`k5!o|<#vJV!ou1*^GjN2TJ$T-FKH~St%q=T1^{sJ@c@9V zHc8R1kkuv!;m2~f^$vca6;>it%q<~Zfzvq?+p2Q( z?K|yu8(r72tSUm7z`pEsascne4tZS%z_O|U*!Bm6Snh&|9XL6@JAkvZQ}X!@0EAfn z>w8%x>Id{+Rk-b0M$+GaX_^3(N~J$y_X02s)5HKW$1GQ0hYKKO4g}YqhXbIhDoOgm qFO5r@&E`M*K>%g^Yc>WLHNa06^o``=foRMC0000~53@Tu_&r>L2o5gAt>_>Gry>Xk zg)9X(2L~N>7MzMp9h~|FTm|>YnHmCt5Em1YG@APpn5ns6#hJt?>DWuvZuW0J^=6O3&Q;lzFAzDX>fzmRY_9O99}V zYlUk8BrE5fYjr^xfO8JUSUO%h0L`3#N~v-elmIN#&8^zDZRIXV158H!T>BYga2zL{ zrxFB`1_**+F-${J01xK}DMT62WYqsZfa!PuLP#z+0m%YQ$AkI-Uarn6Jy{?Tzc9e; z<{}+OQSl}euT=&pD!UDYkcGLdq;A6`pcqsdJb$kjAPhrMD*zz=daVb55F)+z0I0fhdEP)&yAqK2Ao}bp9<-AM&-tW8*C+8;-r4&BZ@|qq10sye0 zGl&Qr?kLK!Q-JDU%Ul3;_{VV%S>J}FGyObG8%t&HK-;_?pd3Tergb_5hFW_qb$({# z(*xAn+Ay|q|7>hE2LRYi^`6JVs!8v&AOP5nfiHEl{MWt9Y0tuC<>$YoCaYeRcK?lg`7&`s5-t)<_mWQs5Mbl4@6R( zF9qP@$Zfhc$@@a&9l-7t*z9!W-GTuu_ILpGaan>;O*5D3`Ro#Z=Zx;vjE^5 Z;1j&fN@Z)Wza#(v002ovPDHLkV1hdAqQ3wD diff --git a/Resources/Textures/Objects/Misc/authorbooks.rsi/book_medical.png b/Resources/Textures/Objects/Misc/authorbooks.rsi/book_medical.png deleted file mode 100644 index e94b6789fb54ce34329953ac7d1cc550bc2d9092..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 356 zcmV-q0h|7bP)+=~6M^(#=zN0&gMM*>gB|@D}wL z?hcBJ5U@)rD56swG!l#2{3vnAJEh@Gzb9Y*J;oSps%AC118@KU>N2J@O&O(BD?l8_ zo)G{KJ{fM|wFW@D|7_@V-nLDWWhG!G0HqX!5G*$2UUMor%HKDQM!m}5QUF|G7|L3a zWtp^B8UO%-AgJ`@d9LzH`>Vh@fYK0%8qfBR@_gFW1~AG%!*7~22cVGwvFGJFolIyA zf!K3iK3`t%2R{Me!5V(^ec+<_4FFH`Ura*Xw2RVSh97+aCz6+po z#sdI5t^h>l0E7_e+y~c14j}q?9|Qo;JJP)rOGWKbh;c9De}OE`tI%Su)vIX1ZQR3nXc=AZfXkL=OmaNw5q>ZaB20PX;Q z$&iPZ%jH2S#kMGz1p(Wlu(4SXSl`5r5AfyXWpoh$Q~dLX*NmobVD{L2APoO{_TAf0 zed+rFtkab7WWvX}mCDwqX9BVqW5^DqppueG+m zQp(aWgo0iGW{mUs9IZ84Yg^O>gwOn;DR%%xrz!51yagRzS}BrWq36T%p!{8xU;aUg1WBHl3_1^ZBek>?T}KkTCMDT zAp~&jxUTEQraT^8U*}t3EJ+eP&m+%sJkO&nOOhlZ&-0TQz@hvxC~q%-$EPRis>1jE zW4BesI!#%pDZcOH`#yD5p_Ib+eb#A8T~+-2{tMurzXt(E_rGR$0JjG48{{V{_|L5+ Qh5!Hn07*qoM6N<$f-PPiod5s; diff --git a/Resources/Textures/Objects/Misc/authorbooks.rsi/book_names.png b/Resources/Textures/Objects/Misc/authorbooks.rsi/book_names.png deleted file mode 100644 index f2396ac527932495e2e9bcd6c4ce80f7c84fb142..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 317 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?4jBOuH;Rhv&5DEQvf z#W5tJ_3d?Az9s_^_7C;Fi`l9eY#OXL3xCw{yLYI$f~PNGri6^l+dRcx*EW=PbV+7jwv-Q_!)?F7l})qjO4RTI`mdKI;Vst0OXZ;Z2$lO diff --git a/Resources/Textures/Objects/Misc/authorbooks.rsi/book_narsie_legend.png b/Resources/Textures/Objects/Misc/authorbooks.rsi/book_narsie_legend.png deleted file mode 100644 index fe7659f396f1f37d6f20908ffecb1a4b5a0617bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 570 zcmV-A0>%A_P)`6pHR9J=WS3OR{FckhAC;d-VbwErUpj*$t%8KX>I2AWwV?=NP zHU*paB5DwRvbZ z9n1Neq1RG)!&v0j&G}x-$*n(stjSRTX4A3UL>x~Kw;+QF;9uk)7>!Eby_#HBeZCsN ze9ds?d$_*2Q!h}0gm3o_mu7(`T;l%qaf_*g0B9Tc+W>%o2~eu$`ksS;iS(KQU;r{{ zjs}o$iGT^558Lp&YL0OUj}rJ@HSV<3{7;-9ifzN%g8}Un06a?IQIfmYwqPQa!$yKi zj!YW0BUZ=(eb2Z=-`lUU_wED#MGvSP*_EVaW+j13Ng7$1<031zR>^?Y(adtwc^M$U zt_rMjAoI%w#NMrWOf+e47PO%78~n z4ycV;m!VnT#mLRFti2Ct8UrS_A~zia88fx_frLv8J5K7@bf(98eql&ZOA=}enAmb& zOvXd3l7TQ5=(q~!*LRd^Y$ltzEvL5rtOr1^<-nx`QLOfObF0-(QvpV^P@}N%L#g05~;(U#ZIcWN2>wvj6}907*qo IM6N<$g1MvthyVZp diff --git a/Resources/Textures/Objects/Misc/authorbooks.rsi/book_possum.png b/Resources/Textures/Objects/Misc/authorbooks.rsi/book_possum.png deleted file mode 100644 index b169c180be074fc0c21536cb30af01592de3cde5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 468 zcmV;_0W1EAP) zadvc7dwJ*M;i2#P;&qv2d3o2xCqXF6MpL17EwgLeI0h~dK zRN7(f>O3%+-I9$U`(c^ilmJH6eIvbd!Sx%uuPMB zqd`H_$SVo}h0ADn1PE4OC{)li0Cc@NkvIrez;Ag)LD#Fy-)sXQ%Q666`DHc$mT7WO zDtTkuwgH%ve?Ihjq4EfC!u{K2a&3!u+Y+5R9RPsM<{ri3p*OD8Y5;UP9pPM&mY`m7 z00RKSFd~b?g!e$UY>oIs7!iw90sqk(^IJ0j0C-UEupaNpZ|neg{%))Me*peY=LwnD zzX5)~|2ka&ksc4=eg?PhPyng4LzMSmTmJ}r4+2QZuUP^RH^4V5^>#?6W`!pJ0000< KMNUMnLSTZ0pTqqC diff --git a/Resources/Textures/Objects/Misc/authorbooks.rsi/book_rufus.png b/Resources/Textures/Objects/Misc/authorbooks.rsi/book_rufus.png deleted file mode 100644 index 22e936fb3f4aecdc78311df46a2eca6cb048840b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 410 zcmV;L0cHM)P)ea%tV!#14oU+AJ?^L>CcG0zUU(nAgYOPQ2tk$Fs5HF>r~!b@ zBBrCWOR)%NS^+l~r$#A&IQ;r}iqSfNwv#qk){oa7p4>_Sr2va?M$@wKhW7WF=Zqse z{?gU?zBIfLK&-9yPEji#^Vh=O!T7(5hTVsQl5h3lbfcQ8mAP7 z>j#L-oGpK&+h0wOs+22`2ca7dntdSk!i~qJ`ha#LDifMi<*m4K0HrBVTIuG~^#Z7@ z@c`oe9&n^SDL~V*(b*3^+`RzKulqp&qy9Ck0jdW01oy^^NcURC!T!nTizj4_YB#C7egVC;=$dE$x!eXb&`+@wm#~Q#kW|pPP*TnPV$);W9U;xy;>gt z1^@sTIt3yE=z)P1P6inJpnm~y$LGDxl6C-DUShsDR*tWiQ!C@v0Ab(( z0JfW%0OIeWI2G;I0Az{cRJ1vei#T0GSzgxmTLa*R{)U?OT|le=WWzk{a`;_xz-bGj zI2GPzd8y=skkhGo0B&@>oCvn>b%Pk1dKzs|NG%S$B(Iy(hi=8L0}19i7! zqX69Kb~97LF5ir;0>}v`=K!E4rj3y9zkukDfqd)FG5dM}O;!z5MAD)*!hQ}$dIlw# u50`rIGbsR|)_cHU3)+_6%klxBcYt41t&_w9@AhZ_0000*mzS z2gp#|vOD@L9fd;0K_{0GItZdjk5fVtvG;3$xjE(Ni1T+N+XdTaixzRlTY(2BG zGZV-?_N`5k#M;y;3EQ16?M|1=i(&p;UAw}o3U2RS0EnZowDy5_8OBk_;czD>@oxl1 z=LY~xrb`~5-k406rF~b3>2D}NO#lD@ diff --git a/Resources/Textures/Objects/Misc/authorbooks.rsi/book_scsss.png b/Resources/Textures/Objects/Misc/authorbooks.rsi/book_scsss.png deleted file mode 100644 index 1262f51118ca0817c38037ecafec635fcf15c84e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 351 zcmV-l0igbgP)(I+h~NK8J|U;bZ7*U&Yz2FW}_v z;3T4>wNNo*oC2-1=GS!TnQwBwTzYyF!Z}Bq>b2_L0dxQW`mzE-2%;$Bj4>mFEX#-$ zfG~d?Rv^O}5KO8CVc58KJYGlvr2vdEP)ZTcchb$uy5ILoby5JKAPAJri=t4jRR#cn zx5CB)4N$-^1<7VZ(v~iHOLED}d%wK@ySu~*!;nqd)<&~u02u(_ zCUH70mBNYdr%LcP8aYb==;XuB70%8f?CzNk#p0jO9_-&N1Y8I(@qG%O$H{dU=q?PX z?fLaKkzXPS0Jh!4uKXyK*f)7pz|G|lLI5D8oO^EDE7r3>N*N_=HOutc6@(B-DQ!d9 z0|+6aHwEzWW&zVcSV^E02qEaTEBJw;-WV7XsC7%A%k2lsfJ!TYRRy#?+@Atat@VvY zTsuI#^j_Yj)htJS;0KC}%NJ_^YYBAeHH06i=vur%8IKdivu?uKrt7sU0Gypa+JuVC zdK$*H)^fz}uN7ckA}{Y!t@YD{0a8eytI)YSGNxkM)i9L=LI~=O0RZ*Jz_@N}sa8UL z)D5|eSplf&)Ev(&yTP_dptn+JzNby!Sk&5c!2k(Pk?{F2LYVy*DM3rG{7%3 Wv%OLRsXy@m0000kK>^ z3}TEW^#^pYTZaX9h#<(DPCtiF` z&-=X3@A-b-_kG^?_q--e(-@|W4OM*vFaiL~{Ulwz_eMLcl}{v~CL<<80B!NFPfD21 zUI&|_GhuS_*tO2!`<{S30S;?r#%&U_Po+PRy{?Sz;ergic5`GEmgEmgcLDFEWZ0HH*VVp#>iyOJWDOb-^I z(X^9UUZC_vC7ev7uBl{}7r3>U!tL=faq)^UfKU%a*0+%JSsXJ?ie;4>cYTDDX=eTK z(tiPWEQ$%Sw?OC)9PDnh@o1iSFn~jHBImQjg8>R9xS#pnnY_P$`T$C06?ZI3WPOWb zS;g(~;eY-L?K8;vEZ(^#k#gby-nk`gM=lO_x2c&GKD^E1ket-7DY!j8JCh`dclT^jgJbL8Eg;K%!=+Sl~vR=6^G>Ph>Mz`fn@A*3&cg0J djR1xX@Ea%`!+9L+@>>7^002ovPDHLkV1jE5CO-fG diff --git a/Resources/Textures/Objects/Misc/authorbooks.rsi/book_temple.png b/Resources/Textures/Objects/Misc/authorbooks.rsi/book_temple.png deleted file mode 100644 index 6f68c1c2e239a5cfe97e069332d127c90a9fc33f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 553 zcmV+^0@nSBP)Uqc(uI(~^6Od>HP_H%2p}!BE0HCEg2q8G=^x|P~nJdB9pYO$;0A|U*e2x%XkHLKOufz8C z!gu$cd`ksP1sDdGG^#tiIs~}-yVA}2{xp+cD!|N|#>1?xxc=|VzL^04o;`2UYDWwA z9b4yg;HrdF18B7)_K&*wzK^CQ2S~~(0H#^v4N(GfMKWtdba%#_Y4U4!nXmVmc|Uem zXswy2KFrnn0$>3Ecu50<5FBr!ukPFo>~*ww6M!-P?Z+44SM7w7H=pArER z0j};~Z3Ry1-xC*`)|a1Wsm3J&7-jwR#-m~Sv8e$7mOaQ!W(-D;?bB`dqv!Kx29WW_ zM!x>a10baYKqRRaGosLpp1>HF{5OE3QkOzAqT2dHI|z|d#;!0=TUo`x zU_=~jwN9RXBNz7-4|=qNkZX$+v<5KgR_~SRH*#?dR8AkBXTi-)sx_@#U~*q66}M?W zi&831QCm6Hfp!p5ZOI8pbY#Sm%pNe{Q9{>gb0HY?8&PNfw zD~si&aONlgHh+G&f*GFylhg8q+3eSU6FaX3GL4%f)wpwb`md(A{0I+qDl6TZ8rTus=z-7wAs&69Yky%w*Phzg|#1!cLv~_`O=yL!W`fP z%jl~gwk2h+?E*;dcmSaNV>8gO P00000NkvXXu0mjfV1}{0 diff --git a/Resources/Textures/Objects/Misc/authorbooks.rsi/book_world.png b/Resources/Textures/Objects/Misc/authorbooks.rsi/book_world.png deleted file mode 100644 index 8793ef8dfa2ede1e64cf3d1b8a02c4ba4ae3f3af..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 526 zcmV+p0`dKcP)&iPXu6NVfL%DDXTdiBz}{D%p3;N?JY~X!o+UCr z2CL_=a>mhcua{xO0o3HADYkaS<>)aKDgayrr%CA9nq_GT0Kmogsaa9F%yPE{&lOl) zs&#yOYYo8cL)4u4_8i=7!o)gEtP{zLufH&Wp3;bA%CI}d>`Xrq`PzgjRER(3J#9ka zQvk514sqDs2bd9wWy)TL5eJY_NT+ToQ6OHI2V@jv6ya1XoQNzTd$=2ANH-?D2^)$0 zOD43!TOZ~h!=8I;E`Z1#4`Af=<^Ti;ve@IS?mjHPN^@Ir%0IzJdul zxcDH(#ns6NU~@3U4+bMBNI#+6dTyawP-(RgqT!#Ab6d{6=XXx;R~S>)3}6QEHvo3m z*R8d!EwptV@l*;4NdoJ32Ydwn6GgkNwpw_sR&iUY;Oz2J2n4WEELy2d275aUiH?r> zLX6%%_c}{O+s0B$U-m7XUbP5db08v zEG3h;dpL&}_AaoehfHOcsN~D5t0VoAb8}cI6zq0160t2a&ENoO%9;;u5XdMUpPb-e zf8TCP>9lPvc*_$YOxak1@E(NA3FHpyST2(>7_EEwktcvfgTea9#U0!&H;gmw1!3d@ z@CWdnc(7pzN33t#hB00McbSKu2mWI{1WlI53*cM*(mNZ|)ByZwG64Ngpeo9A0Qj0Q zL`rBu&$HZL`r1TbyjNgZLMC@S^CByLlM9 z4G((SX^3E9>>xPtFm{=@frz&qJWUv0hCPTUcXLq0Rj07UwQ0K~ZQr~;Z<0L}-%-I*DBp-_NCA_1Z#K|Gm+cBkXaCGnYU+aL%6 zh@uD-ug&9QIMOtDwzeij2AG|mruD-^ShzP1$xa<|7gc=P?EN`?#Tk{%rQnw<3VpJ& z(iegY@MC`;Ov8YMk^!kq29o%bFbX!MIQ!XI!@M^w3%>5{!RCu82aG`tkB;(Q&j&Cu z)GgBly;=nU4aq%!_)xwL4@;%!HNXmvMS!?P*H4!xCP0bDA&&)XHL4IsTmTuvEn}tY zeE=jh%A)XbXUDlu=W-BMT!1caD?&u>ix`A6Vx4$;ytG6gEiOje1%wdjb}jf55rk&q z84m?uV*XX!dQ3q@IIOCt<|sllJ(!=TPghr?ML@zDXyG|Py4_Po&w|2(p*M*9)NujW z*0NoXJY(MI2l-oZ0cyJLM8O|{-*X7UAp9efjcdEjPq556hC>0QQYnaGNcBd8x72~q zn@u3@33z{Qjy_*skGKoa8!NzjPoDSQHTzn6hnCT5aiJsc0zb$}5w~_C0jTI*3q1*{ zfuJqOWV$w24Yx%?CVF|t;LR9cIusF+>yYw8y>*G?uO-39T|Zde(5|2?ce}% z_`PQ!%-^4Q&y>yQ!EE*#mRr}a(YNLI(TY&R){2Fn2INz7jrw(jkOHPa`-TN6@H;;4 zibApIjFsJ8h+*gzw=bmrW&=acdO-_M%r7gMo<$gVjz>SF)JW1{*%CFy8R_)S?r{ zTwD*X+&&TEbfJ+&mSI!Ol*aDFiQiNe-U~5rRCrx49Qdlkk6DLDzjNCk{$`7dS)N`k zUJi>n8>>~8ybmS|L^U2)-ZRlF6NUcJ#e9jLDTf^`SblNUo!-~s@U*L z-+bj`hJfsjIo}>^y`0avjlHwT!R)YEQ(FQvFDH9Pkogv&hbx#f7#R}uHD?4(GWQ4i Og~8L+&t;ucLK6U0m1GnE diff --git a/Resources/Textures/Objects/Misc/books.rsi/book3.png b/Resources/Textures/Objects/Misc/books.rsi/book3.png deleted file mode 100644 index ce11a89b0e39cc89b90386cd6b4f771b9ce8a16f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 265 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?4jBOuH;Rhv&5D7f3x z#WAE}PI96|g2AhXKz1Hpb`ukWKlR^wY`D|TCM7I6!Dw*0`m?q~M8y@!8XyRjt)Kg_GIq-^)Ey$tvujHaDf^*rHEbZL>=VkDttCOa1xVmz#uKYWz zQN_Td=->)wH(3J}*$@B!wl|hCY)rVqxR_5Oicewbvfn>{8kWjBc**iJ)$hBrq>tHQ ztzyxw=Ieg@Rd2|toMJp+rs(Lrp)qoEn()%R4Anz{>=&4T9_rAlKi+rh0MHu@p00i_ I>zopr00VYj(EtDd diff --git a/Resources/Textures/Objects/Misc/books.rsi/book4.png b/Resources/Textures/Objects/Misc/books.rsi/book4.png deleted file mode 100644 index c5f1aba4f88fb3037a86abaac0c6cd74250230bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 266 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?4jBOuH;Rhv&5D7eSd z#WAE}PI96|g2AhXKz1HM_KJ!>=@oxx*+`$8m%8K(W58*9{i4)_hk@w{&!@UhOcN0~ zuyX1}mAMN(w#YJk+POl5IsYT8!gD6(jSv2R6I*mea6a3UCmms@KD-dT=;i6%;^ozH z_0DehNfVt_#Cxm~t}r@ZWc+`>ULt~BfZI(LXsO~e2BEB7^XJP4-(*y|@=@W#^V7as zmJBzfl$P68y!{g0^w#l_%!XukN9PTUpIbJ&tdvgbEV#mG!oU#FsBJQ7!FvgyKNvh+ L{an^LB{Ts5fT(1n diff --git a/Resources/Textures/Objects/Misc/books.rsi/book5.png b/Resources/Textures/Objects/Misc/books.rsi/book5.png deleted file mode 100644 index 18172241ccf543cf2175717a6da12b981501a706..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 255 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?4jBOuH;Rhv&5D7ewn z#WAE}PI96|g2AhXKz1HM_9cdY(tr3Y<2@}Yp;^pu<K6@+@iiZ+u>0Y2ObM1=psx=R3l^qLiknIGrt?wf!H yZ^)^fW8BOk-NZXXf4=XOU5e8<++`h@85mj<o;K9A)it#xFc%AT1eRkQP8?zMk#C z9xq|!%s=+g1UG&g1ep*}2*Au;*M&1|0q*5OTq}ryE6=-vjHEN*IF4*7P)en1l|qOy z7S^O`s?rjMW7uDSy=A@LS9#to05g9F(1B0}sLbmCZ6UNWkRSxpqTucomsF~~7C@7^ zij)C(znQIdmH{3_=cho|)Chnn^$S4drn}Ko`COO-P`Tro9@)VR0Go!|%!A1>2D14+ n4@v>}zAtQ|qke^O0QiNT4!Tns3Oe1^00000NkvXXu0mjfDxZoj diff --git a/Resources/Textures/Objects/Misc/books.rsi/book8.png b/Resources/Textures/Objects/Misc/books.rsi/book8.png deleted file mode 100644 index 6ba69a8c482c525d9024fcd7efd5f2907354d561..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 289 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?4jBOuH;Rhv&5D0tb^ z#WAE}&f94lxegf!w5<;)Fce^4{y@Rx2g5!GIoA)WvA-oIxlU;CHkqW?6)^jtW8ma1 zyg@tbPfYl;^EZe1yP_W(1sE9H7!{VTnHscKh(mFcA4C6>(=XXRePnV=`BpN|_r>wu zsgae8dl~dBlX>_yu^Lc@Il zMgav$hgu`YhyTB`0*#-VQ!P3=s!-c>HI0{hB-*&YoqY%mGl#KQD4+ zVBt|`VCR)Zk!BPWz^RqdB%Pq~gdG6#xu_@uZ}9~n=K=$<;Q#g(qSO(e2E@dOR?6_| z712sbON1O8gw_1`L6VU}Bo`0~4#&na*v_6kFb)7)zIZXo`l#XnaxEv>0U(Pm{Ru)5 z(_>i&7MmIgVbe4UK)yU23$ZZE;T6M?BS#pv-|_>?d8%!qPZYo$G3|gD!_#|za9aNV z{Ri4O0ND{w8T`ohIYkaYID#_EDRKa{z|eF6C_AFF=~52B0HyIxz5__8>3)8GOl1d< zP{)J7pD#D5XaR4Z#M?6V4K)ZfIu1Q3p^H008?oXgcoQ RW)c7Z002ovPDHLkV1k|plJNil diff --git a/Resources/Textures/Objects/Misc/books.rsi/book_boneworking.png b/Resources/Textures/Objects/Misc/books.rsi/book_boneworking.png deleted file mode 100644 index 634a1c6f0af51ea599d1c50d1799e5afb3cb3278..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 687 zcmV;g0#N;lP)-4v7Tc;8n!SdGx7xZp>IwiKQRB-zKhQ*yC=XSm4V0tm^haWhF7P= z2t+})fI`EDen{BWn&ArZ+5i?;gJT$nO`v?J!vGi4*0QWRZT7g-5tajkc^?cV;7-$`pZp%;vakIU%C{aP4EDygyf0uk@e}4u V-6QS>v19-M002ovPDHLkV1f@OHx~c^ diff --git a/Resources/Textures/Objects/Misc/books.rsi/book_borg.png b/Resources/Textures/Objects/Misc/books.rsi/book_borg.png deleted file mode 100644 index 8ba4772575f76bd90cf827d6e1634d7a3a13855a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 515 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 XUUrsBnT=L<00000NkvXXu0mjfwrmCe diff --git a/Resources/Textures/Objects/Misc/books.rsi/book_engineering2.png b/Resources/Textures/Objects/Misc/books.rsi/book_engineering2.png deleted file mode 100644 index 853eb6cca42712d3dc47c5b6726321839662a074..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 672 zcmV;R0$=@!P)RG-AHE!_QQm-i!Q=0R$W9;5Zy>n zI%-~MbkQGBP!JJP1a;F7sf)VlB8j>%BB>xKBc#$|4V!4`ril}0!#U^d=;rBNzo3ga z=jc`#`@(bJyyrRZ^EvPNzPyjbKUNMP2e32%-1Xk;?Uk{m=Oahm{&~{+NN=eNX=tdh5%l?ndJ1b&Ddq1*l%Vr zqB8n9AODa8YnchFWcjvL72>E9(aZy2E@ab23*?DUm&}ZXBx;YEnTVHi>g0NY1AVM0 z9~K_5=$=wHK!5i|;Xn)hAIAw6&yf_%JvgE;HX5d+teP)Mk}J)Zsjc$}fVY_ia8-43 zp)tY3=LufE?&9$il~hV49JNwlUrVubCDG_C9#1_tTY51fT>zaQT=<4|QeEk#;ot}k zd5Tx>m*WlW`<3JOrz0d*$xwY`9_SA25J5(@w9Wz}C!I1ioLK-PXM9@8c%Qi177vi_ zh8EHf_H;!=KX^mal9~W_TaFv_^>?+k>dRYNCd>h3Ltg=iTF2}fN=3;40000VQ!P3=s!-c>HI0{hB-*&YoqY%mGl#KQD4+ zVBt|`VCR)Zk!BPWz^RqdB%Pq~gdG6#xu_@uZ}9~n=K=$<;Q#g(qSO(e2IS<3R?6_` z5z$IXON2^FaOTh0Lkw(xjxaDTuR>LG?;c4;l9dZKZ)sp)h;?FMl>fwVIG~-u)}oSu zTtJosd^Rm&cs)6n;eQqb!&_#`ax%%fLB4;bB*wt}<`2U&ZgB=y9tMWPC&&*4k{w{b zd^W@9NhJ)-NMbfp9~sC6Bs<{y@oEMZQ+A-Y|3K*LKf&VvA60;9Mus%nI^fi#R}5x( zVhleySiqV^U%q76a*2b%NACv%Ie=sb`1&+3Y@XD>VD8G#AbQ{t*m4j6(I7ckHvIqo z18p1t10bIxJBnODRxSVqH!RpK4Y}!?3qTfbIgju)DDl}yF^~<&iUOGB;1W>}B1Uc~ zP*jY86XX_%V+2IVGlOIYh)9=Wbp(CV0FIi@S1S%f?&s&nRCWLfbvy|C`Erv=4gj`> z$Y~E=JN=emdyqH>?ASrj5NyCa;Ve<=hDft~)B!XE070*c8E6EpO8@`>07*qoM6N<$ Ef{Pl_WB>pF diff --git a/Resources/Textures/Objects/Misc/books.rsi/book_hacking.png b/Resources/Textures/Objects/Misc/books.rsi/book_hacking.png deleted file mode 100644 index 1642063f7e4bb3e1550cb1ffd8d8632b9154088a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 487 zcmVbc91gqZ9-=cvwS(*Cga3G&uVQ zL{M9UC(+Ol(Gb+qEHoHs;MUP-=im}HH#CS8mO@}$?;Rv$$=&_Z3*o-Yk01AY@B4Yj z@9}R2yOw~~e}JD{ z({Qw?!HKelZmZ6A56n6+e{xXks0jnXpk+;`-FC7iylY4TxQN9d%W^N*bsd>X#XSIS zep@d0^0h<)a1(%=H(0YtlGMwWKohwKLhMF#d8}5^h(@W~&;XVd1*_}lILLhrU9aO(6cGrAu~97I40MriK_HogSSa8+mBLJ^#JbLK7l5Cfn{x=T2$qi=p#P;) z@_F2((`M}S)xN(z4i{k18^6HJfBV*bdl(V`n}#U!;Qd|Gavrn=pt7;ggm5U;=9=-G d2Rwjb>JxBicgGUjRB8YK002ovPDHLkV1n1>)@uL& diff --git a/Resources/Textures/Objects/Misc/books.rsi/book_hydroponics_pod_people.png b/Resources/Textures/Objects/Misc/books.rsi/book_hydroponics_pod_people.png deleted file mode 100644 index df41d9621411feecc26b8468e5a251ad02b3d164..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 593 zcmV-X0W{ChIfD-~RO`GNsJ4rq&IR!PQC>Az66PdyJ_WK!vCSd?B-)DK)InaS{y}*cf$*)KV0I~ zRf`}JYznS}dRC=w*U6=F^bO=Z=Wbh7Rd&a}aY+o9K{b4Uaze*w`G!x&Gbo89Kb)UD zTYgUd{6%)Ye`TdnW7pk=`{iSj&HgRxv8*f-&wJ8*aJm;>MBNj#S1QGch z*zl_j?KPQ959w6eYumO>cQ(Q2cj6FGKr59n7iPi*DCc!n_G*|33*$+ZvZmuWTONq} zb{xFnMPx%MoC0LR9J=WmOX15K@f%?=_F*sZm^pK6$YtMu-)B)q9%8Rah(tH1JtGxT)O-S zfk~O45JEyQhLl!i97_;_5D^%exG+g$leqXUcvuR1$ZcBfk5q|?E&EDbQY8q5!1H2C4!0RU1;09@Cl>imWP z7@l85@*5c-2;TCVG#U+r5CC|dhY$j#6jf&jr&@`Wd7xw*fWxx`>h-z~?0KHH)$4U# z8GuXoG?LF)6_8Tuj0=SV0F6dNg9I&!qgVjzViVIeky293mS}lRgb*5PRFmh$TmS%y z*%ENwj&{4P=L>~`whgWZ`aqfsfIslZzFS_CcDt=hZ`-yG9w_Qx5Ni_#a$Q%Cg%D%k zaTQvDzTanQd1-8}m@T1{(t#(lpDO^|+=Bi6eZBFNQml*3KLQACK{}P5X$$ti-?ShU zpzrtf*r`^4>)+9~ZA{ZdDWzKw*yjomD3{MqK@_tkUHV`?m(OD)jrpI1wOUQzh_f;c zu45x<;Co-``MprTp--l*jqRaamU<(mjA`b{M~aa&c=25Fp!_=2f223z*2ea&Z^A&C mbViT&KJP~Iz0gAcT)zM$)83daP?8P+0000B~Hxqz5dC}`t#f6a@`5o2|&$l+r~R?fp5}~{RqhLtLF1h zh)B2wOw$w%MOl`@u~J27SypFEQ4}&mV%Wnv5K;iX?>FXqYGon}!~Ou6?ufYyHhZc%3sv2YMH9Bo3!&kq z0BDNYFThi6%0;|q_Y2nF`##Wypqb$2aU8P(m6g&mY(wywt4etv;1JwgW%gPC970#a zItyef{HuH;&x^wW$ei(1oAt|K0O)N<`!9YcKQxUFKd&Q!}%!00000NkvXX Hu0mjf;R~1k diff --git a/Resources/Textures/Objects/Misc/books.rsi/book_nuclear.png b/Resources/Textures/Objects/Misc/books.rsi/book_nuclear.png deleted file mode 100644 index dbf95833fdd79e377a89024e13edd91de963b3bb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 809 zcmV+^1J?YBP)GddY3PBfMx_(7P- zopbN~-E+=8_j>W4bp>z*a5(@Tr_x`ox!XsXE_DH5mzxkAF8)Qj*q#fZMcb-D33i$o!juVPZ$CGH zb&%ZfPyIO)yVGH_Dy`_x$?|x+4?){u&J7?_{NuFsOij)uf%m|(`FZ@NEt<_{^|svd z=8=tNK$o|+`Umh(4%Da)D6JM?sW}Uai`_d3?b;(y-@XBOYpJ$a4&Qr;hcgMhn%ltm zQxShE_fPcGb}Q&bt^gHD(!F5!08jpW`3AD9#S?v0w(U`_0O4>LUUI3lx7X3mE4NQR z7>`5R--lvUz-pJmbtV8_dBd_IPPQEGI@)rj73e*o()Ft?dqymF^9eIa!q zPJ`EIC5l5_d197*a4BO4(ul@n*bi3hL#)pPb zF-|&$C~a@!8lCqH!s{*5e^zW{1TrOJW3PZ-(GT#%<1=}L zdTm3yXJ^{x$;|ipW_184!!SNTj-6>cj>GD%W=num?s_ihx}F>JJTD%v6aYmCDFncN z9&s%JW}Ak<_P4^zwHko9@}nmWfZ6j*KNmovBH^3Vr`U!~y7Xpwa zApp_r*#Q_%x_fYt48U;4qaHU`5**%X#&L1oWNB?ixpWTt*%$fmafN21@ zuDfZPM#z8=vN#Ih&;0de3DWf)T;1I6ywR%SN zp);T;3fjDFTXZj12r&>m=G*{OzVCys>$|!vOGwics;UAJaRX5EEX$xMilKHK2RzS% zD2kx(`_ltZ)pfmFaU91G1Ob?)33-kW=}`bXuUm}TYa1P`jjQ{`u07*qoM6N<$f`EIeGXMYp diff --git a/Resources/Textures/Objects/Misc/books.rsi/book_science.png b/Resources/Textures/Objects/Misc/books.rsi/book_science.png deleted file mode 100644 index 47047c958a032b1709baf9936c6b06fe55b7cc34..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 291 zcmV+;0o?wHP)@Tc5e_}9eN`-LBZJrXi1iW5SLc!VDn2-|A6_RL+ESY z*U*pvk;uQpD4`s=QBYn51&Yp&gj&8iOpv5A4EglwJ{yl-KD%UFtDsdtL4ku~HLn2d z>&wpCEJ!)4KtqO%8byhcoFxkYK#J6w(a?1KqW52xD37jfv&L&PP?JYPFJaOzXC3MJOJGE psUHCj4xjVjai^{4!ARsMxC7sySvz04@h1QP002ovPDHLkV1obPdglND diff --git a/Resources/Textures/Objects/Misc/books.rsi/book_security.png b/Resources/Textures/Objects/Misc/books.rsi/book_security.png deleted file mode 100644 index fb1a4028e8f4ac3c83683d1b1415d0157179d872..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 319 zcmV-F0l@x=P)(BbLBOZci<*>0_6T?8(n}*&Ve1EQ_c?1 zEoTSlma_wN%h>@@!1@nxPP)@>p*MhY#sk24KhqRI1eN>X)LTjKg9gJ-Z~^5CS}WMb diff --git a/Resources/Textures/Objects/Misc/books.rsi/book_space_law.png b/Resources/Textures/Objects/Misc/books.rsi/book_space_law.png deleted file mode 100644 index 524f10b76c4719fe9dc921261121e653c67d8a81..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 434 zcmV;j0ZsmiP)VQ!P3=IdgGcf#rN2Uec3=E7EIRIvP-PH;P z79Mp5c3xQ&c}772oO;U`O$a)WpaVdb3jy&I?G6S~K*j$vM5!Y>4G587IVsUaQX-Th zLd`P<(f~!dKzBbo!)3>xlo&y}16;15hJ*Mu1bdGbss1O?0U*m?zI+S!HF5}m*dY9j z#1J9c0dYXfVLo(0Vx#jx>L!p75+sKJ2!KL?6gjFmU=h$)?!X`h0rZ3i^1UupZYQmx z0Gq}5_^Kz#?$0+5vkkO6Ww1c5~)W<`=5083!lq5_r%NCh-Y15|ZD0Wjzn;mG&s zWdbOtEGNM+WEI7rs6ej=VEk)${*h!JQ4RoEC_9^#;c@D3FdLNDL41(EVdVo%45S7G zetv#TJqI8MDUAINY7s86KVNQA#{r;*2s!P+Yp355Y!4FUfJ!0^!3Me$W)r1uXqAMc c4xj}9039Hg+zFV-#sB~S07*qoM6N<$g2#`WJpcdz diff --git a/Resources/Textures/Objects/Misc/books.rsi/cover_base.png b/Resources/Textures/Objects/Misc/books.rsi/cover_base.png new file mode 100644 index 0000000000000000000000000000000000000000..4f6f819a3a116963df4aca8bdda0b0131372373b GIT binary patch literal 288 zcmV+*0pI?KP)Px#+DSw~R9J=WmO%=GFc3w@(nS&>P|3C)!6VqqdJYd`R~0c3sBvdk3I**<0wF^4 zHiArMUPuBTAd&cYGD^|2>lVn4OF8Ge|CLgt{^;PSe--7q_CIwuKA1(gSO4TmcF}1m<~;E8s#B2qHjvs!jrLhlZ}4 z{|JmRkP8t{03h-aNGXF2CkYs1;tKe{9qvpJfi*K|t|5*F5=#cINEVlRcI(7 mrIxmBNs&w`Px${7FPXR9J=Wm9fsEKoo_Kn}uMbiCO>}Lrfq(hEJf058zYz1ipl=w#3HPu^=In zU}&7ei6}5zY#_3~{xiBJTdZG0fRnjr4)+eghY$ZdH5HK%LcFwit){fTv^eMdB?BtP zf5-&e?H23x8etfUG)={K_`d(N(VsHG@puHK6oe4yx{h|c4PDp2=*HtQ@;t|CwGyMz zNI80`(D!}O?REhGgpj)$#uxy=^E@n2#`OLYhFQ(?J}^IGs+?#fHNn8jS{Q z+g7O!Kp_E2sQ`c=2yne#AL@z}fZv}(bpoUbBuRoi&!r1Bn@s?KVHo8zA%u__Q8K_e zmm0W-N($03jN=%lX~J=wyYF4sh3mSNXT|udoCDGX48uSaML3_&m7)cYCPNjefx%#a zBuOg8itC>{e+B6$*zfmLZE3{rC((H^%UG1c?D?#p67v5dUsd1JHMqkxZctOx~@ahwDP_5;Q&f0dc9s*oH2&YW>Xq*T^EcoFvigD_Yp-A0ARPoO4)~C6iW| zOeXL78O>(18l_as=X11LE!eh=dcBS;%PP7o%MgYk;y8xqc~6=B@Zq2G3+bf|^9JeM Q!vFvP07*qoM6N<$f=!SD=>Px# literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/cover_strong.png b/Resources/Textures/Objects/Misc/books.rsi/cover_strong.png new file mode 100644 index 0000000000000000000000000000000000000000..61baf7b5778f1262b40dddb7e311c4d26f3fd733 GIT binary patch literal 470 zcmV;{0V)28P)Px$kV!;AR9J=Wl{t>;KoCG5-GD67*bxFD!2yVTByPfWH~^<0AV5T100fc&Z(#5; z!I$|n%;KJ5kb~hRos_CyS9Pi2$&Fqgr(NWHQN2(?ltyCHorB^WIzDP?&T)9%o?~GM~@s^?LOCed0KN6C!KkY+Xa6X^Q5h(o=<^reFsT_g)^GPYo5%>-d6^NqfegP>ZQc4<) zhE_?Xlo*Bq=nrvkq3<2VlWdL4k-Y*r}nz@qLn2z= zUNPi5tRTR0!1qa0g3D3sAN5DMD_ScVE_oJahkJ^?E?6`<_{|mdGDijn7Z;b56*u+OAdsgX;g$tC?SMc63Dk2w-HWSogY=HK`}*J63>p#jkZuxxnwry4n3`?gh>{ne{qBZA*{u_Z^a;tkk SAJ+xCkipZ{&t;ucLK6VBy;Udx literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/decor_diagonal.png b/Resources/Textures/Objects/Misc/books.rsi/decor_diagonal.png new file mode 100644 index 0000000000000000000000000000000000000000..50f6f591834c155990cce00c1d40198ebda72db9 GIT binary patch literal 246 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}8$4YcLn2z= zPTR%T33Hm4a?@0xj$Pjw2<(q&oASGIFLFZ}NJa6!<|@>vrW zoQ(3{%zHJ8{cdmCrfbs4HS7M!@0Msg7{9yE`!= literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/decor_middle.png b/Resources/Textures/Objects/Misc/books.rsi/decor_middle.png new file mode 100644 index 0000000000000000000000000000000000000000..ca4ca82114c9c87b69ca5cb8b1ae0a6bcccb7e39 GIT binary patch literal 173 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}>7Fi*ArY-_ zFB$SR7;vx#nCLyab*1xnd|Pxuv)Z+daR)klyY&8_wSU5{z{J47k&<@y^qF{(%1srF zp}E!PVx7a&yfl6DH|@_?SaKlp^$jNX;|JmvstX8y=fA_WROHr-<0e3DI|>=sJ{LGO T!Rfs|&`JhRS3j3^P6r)<6{Yn!`g%dY9YWzSs8smQ3%^)K#{j+6`2%ZRA# z(6>9+I;wPN^z+$Xub%Fh!WOZHkI#XD>4WY8v*r2+HhD7`AD*>Yp5eexE-%fr!=Vgm s-&iBQ^EEux4!9ci`S&E(iKW&v<|v%~e{b4GphFluUHx3vIVCg!0AU$MIsgCw literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/decor_vertical_middle.png b/Resources/Textures/Objects/Misc/books.rsi/decor_vertical_middle.png new file mode 100644 index 0000000000000000000000000000000000000000..75f141ce40d4f667c43efeed5ec3a3cffd66dc2f GIT binary patch literal 196 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}b)GJcArY-_ zry24!D2O<(F8tY|T_DMK&NU_Zcx#KGIvcx*fT`LyUwcK}d>w}q_h-5_E4BpX3oR&g2c3KWIV`;u#5V*l6qOP3w*FE(JLAcG5e21RyLGJ=tg791J&OCj zxKzN^xa_&_W=C2qa^air@?=}t_cNvp4YszGhHQJ~HZ(EvBsgd#Jbfs+H13ePvfcll bjt;)-Q^mim*42mxTFl_->gTe~DWM4fCJjJM literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/decor_wingette_circle.png b/Resources/Textures/Objects/Misc/books.rsi/decor_wingette_circle.png new file mode 100644 index 0000000000000000000000000000000000000000..a9d9afc120782b87264ef3ef0d4c1c362df51e7c GIT binary patch literal 213 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}{hlt4ArY-_ zryk^OP~dT0UC77O{XnVbxKfEAPxphBot=!{S0pC??|b4bZ@a~Xf#HMUWHX86HTSA- z73HO^DL!&W#3^9^YQAYft3fyV)>>$*iTZpu2h6pSaYc|5IUO)|rQ^*0z5cUfMsr@Aovv;#Tmc$r)}FC%hQ3Ug3McH)_#)oXMXVBQ&7%lwqE~*cglZ( P)-iax`njxgN@xNAg@8R? literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/detail_rivets.png b/Resources/Textures/Objects/Misc/books.rsi/detail_rivets.png new file mode 100644 index 0000000000000000000000000000000000000000..53a4c8bef4ca7536b978627c095e3fad0d156f2d GIT binary patch literal 142 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}9-c0aArY-_ zuPzj1P~dUCDEFKHs-lI@^p2HnoCib&{@?6+l9j~9V1N2dy3pxZQJ`MDh%=^yS!0x(2^Q@!awDZAY4C}=C54^5jroQaq&g%Iq z85@q2_T0<;EcGg#vCWb>;Y(lQxfh+j)n(yq_l?&SpGsO6@A5>yhT-xa^<(!!oIV5H O$KdJe=d#Wzp$Py&1yg$f literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/icon_atmos.png b/Resources/Textures/Objects/Misc/books.rsi/icon_atmos.png new file mode 100644 index 0000000000000000000000000000000000000000..518623069e8e56f266a1f3f23f86ef52559859d2 GIT binary patch literal 246 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}8$4YcLn2y} z6C_v{Cy4Yk1sYsw{Q1=V|KYg5fA0T#`oDfxgvS0t`#VaXPxlAts2&&eS&~)p;{Az^ zHykMi|8DCC^(xD^K4TSfWTs<_VErGF8=s^D#tB8H9YvDDzUIZPSs?4MBU?m z|3688|8Ktk&kOrl9rtZBqS7W#VY^V<|{Ln2z= zUfIZXSV7>}$NF7X9Mkss$Q}P1x3FbjQ+1qfa+}b>gE#qF*W{iT(72Odbn*8d=YtZ- zJueN;7r(Ymwpdir6IgrBb+=%G%<*||e=%q-6?0-xXmRlJwB-tAcrJ6V`daDH>i%NC z=>7RD?g6YTwg!1IE|}u9_Uj!6C8H;E7*AL#D?Q)ablk+WqC7Ej+TU-t>>oaVqO?hT wSL}M5?YZ&ymwVprTz^#J_VTTU$No$e=hC$=ysPL8bUXutr>mdKI;Vst02!TSmH+?% literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/icon_banana.png b/Resources/Textures/Objects/Misc/books.rsi/icon_banana.png new file mode 100644 index 0000000000000000000000000000000000000000..2c2a65741290b7ca97d94b98966746b8594fb01a GIT binary patch literal 193 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R})t)YnArY-_ zFK*;KY#`F|(B3V3$w#Ys>cJJJ>lOGPDD4PH40v$o2FsU=;Mv}8k6v#NjjFyc{Y>*Ex0UPMj^+KcZdclrs)*?kji;qOY&{+aK4Nv4nRJ*@ qZsLW?_eQn#|74Q#XU;U;&YYsFb8Y>TD|dm;VDNPHb6Mw<&;$Sx-b*F` literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/icon_bar.png b/Resources/Textures/Objects/Misc/books.rsi/icon_bar.png new file mode 100644 index 0000000000000000000000000000000000000000..3bb7e7631f9268a3e640dcee2614297684d960a8 GIT binary patch literal 218 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Q#@T9Ln2z= zUfRgZWGLWrvHk?_1(t=@5uH<78jLg=<1!91af}o^Mt|ZH=n?zJq4+6 zBUUpC3QlC*SshrhdZFoyY5e+|C4@@FoDZFuRkkilZuU(9XQl@`Y6YAhRoyr4-Ki}j zr5|wB+b5YVVf)UK*7J|vJuQiwzF#-~>XkPx#-$_J4RA_kl>P3*!kAz6f- zzzzr@!RhvnQ?q~&LWq;OFhO-)=j~nJ_taZd@(@BE$8lXDguEx}6Ru2<_a4?-#28_% zh4-F$1^{qlf}C?mDZv=C?uQD9F#-ULF&Ksc^E}f6z8;*WY4S8pFZW&79W#WBhXDHWSSH>`;_!-jvZL!?^isof&zW6ZT)vdM8JqBS zyuACUG=Jq1#-hf1T7I_u9d&2_U*2+I8lMIC7rqyHlW%{tnVwkM+lQVszE+2Dqoy$~#1eNf` zMMr9OFuz;pp>kVhlgX*y-~a#r@q=m3dHw7I9}1EcBhxlcSlrpz*ytE@eman9e0aY9 zJWu_;dWGu}mxL9Ketdpxta?kcoWb-!gZd$$t!@W3Bv=_l=j*)YR_|F4bQy!EtDnm{ Hr-UW|)Ou1O literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/icon_cabbage.png b/Resources/Textures/Objects/Misc/books.rsi/icon_cabbage.png new file mode 100644 index 0000000000000000000000000000000000000000..e9c806f92e25fdfdd989bc373155574ec490e728 GIT binary patch literal 439 zcmV;o0Z9IdP)Px$aY;l$R9J=W)4fYVVHC&lui2X^S`=K2$X=j9q!%KKRBCC88Wij==r4%E(V-y} z`V$&!YtW`_sHG(o0txSf6@?I&1i7Y#SlQOlYgya6xGv^-ENCc-Lbd)3z~$bJslA`GUkN~vWrDvvjrX-KH*xvS6RD?jNt96jiIiHcs~ zUS!dROV-SG+W+GL#EF{nt_9XDS{?6rfMg`$7j`u|J3YriY9C9r&fu6QzA(RdmQm8J hTwv%YNRsrYJ^*#iO&Tt4 z3f3$vOP4(O^Zoq1iLy*OPco7c5)vM4i|#5oz~x@lt9YL=ed3KrDbfC_>=nGJ>;{1g zrfW645pdvbX7p$|mJ)4wLdGHN;lTq9Q8JUGIeLMXbGaQ{z`!6~qnKYe`}TC8`xrc3 L{an^LB{Ts5F0oHI literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/icon_corner.png b/Resources/Textures/Objects/Misc/books.rsi/icon_corner.png new file mode 100644 index 0000000000000000000000000000000000000000..70b68d327ccd07162249c512d83c3ed024a95be5 GIT binary patch literal 137 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}&YmugArY-_ zFCFA$FyL_t{61eNJB8!?H<1?%tpPvs8BJZ78rWB9O}cV7Qq$nzwsNjJ2e)l5>Qu3Q hoxi!RjtOW&yhW~+#%ig>;opHA22WQ%mvv4FO#nKQE5rZ* literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/icon_diamond.png b/Resources/Textures/Objects/Misc/books.rsi/icon_diamond.png new file mode 100644 index 0000000000000000000000000000000000000000..268a659194e695504a7c035898eac45041d75cb4 GIT binary patch literal 193 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R})t)YnArY;~ z2@rU2;gA8Apd=StK^Ip$%LjVQ#p?>uh*;9ieD186*wj!IMLq7xTKP^{CHuI3roG_ zQkS$vr`Iz#=*4e5dwpi{YKPFRm7K2x=XnPN$X`^C+t_g;xa`pp=kH2W?=}G~V(@hJ Kb6Mw<&;$UTnmG3W literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/icon_eye.png b/Resources/Textures/Objects/Misc/books.rsi/icon_eye.png new file mode 100644 index 0000000000000000000000000000000000000000..11e47cd11d39a70139092188cbceaeec98c9b376 GIT binary patch literal 172 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}X`U{QArY-_ zFCFAP4FVFJ2Y}UZSaNxeBcj1>?MU%VZ zZvR~Kym<3h6VdOgK`W>K*~Jps?tSS?$`6@Cg3E(S%Z=CTeQ15?Z}3N$iD3it&pg%h TYf?2p?qcwC^>bP0l+XkK^?^Wa literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/icon_fish.png b/Resources/Textures/Objects/Misc/books.rsi/icon_fish.png new file mode 100644 index 0000000000000000000000000000000000000000..7baaa1318568ee93c75ec992c2509f5b8b21ae39 GIT binary patch literal 342 zcmV-c0jd6pP)Px$5J^NqR9J=Wl)Xv=Q4oc{jaw`%7$FG(3w;B@N`w_F8&U8%7SiPfd<6>|A3#XE zmUgky&c@n8;Vz4yAY>sr7Gd*))!YlI<|{AEnR5>_1BPK3h9~vgsmSZ5gzB_>ii#`| zfN1xN@kKk>gc|u6NqN~9$&qT%2{NEgpvV#_?}xOiDeq~Y-)onB~JYJOm)JY6L&pGa%6Rpe~bpkM(gM*Xy zzvkx;6SZFKV*pr*-KTMb*A|@ZP3Av8+)vkg3#vg!nnMI2IU+ghTSHhxzHG!d1@9SX oj1AN)37Y@KSDIsgCw07*qoM6N<$f|Z1gegFUf literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/icon_glow.png b/Resources/Textures/Objects/Misc/books.rsi/icon_glow.png new file mode 100644 index 0000000000000000000000000000000000000000..030f8188773d6e9a44ad2aa33c346fa1e6188c8e GIT binary patch literal 230 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}3p`yMLn2z= zPB!FXa^!K17YldUuw~=i=!(w0m*h@zS29%#x_yt%k&;%-)H%~^FxjE*kP5SFpor_o z_Yo$JmpIBPx#>`6pHR9J=Wk}+z-KoCWr5@QvvRQL$fD7eysyTEonf{x(cMT!tY2)T=n;BG;k zVYdhlDsqL?Zj2qJiA?G-*aYS^vs299Kc4}^Fbu=EGMQ$`d*3_fPJN7#5Q0i;q#1I~ z(XQ90{(i9_grJeqB`}}O`mf!Nq9_0u?e}c9Tb0(0W(Z(9nGDbFFdl1VbOz?$vwHpH z@cqui(?3nCKHhoXwNaBrmpM$Z@sDs!!Z6WKcU_}I{hAD(*OVf07*qoM6N<$ Ef}?JQUjP6A literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/icon_ian.png b/Resources/Textures/Objects/Misc/books.rsi/icon_ian.png new file mode 100644 index 0000000000000000000000000000000000000000..04109c503641052daa2c59f2a1bb05665bc4d34e GIT binary patch literal 390 zcmV;10eSw3P)Px$KuJVFR9J=Wl+Q~7K@`V7Wq4flqy*s{8oCMw#^ANTK?EW264A-KNB;#0FTr9U z^e1HJtw1_>-OeG=VV#2qFWW(OO@iPpSeN<0z?;YW@trrrfWzT%IR2SEN$}ehaTKlX z)A1&E+9C!h6yW$qR&!qx97RxTwyD-t+H~3?uGST`W}8IZ&IAB_zT5*)QF*2<;)=>| z`K26W$^wd|LyD!W*&D|AFDe za(V6%^vju=Lxu_DRD)$_#&BW*7)~t9&McjT6!8RJkGcf@h{yL2!Z1W@jqi^zrVHHd zR=|@PaG^B-zCQvW2%a(KY%RnLV0g8f5BO7$}6Sn{{3jU98|`~IO(kN&7zd}#hX_ODplyZrytfi zqUNrXpm<#H{5(4)&ps`_gy#YYEk7dyBl{;tSk7X~I$|koD&xedpt+;NGhs=Z>m(sX zoyNrO^jT>K8QEVr_UqrDEG49(erUeE-JkkzUj*A+4gSrw-tJ*K$zVtQ_e=lpT3=r< mrOv=kZ)2bVm)pS!j0}E^&HH(O-{=Rrn!(f6&t;ucLK6VTv{;$| literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/icon_letter_N.png b/Resources/Textures/Objects/Misc/books.rsi/icon_letter_N.png new file mode 100644 index 0000000000000000000000000000000000000000..7b1888e8c6aa60151d78b7febb46ea962db4970e GIT binary patch literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}ah@)YArY-_ zFC64NV8G*iamntC|66OWGrZIk@LK3<*cP;RvHriZ?6kDBc;})CGX9&l_s!9nE3+VO zj@SfIMRpe#uNE1G1?M|VSEwZD?RJ~Ox`yG)rH0+z<@*!TzU8ZT-_s8)3Erd%w28sf L)z4*}Q$iB}e&9Le literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/icon_letter_P.png b/Resources/Textures/Objects/Misc/books.rsi/icon_letter_P.png new file mode 100644 index 0000000000000000000000000000000000000000..12da61a0701403eeebfe88d0c2f3921119d92252 GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}xt=bLArY-_ zFKy&KV8Fq0z<Ce<@1~yCrf`UJ9PSfq^Fs#mByYxR( z!(7c-k-XoYBuK{zZ$8_2i1*9Al~z^E`9afp3jA}@t_Uu3JyP&}(iew^yftPF)j3K^ bn~IoP>*SA>9{qn9XfcDQtDnm{r-UW|puR%F literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/icon_lightning.png b/Resources/Textures/Objects/Misc/books.rsi/icon_lightning.png new file mode 100644 index 0000000000000000000000000000000000000000..92a115d2b6bf25ea262b3c5d0350f7037f490d6c GIT binary patch literal 181 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}`JOJ0ArY-_ zCmrNHV8Fo~c$M?kJNpDDqo$YLj2sgKRPM{)JSL{tB2Z*>Yc}HsBW8wIJPZbJb#?33 z%AH#n`L?udpWPouhG#EpTV`6ld(qf^e&MG*@wuW(Kdq*@zj$=K-*6A3d-ZDH_i9

JI!(yuN1If%QPE89ZJ6T-G@yGywpXU_>DR literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/icon_magic.png b/Resources/Textures/Objects/Misc/books.rsi/icon_magic.png new file mode 100644 index 0000000000000000000000000000000000000000..80e61b35ad38bacee8d4586ac151af403bed5610 GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}MV>B>ArY-_ zuN>rUP!Mprc(F>wEQ#|{Yw8WwX$i_~zb{VaJb3wC!k#nQ4L=)M99&#l1P&E#OfS(r zRvdTt`Ij?4rajVr_PL>`=8nJBp_0Px$5J^NqRCt{2+A$7-Fc`)0N?h68*q9u-g^LSk@n9@0-hvZ2>E_06ol1zo1lpz# z^#2=8;5`a~#D2yA0002q+On|f4!*L`6SQSvt2*EGA_Pl)@$$u17HG@D-Y-Wh>o6{$ zD&caai=e&}vGToNf>oWH>~t`S7odCb#>n?t02ltcK8F%1#mwLP9MmU^)l;}R(^el7V!iC_2%1ecJ7uOJ@)000000KlJ6?+(xT zZLY;zW8VfMQY^|;wq!tK>f%%VM<4qM2=aL+l=;c2cV?vX0WtUI)%nZ^_#DK10P_LN o2mH)eAh?7qdPx$2uVaiRA_ieW91j+G>iIWf_008)R60YIJTI-(kBw_cn*4m=;&{qPLy-qP63?cI?rBHrlf-0V-&D?K!95wiP% zp^=y~1bCy@Lle|AcHzAEhyahkxq$Wl9YcUW3BOC-TdJzZy?|G9GJr^WKOoEiqE#-% gz6gh4GXemBJCL=iN#8p(EC2ui07*qoM6N<$f(;0X!~g&Q literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/icon_magic_knock.png b/Resources/Textures/Objects/Misc/books.rsi/icon_magic_knock.png new file mode 100644 index 0000000000000000000000000000000000000000..506dfdeaee7111d19d1bfa83cf796a5231979da2 GIT binary patch literal 368 zcmeAS@N?(olHy`uVBq!ia0vp^4nUm1!3HGP9xZtRq!^2X+?^QKos)S9WNUf4IEGZr zd3)QDugO55^w;#2`^tQWC7}C5IvJ-JbC8H zLr-U)Rm-&ABYx5N|E1i}iEHv}9$^42KJ^|j|8&^j;p=zC^>=G3&mDeI12ptcxAj2{$=^EnTEak9c)I$z JtaD0e0svZPx##7RU!R9J=WlOYmOV literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/icon_medical.png b/Resources/Textures/Objects/Misc/books.rsi/icon_medical.png new file mode 100644 index 0000000000000000000000000000000000000000..36799b2f95eb42726182571c54d44f79d10f5442 GIT binary patch literal 180 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}d7dtgArY-_ zFCXMRpuoWzaEo=%hW}|f2Uyt0~QkP3{+)HM9Tm zbH=Fb+ZJxNdhgW3u4ebm%wHJCYtVioXWq28_JNOh1?HM>c%ywH?&q+7zCbqVInZVXPgg&ebxsLQ0E-MkDgXcg literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/icon_medical_cross.png b/Resources/Textures/Objects/Misc/books.rsi/icon_medical_cross.png new file mode 100644 index 0000000000000000000000000000000000000000..970b6d3b4b65c2820fceb61eb083f4ea3faa21d5 GIT binary patch literal 215 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}6FprVLn2z= zUQ*;^QRHF0uz&VWhHc>wm@4>AdwOt8JHsjHr(CU$*IZh9Y4N`nrA2YO4UgH>GR(MX6>;mV-2$NF O7(8A5T-G@yGywqbrd9I* literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/icon_mount.png b/Resources/Textures/Objects/Misc/books.rsi/icon_mount.png new file mode 100644 index 0000000000000000000000000000000000000000..399560fdf65cbe5964288378fab9ac40b52dd278 GIT binary patch literal 311 zcmV-70m%M|P)Px#@kvBMR9J=Wl0gcDFbqXA(?M|OAp}8i)pL0SujLW4bLC3#5ZMU<>8x5tnb9^C zVW1C$6qBEyv;c`jB9ZuK5YZr_iP3n*6cbTQd7J?|IT1n37Q_aK2)eFw@$CkRqS(aJ zEr<*tqWPSJrV zP4DEUX$%0sx~^aUTNBI-<2ZWjdL>p>WwI=TBLfzt6fiSP)8wUn`Uc9fbZb9repD+q zutzDiiTCGFUXtefMv}(C2AEmgPx#_DMuRR9J=W)3HheK@^4I-y~!g)I<`3U<_E8fUT9Kjb$FdVk=7p%MApq-NsT( z3LnNaK18fsBaE3P8=F}Zh{ck^at6f0`<25m=Wv+|LI@#*`0qAsE_wy zDg{7&zs8(*rvg?JSch$$M_k_x@y$J*s|R$PIE7mmFlmO46ZYy=Zn`gAK316M6r&cH zH2eJm07fmC=#+MUlfmc>fadWo=Htt$fYTO0{vRNp$~xR-3xp8j&wT^b9ZLhpv>tx| O0000D74Xb^DX_-QSKz+kKZa-z1_K6UwsZ&A^zMVG>J2LDiAV{||g% yyB4Lp`@KGU!<%zkuX)t1X{wAYC>0Z&C@AeBP%M_u$?_QJ90pHUKbLh*2~7a(j7@?7 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/icon_planet.png b/Resources/Textures/Objects/Misc/books.rsi/icon_planet.png new file mode 100644 index 0000000000000000000000000000000000000000..784dcd088276c9137effb2ec0f23e8d2e47f6ea1 GIT binary patch literal 311 zcmV-70m%M|P)Px#@kvBMR9J=Wl%Y-oK@f(&mV`E!CVhn_s1-FmgQ7_V2GCTkLswO7f`qKD=mT&H zQv+zkc`%3}P5K5n$l0sdwzP6Dxzx;;Og1yKGxKjYyPznFqA1FdX;dk))|SSYoi8F} zSyri6bdmSI1aNr@r`-@ce+R%h7u~NJv)NkvKm4i(lUKNV!6nxR`Pu{+W5Td$4!tKR zHuJiDT%NLjEwu;$;Osf9Nh8?zBm4ljm(i`N30RH8$!9n4`2d6aV1LW{1&9c~c!T*6 zMhUc+K}=ENe;0^Iy#lsR&0l=LNh<_bWBga=ARoig{{cl&lr^N|NgZmL0?7aX002ov JPDHLkV1j#Cfwcet literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/icon_possum.png b/Resources/Textures/Objects/Misc/books.rsi/icon_possum.png new file mode 100644 index 0000000000000000000000000000000000000000..5d25c82a913203c1551f3c7fa9f270d585844150 GIT binary patch literal 337 zcmV-X0j~auP)Px$3rR#lR9J=Wlrc`jFcgMABTfJgBhAvi5>uA2F*9~39XNmwlQS?y3eFXpH8&`W zGen9Sa|Sb131qYj1Cl?sS1I>$}Z0MPfncP;N0D5VxtUlc{KICxI5Qp!Dlym5Cc0XThH>h*3iAvizD zzZ=3~7^v5~@5IeH_e0eCNqV;+%d$nRwe~Hszvz?)?O^`ZJ;bm0U)JBO1a2| j67&)M#?2#vuDnZ+#Gr}{hjowD3?DLd^2vQ&hKDg&|Lb^uf~nf*!T>O zOUo1?hJ@SOrUguWvcAJ3d;6+;N{367{#vi#FXpU$YWaM=R{eR4sX?=RU8aB4xLh9| zx|c1^jQQ7tzd8|mj!WzIyQ?Ooz4^T_tO@80>z_=_UacA%?LJoneZk=A>gTe~DWM4f Dt3qUB literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/icon_scmmd.png b/Resources/Textures/Objects/Misc/books.rsi/icon_scmmd.png new file mode 100644 index 0000000000000000000000000000000000000000..d64e9bdd85d4cd9958b8c26e22bb29cddcfa15c3 GIT binary patch literal 280 zcmV+z0q6dSP)Px#(n&-?R9J=WmAwsvFc5{Gqcq-vf=RpqOVCr%x}~CL2{vF77v91pDWXFMN|1aA z7s-8%v25)7d3OdBMN$48le2l5hc(26y0Z8-x~9)MGmB~T>y`CSJaabJl?CvQ1c1$J z0B}uj==(MUI6Ty3kc5Zirx4TW{5AvVqGPCOE-@s_0Ddurorhnd0Z|HE(;MPx#$Vo&&R9J=W)4dA9FcgO2R}uWd&C$O>s23nEom~VMuhhkB=;ETII!Wm$Z7>{l zs)JbSA|!$!oM#CMoWpk#0!k^R{?T#~=AZU1YCc7`+nxDrl9%^C3$R>-`Ebyq*=iSO zSFto2^?bFCDz5#it_81Yx7*#@>U#^$0m`mozbW?%V9W&(%QzSTFb+nDSd6*+CP1_~ zRN~|e!2WmwAWqIin}hTFdj$Y6S&E3I-|al7&r+W@0C=Sa2&X~u4SlCqN-3oP9_lAb UA?^Pd$^ZZW07*qoM6N<$f-MGcKmY&$ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/icon_stars.png b/Resources/Textures/Objects/Misc/books.rsi/icon_stars.png new file mode 100644 index 0000000000000000000000000000000000000000..0970ada3f314c9a5ce730976c12b3e3cb6dd3077 GIT binary patch literal 181 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}`JOJ0ArY;~ z2@NIc9&fuehDvVDaxNWOBu&D7J!}Rqp zg+#5(bN<)=ytMQGi)jyqmd{l75L~V)v7yC$6SvZg{EOU+7&%)RJu7&4nl*TV1{-j- au>vi89Nit9H8U8$lHZ@!%p?R@~3;m-ao>net7IVaBRkSsklCei0CyYRFLi*>%n%4zH;|TNpfD{an^L HB{Ts5MMpXH literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/icon_stunbaton.png b/Resources/Textures/Objects/Misc/books.rsi/icon_stunbaton.png new file mode 100644 index 0000000000000000000000000000000000000000..d247b9163c5ec989bbcd9a88a403d3520b7bf092 GIT binary patch literal 183 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}g`O^sArY-_ zFCFA;FyLu@xV)l7)Y`eQ|Ixwf(w29R`1Bshi5;xIvryCRN$vM9{0kWb1p`$l?U{0B zYv`ljI;UTDO}}t-@^p#CcV2&}lVRBM(NB7Rk=uUR-e+?k{Saxod(%Dt!$Uj4@^d$j gFdi`RbNLd@FT$hGpz&@0X`tl{p00i_>zopr08AT73jhEB literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/icon_temple.png b/Resources/Textures/Objects/Misc/books.rsi/icon_temple.png new file mode 100644 index 0000000000000000000000000000000000000000..54bb81a404bc969f4a946a27971db9cac58f3c8c GIT binary patch literal 381 zcmV-@0fPRCP)Px$H%UZ6R9J=Wl|f6xFc^m4&T6G4%5c@A6G7-1t%gdMd`vO=j7R#aI=oC{*!5k*nJbsGQxA=Ur@LIS+JzTu)3YH7MU#Q@-W#{hhF7D8-#XHKPM4m4(8qbh2o*22%fl?Z0oXK9dE&KO3ve#|Pj5A3ojZO5-`UapZN{D(5 z-}g-=erJH35mePmh4Ie~2q89EIQl08buB?i0LRgqy4@N0tUh*<0WG!@(7C&k51nf@ z3DIq6JPF2|kdOd*zEl}F@lG+B&iB6w0jRfcHqTL2D*)RKsgIU{l<{OTo&We58M&}n bECf#Y%1F(;t91oz~44$rjF6*2UngBIaMQ#89 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/icon_text2.png b/Resources/Textures/Objects/Misc/books.rsi/icon_text2.png new file mode 100644 index 0000000000000000000000000000000000000000..c87370e75da7ab47f478555029d369060e6c806e GIT binary patch literal 167 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}iJmTwArY-_ z&lz$x7znsr?7S{;F#5^A)Vv8n0{j9l8@fYPbTqdKtp1-c^X`Ns6^4e(8}my`zTbQ{ zUCGQ{)mH8O@j1m)mweteHE7l6O>Jf7fB#iB2A!I1cr4-mTRx!q>)9jt9Kv-U*M0?Z O7(8A5T-G@yGywpo3_fK5 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/icon_text3.png b/Resources/Textures/Objects/Misc/books.rsi/icon_text3.png new file mode 100644 index 0000000000000000000000000000000000000000..ef03b24174fb8fe88f2928ac9140e8f4cc07956c GIT binary patch literal 160 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}QJyZ2ArY;~ z2@xDe57lqL<#td*g0+Q#VSbi{p-ECw1JD)*Pgg&ebxsLQ0ML3f A!vFvP literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/icon_time.png b/Resources/Textures/Objects/Misc/books.rsi/icon_time.png new file mode 100644 index 0000000000000000000000000000000000000000..13f0267eb5e36c53fccb7bdfb22450cc42aa5dee GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}?Vc`Ly?xOor3sz0DI&OMl*0Z1Hm6}JVJl<@&K-Yxt z@Yd7Y1t#wQ&!;$J`URWDjw^GF84gs}pZ6BHs9eKna@F9FMTzloppzIpUHx3vIVCg! E0LjBnPx$TS-JgR9J=Wl)p*?K@f+(h+-)=xfn^}DZwg|!W1#hA=n$m%FZW96GVK3fcOM< zmge#Zhm8b7IJnM$=j9;(8qvb`EM#K{7S4eN^uB7@*_q#OhuMXQh=_>)PAqI<#ViI| zJi%}@;Ie!dx{f%pVip4cC9cI2cXz>K~h6zAQPtt0(>GnMU>J1a$?Md}z28N>nrJW-FqlfSI@NPXyJ4J44Cb_)9 zlBSCdh-TpRZ4t+|NUvw;_C2p(`0G literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/icon_wrench.png b/Resources/Textures/Objects/Misc/books.rsi/icon_wrench.png new file mode 100644 index 0000000000000000000000000000000000000000..99bed38d3c63fa6d465ce7b904ad7c0c116e0b68 GIT binary patch literal 473 zcmV;~0Ve*5P)Px$lSxEDR9J=W(@!YmVHm*i@BC)`nPDgSQ?jCjY(!T6?AGjVjWiCE1GSmjV#xuy ztfIC(Y*V%^DXiLqqx;?*wmn!5lsydD%`}8G#4=d>!{X<0aNUEqxV@kA^E~hKKJW8_ zrfHg{-I3njj{?xq*(WM_#$6oV)$>WJYYOS?{vd&uex+RH2425vlNX-H@;UfO*1tWJ z$?-BdKVHBvoQ#e3Gc`T0RL`yw+!6>#DD;(Pe=1!q`=q$-6y%sVPx$2}wjjR9J=Wl(DVCFcd{^0+uD)a*y1yMixlH4s`Yolpcc4JEUNN-!TJiHh==5 z7@7p-M;~mFz^Cx3tmNhS+V|!Gi9{li_;#$I)qiV91aX`!U;Q?ZXkI*fZw1u=7Ox5j z@>d8QC%>K<$+Q);7}Pu!9*vPqkGbLy^H72EP1!CF?-DTyZ<`lGzdLV-o_`F-iH@yp z|Bz|0g6eMbzKF4D56*#(&GEdgvm8dUqR#UB=Ihhtr(F-N(nhlJx#*u90QyZGCq*w4 z_gUaLSx$ESMzYFrq91wxD2%bE&tgRYfbz|*&Sy}*0RX70FZVODQ@$zH)nk3StgN8b h=6GJk^i3qbf*YzoN_Lo^tlIzp002ovPDHLkV1gP?m4N^N literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/overlay_dirt.png b/Resources/Textures/Objects/Misc/books.rsi/overlay_dirt.png new file mode 100644 index 0000000000000000000000000000000000000000..43d2d741d7b1b07d665723de698d863a327db819 GIT binary patch literal 608 zcmV-m0-ybfP)Px%8c9S!R9J=Wma&TyK@`S+N3h1*(qg$ab)&W!}KqzD$7&5gO_b{55J@-?%&yq)ix_rCXb zVU0D`xL{lg4OCKWc()C=4z#ho|02K_qK)l&f_B`xsf}&>F(LcastRCs`kqJdR7tT7 z{8Umr15)5q=w?+*&;aU=q`+U5p;UlJ%o6gsh~lEEn9ve*fJg57p<6crqmAt~jE`kk;+e^l*)g7h|!`X^LU z#7c@p8@sEdxC>mv^TsMv&VWmM$36ZA+|B?Wc})uc*XMaSfSB*u1QZw;-5D2j067evu6{1-oD!MPx$0ZBwbR9J=Wl}`$SKop06h9H509za@pfiBc7x=jaa83irNbto955KNn%nK?6W zbfnFEAR-R$_wnW*;BYwpjK>{V9k;>{GXzokT_A}eiV{tgBZyLXNelp}uLmqw8*P2I zz~izL{qUb+@9_59TWjn4TmfA;0EnWL%E(x71?GY+&{TQ*rbk7$8&(8}?o@DPRIt|o z1qM;dS`S<)BY}Qlj)+wOlR)m+QByF~-k}4^x&TSYLc4Hxfw904Q`W^K0h3)ZivURw zV?@{o(er**{vX=~b_e`0vl>iH?ttu$;GTp=cY#g<_;f@!WyS)h{jDvmDo$OX@eYSW Z#|!wvcF89-BVzyn002ovPDHLkV1hqTf^q-= literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/paper_blood.png b/Resources/Textures/Objects/Misc/books.rsi/paper_blood.png new file mode 100644 index 0000000000000000000000000000000000000000..b0ed27ad528221596340e4986230f5725963c417 GIT binary patch literal 686 zcmV;f0#W^mP)Px%Xh}ptRCt{2nmcX+K@5hSzyX3*O1(uyOF@p1lcdanQszcm&{FLMR&W3iDUe|p z&BLCxcM$k%fC26Quh;VsHh^ImhG9G{FVr7?y?>mR#~rMO_GWy&2Ix9~P1D0_XkooR zkN@>O{0;;8`dod~LGADM))!TuZ1AUPPX5jNpef|D>%;<}r9Y<{$cY1-pGL@t1RQ;i zhu1PYbR!yUnjSVyFXDk502D-VDFY???pV%84t55(sYnfm6u8ia#(fV|PvkYgH9(n< zo2CaCI9KO+kb)HeG=NANDe;ifKYy2h0;~XVZkTGI6w;PRSci(HKxlr24oDOOrNrhq zH!Ibqfc93H^FY;S2Oz{0>%w-nfaP(Q)GqNbDgc~aVJxAWN5<%nJ_$~B7TC@fSr7Q$ zea%4*K*|8XG+ScI1L~_Sg0U2w>MX#S0-S6l2OzZw`CH@Vv*0lRpFVXVq{3PQVksEf z1#(lS6v|Xw4J}!poB{g-z}r0iBml0#*dJsAfcgNpLGXQO=^KV&7=~dOhG9GuMg0MO zZQdP2p0YmxL30n?ACM|f;Zu=Bt3O~=VI=f9RymS{QX5q350LsDm%Hc>$d#tG{~@m4 zACNME;CGstP_;h*P5AhxG|S_X{Q0ifjqh`vX$NNniAu4RR?^y+0sVYjd+e<1|>kKOkqK zv_4;3Ut|i5sn6HeXDxy;BU7}>-bH_aYa|A@K3`j(-5=nan5sTsTi-AY!+1pg0g~&n Uf3HS9=>Px#07*qoM6N<$f|4&U-v9sr literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/cd.rsi/icon.png b/Resources/Textures/Objects/Misc/cd.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..346d8c162a920fabb4dc5c692bdf7c156837b70f GIT binary patch literal 361 zcmV-v0ha!WP)Px$BS}O-R9J=WmAy*DKomw##5b@JoMQ4QQ*R?|mqM6o3r!*GPbC(Dg(4QwVyl2f zx&@o9=TVX(fi!uBv5*aJ*gz&(u$j|MhTQXUZ!Q6k$K&~Dg0U}#VQBxJrIZ+Boa>DW z5Qd?BUu8Sbgb>_bUO0z1I)r>nw%!oOvE6&wgHzf*xex+?v(pm*qWNraCkA(*PyU^) zT6tABRCUAa=NC$;L7i|OL06up>D$N416ADsP?jZSSyB|mpc=+9JfFzWwZ4LU}xrCt``w`o*#A#0E{ug z^W%Mco+@_^0FWd}5Y1|#9ABXFpY$(GaGB4H2n neifaE2UzWtj~C9lT*>%qtrgFStzi~GS2K9J`njxgN@xNA=O$S% literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/diskcases.rsi/icon_cargo.png b/Resources/Textures/Objects/Misc/diskcases.rsi/icon_cargo.png new file mode 100644 index 0000000000000000000000000000000000000000..4bee922d75418a46b80fde7f2af1b62f1d1c9acd GIT binary patch literal 234 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}OFUg1Ln2y} z6C_v{Cy4YkF|zfvh(tt0{CWQPadN`X%K0kI_O(9`7Cd>A-1Ka-K+u8X$B$2#GUdpJ zXRn+l$!vIgL3YsFS+t>X)g^shI;9`_; z_@=urVBt*W6I(?jc`B4-3fL#evOZC=_~S=j&p literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/diskcases.rsi/icon_cc.png b/Resources/Textures/Objects/Misc/diskcases.rsi/icon_cc.png new file mode 100644 index 0000000000000000000000000000000000000000..a0dd3a87938ad773547a8cc75fb11534487253c5 GIT binary patch literal 239 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}D?MEtLn2y} z6C_v{Cy4YkF|zfvh(tt0{CWQPak9n1f=-p@|9k(Q{qXcnbknoV0zn6kA3r`}%9JAo zf8*Fa`F>P9U=4gV!^3DQTSA7F!-c>}ju!%j)aQ#h81N=+{`2?WbBmu#nifj3GQVp0 z{(Ju7BbHY4LmY~v8X~*;{e{^lygIBHEFdV$G=;_3mG8%wm%@klRDPDQGZGMAV({Vp m+x$(krd)0ZH6&O|SQ(yuGGh9Fxlj=3Xa-MLKbLh*2~7Y~ab9o$ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/diskcases.rsi/meta.json b/Resources/Textures/Objects/Misc/diskcases.rsi/meta.json new file mode 100644 index 0000000000..714b0b19a0 --- /dev/null +++ b/Resources/Textures/Objects/Misc/diskcases.rsi/meta.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Made by SlamBamActionman", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon_base" + }, + { + "name": "icon_cc" + }, + { + "name": "icon_cargo" + } + ] +} diff --git a/Resources/Textures/Objects/Specific/Hydroponics/lily.rsi/equipped-HELMET.png b/Resources/Textures/Objects/Specific/Hydroponics/lily.rsi/equipped-HELMET.png new file mode 100644 index 0000000000000000000000000000000000000000..374a7981d0479d7d078025fee7a0b3c26d5cb69a GIT binary patch literal 341 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GGLLkg|>2BR01_nlU zPZ!6KinzD8HgX;c5IFX+d+t>39SvoA3i-^{(&+^Z-!~MqTMIt)Rpe6;E8DoaOQp4A zW95g|iaqtOo)mq5EV$$J%tFNpTOB4w)%I-sdgAkz70-k>zuma$>${0E#-{8~|1!I7 z*!AP|*&M5~(CXk_ED1Ywx~ntG_JwizCn+>AFmWJ=65R{0;_JWuR%}`K`GxMjC9>~y zs}FW>W*3kUVq#8f5rd+ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Specific/Hydroponics/lily.rsi/meta.json b/Resources/Textures/Objects/Specific/Hydroponics/lily.rsi/meta.json index ddbda4f0af..782dc2bfda 100644 --- a/Resources/Textures/Objects/Specific/Hydroponics/lily.rsi/meta.json +++ b/Resources/Textures/Objects/Specific/Hydroponics/lily.rsi/meta.json @@ -1,7 +1,7 @@ { "version": 1, "license": "CC-BY-SA-3.0", - "copyright": "Taken from https://github.com/tgstation/tgstation/commit/40d89d11ea4a5cb81d61dc1018b46f4e7d32c62a seed modified by potato1234_X (github) for ss14", + "copyright": "Taken from https://github.com/tgstation/tgstation/commit/40d89d11ea4a5cb81d61dc1018b46f4e7d32c62a seed modified by potato1234_X (github) for ss14, equipped-HELMET taken from tgstation at commit https://github.com/tgstation/tgstation/commit/4f6190e2895e09116663ef282d3ce1d8b35c032e and changed hue", "size": { "x": 32, "y": 32 @@ -27,6 +27,10 @@ }, { "name": "stage-3" + }, + { + "name": "equipped-HELMET", + "directions": 4 } ] } diff --git a/Resources/Textures/Clothing/Head/Misc/hairflower.rsi/equipped-HELMET.png b/Resources/Textures/Objects/Specific/Hydroponics/poppy.rsi/equipped-HELMET.png similarity index 100% rename from Resources/Textures/Clothing/Head/Misc/hairflower.rsi/equipped-HELMET.png rename to Resources/Textures/Objects/Specific/Hydroponics/poppy.rsi/equipped-HELMET.png diff --git a/Resources/Textures/Objects/Specific/Hydroponics/poppy.rsi/meta.json b/Resources/Textures/Objects/Specific/Hydroponics/poppy.rsi/meta.json index 8b6952d030..b49b49cc85 100644 --- a/Resources/Textures/Objects/Specific/Hydroponics/poppy.rsi/meta.json +++ b/Resources/Textures/Objects/Specific/Hydroponics/poppy.rsi/meta.json @@ -1,7 +1,7 @@ { "version": 1, "license": "CC-BY-SA-3.0", - "copyright": "Taken from https://github.com/tgstation/tgstation/commit/40d89d11ea4a5cb81d61dc1018b46f4e7d32c62a", + "copyright": "Taken from https://github.com/tgstation/tgstation/commit/40d89d11ea4a5cb81d61dc1018b46f4e7d32c62a, equipped-HELMET taken from tgstation at commit https://github.com/tgstation/tgstation/commit/4f6190e2895e09116663ef282d3ce1d8b35c032e", "size": { "x": 32, "y": 32 @@ -27,6 +27,10 @@ }, { "name": "stage-3" + }, + { + "name": "equipped-HELMET", + "directions": 4 } ] } diff --git a/Resources/Textures/Structures/Furniture/toilet.rsi/closed_toilet_seat_down.png b/Resources/Textures/Structures/Furniture/toilet.rsi/closed_toilet_seat_down.png deleted file mode 100644 index 738c92a6d361f4ddb1e3fe611aafc897329d39b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1445 zcmV;W1zP%vP)f? z2|){?XcKPQ1gV>F`N299XSnlxZ{B_X?V2W0+t-n@73x#!)vbMO5P(J?<7j=BC( z9e@x9T)fu1*L?DKboR`-a9CoOP*TF9ZHp-cuy8RzEaqJJz<&t0H?-l^3>0suNZoMCCx0n!KHT1^5lIXRgi zDgmGaBp{=sqqPTs=>tG>Iz@c$?CeY!(S7G;AwB>s^l>_rdFm~I#~>CTAL)(hZ#%$% z@u|i5Qr@uul$Q*20TIeR6#%e4f*(HrVQuqRU0qG$008vk=l5J$003<3+T;jffeHXF zE}fvw0&8n)QAc6~Ji;DI$>7y`fn z=H&z#g1e$l*Z;NQ_>l(y@yEjKqu8)i))t4D*ZKw@t6~uq0Gc>}mWOb8#sLxl(wmN$ z?|8XAcA5$q09n=6o zh|`ywA~3<`co+x3^1nW9s|C(Qrmd=k_k07ylGV6vb{<*^oX z5~kDR_j2+O!2l2h+ZNDxUG1K?jUxa|z;FxzKyv250H{QXO76AA1aiIu*#ea)P|3Ye zetqSIcZ&9|yFpI4tS#V`qJRN#z}jg;wqn%)pjAF}TpfT=#AOW{l)DF8~rLTj4=Y284MO4Te-Yt8vqoKDPqERI{!9l{cW$ip5;@06DR?DjRBT zjMrAFVOZIP$CrXIYa?n|RU5l1s|Yac1pc z-|Mhhd?13R#W{JA#Zce&W3kpWk_1J5wiQmS`GBknj2ROg=5GTS?Gb>ic*RvUawbGf z5X@!-Mv3Lr<9wFYUY8BrP+mU8By+P$W|s0o~#w_&~u-!~R4jTYTcblALZ2@gD^2CMzzac!RN1%)c z@VWFg{RZgrAFhIFJu9sBxV1X2&VX9AtX8kTnW^1a0OLSk00000NkvXXu0mjfobIH7 diff --git a/Resources/Textures/Structures/Furniture/toilet.rsi/closed_toilet_seat_up.png b/Resources/Textures/Structures/Furniture/toilet.rsi/closed_toilet_seat_up.png deleted file mode 100644 index 204c5ff89df0d7ad1e4bd2abf6df7f9cd4c68576..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1553 zcmV+s2JZQZP)Px)%Sl8*RCr$PTTMt+Q4qdD>sA%CX(Mfml4%lFp#%?yBI_=Cd% z#a0(rTjc2-=q-?@!a31bSd)<$0327hgDkG7L>VpfCj&qsbW$QiR89bp12FNTvaTqk z-ytcpBts?ubROV~$55PMGFKiT0g$-{L#{6*X9wWM^;;#iEr}2Sdh+y9mP80y=;G>P z3;Q7lH%83;wNVCo2TYl$i2<11nvbXE;ugmS5GLm)OYr5om$c{i_?#G?Fe#6@%>Y1% z!)Fc@U_z)S2+MzezhxG{0sz{O3DWv zc(yn`Id2jGu)^@faM@pjKxZ^JIhWn~5&&4)7y7J@uQC9nB04-hXVGq_ z`>&ZYz)DddI(v-`e9LaPOR-T)pbmUH0MvnMlg8{Yph?!ML)H!hQcy)KM*GwaN6H+# zXQ7E-<6&ZH`K<9(|e-tA~aLYh(At(sUC5 zU|C$=CZRzI0Be?Avf@hsbiEzbmL>uqx6HC;2t9d%T>|j%!DDBIheb%qfF?LW$pBqQ zl}xyO=VsvrfJ$R9G$cq(0YJ)3U8G;5UO@mzAq@bJ!a1Pj2r7q{*JJ1_b98*tXz0Tw zoCJWRiY!Hg0s4**5Z)^=q|(~S!L!5j%fpgT1-o1VEH#I&zrgb&eqtHmkqYB``5=#| zixE)XH6Q0EAW#f)`0f<(_ztJsCIF~3(e#zXbKefrl!wFSZ8cZOW{AV5D+EebqfH5b z%mYF!@Et|#L35o6x_k!nmDpvikgT-+P97jLLD#vP#d&d1d@^;m^h<5S)Rq9m4r;a2 zWBf_%5ALIoDX>kr-=V54UiSP!gHj)HI{_i?Can=JuCos$jI4MF-yM83a zG@i0(*(89zQzLIdM1!C&Bm51&4RZaK$#st?bYvE+2)VAO(3AeH0O(~CyD$+1fK?(S zAKKf>t!9-|+1UDyz1P2Cl(*LCt8issR)1V$nwNm9GwIfD0HmXK$ysR$SPvulJA%Cm zfifS!|N6?Vk2$`(3+AeDjFL@#-vOYhmdhpgf6sv5>dmib5PItT00000NkvXXu0mjf D0+_@x diff --git a/Resources/Textures/Structures/Furniture/toilet.rsi/condisposal.png b/Resources/Textures/Structures/Furniture/toilet.rsi/condisposal.png new file mode 100644 index 0000000000000000000000000000000000000000..c60cabe80b18aa8a578e2225633f58de1b405a5b GIT binary patch literal 31043 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Furniture/toilet.rsi/disposal-charging.png b/Resources/Textures/Structures/Furniture/toilet.rsi/disposal-charging.png new file mode 100644 index 0000000000000000000000000000000000000000..cb9ad3a9c75d02d9915666999f56fa89dbcd3d24 GIT binary patch literal 31052 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Furniture/toilet.rsi/disposal-down.png b/Resources/Textures/Structures/Furniture/toilet.rsi/disposal-down.png new file mode 100644 index 0000000000000000000000000000000000000000..97712ddc65380c3b71547a3b31bc8e6263080778 GIT binary patch literal 29554 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Fun/spraycans.rsi/clown-inhand-right.png b/Resources/Textures/Structures/Furniture/toilet.rsi/disposal-open.png similarity index 64% rename from Resources/Textures/Objects/Fun/spraycans.rsi/clown-inhand-right.png rename to Resources/Textures/Structures/Furniture/toilet.rsi/disposal-open.png index 27b68e2cfe5d2b364b379707b887bdfcb115eeb8..f48f67bf9a6467f84373d16fdea11b6b28e5d682 100644 GIT binary patch delta 3261 zcma)8eQaH28Sh=!b+f+k3B$u{mRj#-Z%}T&gT?L&-i+ zkp?pfD&Z^&CNt4YmEQJhGM5MXlh>#eO)kz@hjlQ0#@np@^IhFWEZ4ETPmAiEyMe-_x@><6tB- zfiQr2S)n5s87DC#3_Qf5`6|D0$s?JtAw=tdYsBa>C+#@021-&m1;Dsnr3f-n!vrKn z{#WIENo6AHWCSz{bJfNzBI6TB!4ha$P)e1!N#&_m3ZTa>mZ3RK&4RuV?f(>0xcsrTUwD2KUa8fhw6 znSrzhGQe<1MT12r11Eqp7FtE2sKQV}(i$T#DbX~j0I;?p9bLLL^VG$tWkimpPvL#Y_UI2W8mN>%-a<`il(7fcH`ufs0R$Fq|SQimbQXoTt z6wwNhi=en7?Wl7iCQM+KK%tBk6!E|bazGoT7$<=T@Y|k?xe=2w5e^4Xo&c#@;*nJn zpb8?|;wUh+UFWuer5SX9JJcfB-)7OU_7ERrHNpJL|`6?R2UO# zk%-1o3G>b)NZs1PHZzm}cp!ICX@{`o4rvXm&x8JG9Dp5cHs$3Y_d@&M+1H{O2saaGE=i|#-BVIXH{NT7w z9b!9BdgOzXo^X&HB<`5jV3-n;6d~7#$~)?%RqtAtpI&xJzU2)+ z$rfUs?^>w`Ucc)W zm8rfTCw0&aF+vqw zF)-k4XAiS6qN_|*xoC$kK$z+tJW&~8LUP!OMPQf(47V1*T_z+XaSB$r_9WlAQWpS_ z*ExXxSwJ9m+2b6+_uK_1e&%@#41*{a{gk@_p+*yJLx@;~p{JJWU7!`0usXZ=Sfwm*C28S?Vr>Bo=XdHAxM z|GxJ#(|`Nw1^>Qc+jWDxe{t9Q-}d4Y>{Ejm4#DHTz5Aaz`RnU{)b)W6e&fZ;-AC$2 zyRZ7lE&bO{e4#f#y5*t|uh@8Ma_6Ii;_zduKKA*UZ}mRCqxsVZr++tAejgZLcgxqF z_!C{b93WJecR3d1=b9&egFUf delta 1117 zcma))Z)lZO9LM);w_$hPx@wNu%m%)j(d0s>uxin` zV_P2m-40c@**jGWGTddJmMR373LmJ;Lh!W5Az&fW413yy#-`)xVz9lowAsG)*wu_t zNFhcE2tg5qlu7V?5hCu3ogKG%p%=NJdM5G`p5H1dl&@5vGC$-+m zNFfoWhJa5L1A$mnUO+j>sDFa`Mk`~AHk-V>=70`@R0x-Xah<|_8vDP+PQ*A%#3Sf1k1#K{?*^^wx6sm z)XHnl{N_1F#5$?5_p8h8>iRwNOJlPB89SO>Vb|x@%xh$Y)47E>7EZ01wU@f;dSi|2 z8uHyg-TrYn@g++3{akdCC2&dr{jG`Z9ffaq7+MYR9cVM&CYUtB!8i8=E<&`F3_} z(3TD!eC76AXL}D_pBedX^R|^^Q=g7ZH#$2ft|Ts<@7R`FRr5(8O(14CtJwmKhubAGS$YVV%Du?WSA1)Hs%72DwHO@T?CvaP* zaMW+_!97u=xjJ6!7+!)r4)Ep^Yk@@LYYb>63sU*~zXPgG|1H1nZ=5lA?l;N~zHem1 z@R2eI%(;dhI5Ia|t(T8%9&FMrqn%zZ4GuKBH1=;E98D)2*fYIjV7#{A2KbQh4H3~m zq=qPuqA>c!0Y)ebKI<6gTY#tm; zCtCb!-`Cvy;zZSY8#|y_I-=)GbcmFe8)VJmnE8VXv(2ShQ*yIz&Q%+AjHAnro8MP! z)av_cD@?ig_KFjOC)3l5b1%Ezxw&Pht~VwR0fIK9%Z{wi+%fM;J6*kYaKX6AL%5ZV z%iVpwvD0PT$w3O;mnGDwBrDKK-&qj^ccikyu=JhQu%=A4SUn8T%Hs=8H);zrwc6}R zOI&w!crh?O-W1P)ckixLZS8P<({O3&kW6qgYHmU|+z2Bq@CnEF3>9U_HYM*Nv`k1B zkyg(oG^T5|lHAdu5&DGsjLtAt4rw`zZfya=t?bkORCUX4I^w=NRal#|-RoNkO% z=JZ}yny>C1E@ce{ZQmWzTn9bhid;2<_l4E0v z2a{o-S}=;WlLlT*>usstuQFfkT}Q=IX!$;nZnC=JFarXLHGn3x)0l|ajM z+nTA^a>h9V7_8vVm!S%MN}cnyOt`O&iiy^7Xz1$btU%fr?HI#GAS6pkTR$dvF~Sk5 zf>07=dR#RnE{=Gjec?E7k=BMszS03VDm2XLuvgMlC!ier)&_Blw2Z0sp=m)(0$~`Z zy^>}k4pNv2QBe!)*uZqiC?XDa_Qt~#JXs)U4oWRf=4Iim+Hb`Pn1q_`H%t7zt$O0x7sD$@wo^;3qVzl(*Frsah!EWoz zK!!#U6NE{xyA1pd66!$ulJTHTT4)8~Bfvazitt{AFXq^FHMSL)q9)b?5-th+5Jn}l zk%jf^QPB+zIhVp9)`hk=T^!8>YzTvG34{t<;Cdy^V&|lAejFsWzgU|RTOQPF0 zq+g0|5}43f1*!McG^&v6K6y_zFtFAZ(x#KP4bh>|zJyQB7&Qdq-Xqr7vX!PTfi~K< zr`oSw#%g#3DpJ0pt_?^W<4-uhLChEzD(cmpwD69sCG7veQ+0>~q=0Y$>-MVqg|$;g zhZd$XL#fKkL*fPuG#PwR;Jnq%*g zRwlIP2+YBc<`({=aI)<^^(#zri4$Cf+7BY#c7oxg!kv^_aX84*>0XU$!YB(QgfA4} zWy`3N1kfjNQG>v+DDIgwXYix3?P7s#d)>EHLl=c0sn4VrUHAS3(usrn?>M%tFm8uQ z{ffX67bnsp3_y(7-eq72DV$&xbIWytJj1F+b#DdPwN_%G*`x@RH3_lQBoTfXLo8zB zlppg1MgNI*11R7514RSGX20ly68>MrEcl?p2%QbPMtOt8|B z8((p#3JXkPQ}55p)kSS7QDv!)rHFiZwayO{0b9r5c{t4xqg&*{>80O(LMY-9q$QMw zl?ZJJhYo&=9|a+WZNi*6{QjjYMG)&i*dk3}ar>GYUq=FRV7b#NSvX#+G75RpA&Z<6 z1z;i+u`f6h4~&Hp#z1OhG=V4_u7D-T8LpD3>ktdjo52A3*mj&R!VqbxB$9C9lvOn0 zgyj&S4zVao97QCMswVE0!)hr501^1b&@AlGe045&h)IH=f)eF(I3zw#Qeu>8pTqrN z0+CbbR(C@>#1x~D3S=o$pu8{`zU5(pya5b` z5-~B*4kvSDN;@mF$d6b=nm+QDp)UeN-*FNIcws`?I5IjxdOIgK6HcuPpqL6!*H+Z&KZH5NkCX)2!oAS0khT=7bcp!v)HecrcQJI z)6?Z`)p|oCi@j}PBt@zMxmQUTY49F78;BT-Aoo(y$mar++!?RR%n{;P( zkX}B`5>UyRM&K2Ps=W=wNbmW^#sYx|(mSc6(3+@=*hLe4V4;E{pq}mOlio|J!vr@I z2Qm%tu;B^@SW}iJwHENF*@aO=}^_SOSFqsj1IrMX#79kYh52&o5%%-THq=m zK|xLAqgaj%IAsVKl@5tQTHho{&Gsa6X}&j_A*3Aea-dLAeD$O)Rq)pAW}mL^b#|oG zSx)D|Yl&&d(<5IBS6NWF&n`^;0F6Hxs$Ox7B)&_lg1s`0(zKLJNtvW&;DTvw^S)-Q zvWg)|ZOx+L>EQnASQYCQDwkqcx>jjAFby;<>1*en*KA3VzH=tgFnTeIe1WhAX(mJw zl&d68!w@Y{3@DUx(GO~!y_l`6VXI#=(-P#)5r-lON3{@j_SAv4i0o0giBR(-aB}q; zm=?@XSq`Fd$O}u_Sag&-CZYpu+ksxX1819dmwkDS`DgvJq>Ed_>%b>XW7mYF_7nLb zg7Z&^1d({-g2oX}tw=+Yj_ho;GZY$rKEh%Dkp(GM!C>bJX zCkWq_O^-BCKOkn3rP{XkyGT%t1`#7U1b*N*< z9V#O|1QN|d-jvValsJPiEmAUv3ZHZlfnF@>>&Pd~SH~-qGBc(>29{Lg7=ge+fHb*{ zgCYi1Nn~Q0hl6F}5@ktxp1xv2-1C|P zMVyw2(lgyY=QwR3P@%@LdWQo>F5=E0ShQ&=xlqa7&18 zoG-yyhi1)x1Rlag*Se@R-`kU(6PZ2OJO>it(M&>0G<|Ik?S6ad&|6-4X!qMohh`&p zRV$4VRF|5IS#r5+RQh~!>oMA!@JzlN5u68z|Ce4~I$}rVh@0IrQNd%h_4K5Rz?q`v zn5AzlJMfm326nyC9@tWwuBYdljA>oPv-$Y90HwwM3(&>0%u@EfmEBR_NoNF$Nir;Q zv(=Y98f&nth*^WI$h_%DBL%JbI!aNES_%#qXo{%KnM z3c2PtKeYRUdp1_Drt`mb@{09W-2TGtS3dZe`q=ujo4-68J^#?RZu{=%{$fhKXPx);zkP=n z{&DaJ+rRex1NVN%Zt%#J$DaC?PY!zrp15}X6Zieb3#V=?z5Sc#o*93v`d44Qd*sd4 zGpE-*cGvkcJFb81>1(gwRNH@MZthh5Kb~LzgX=e)J$~$q-+Sil`7;M@UU%z$@7!}= zn0WdhJa6ZdfAsK~7vJJtee)y7KRNieXTP|6i+SoJ51c!3_eUPs_qowc&)u~9(OtW? zTz~J$laGJ?CA@4p_~&1~DtY;;>KV`bQt3DWEwCqMDM z?Hhmh#o$v{T(;@C+KJCbKlNGuCm*6m2hMx?+n2w5-91m-v;RjoZ2YHpA3O2!_a2X~ zyv%#x#gFc|?lWI_=JXG5xcl@sF8|=JH~wIB$XowsYaah|NZla50`%W x$&KZAK0NqUe~Wi{_xCrp{m;*NH{bOyxBk+Pe(zV)k8RvGdE>;Nj@|xi{|mjAC?Nm< literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Furniture/toilet.rsi/disposal.png b/Resources/Textures/Structures/Furniture/toilet.rsi/disposal.png new file mode 100644 index 0000000000000000000000000000000000000000..cb2db2f9d8e9006ef560ad3c6962142e9de840dd GIT binary patch literal 31095 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Fun/spraycans.rsi/spray-inhand-left.png b/Resources/Textures/Structures/Furniture/toilet.rsi/dispover-charge.png similarity index 66% rename from Resources/Textures/Objects/Fun/spraycans.rsi/spray-inhand-left.png rename to Resources/Textures/Structures/Furniture/toilet.rsi/dispover-charge.png index ad3ad959de4138922ea09c84316ad9369fedf403..23ecafa9d8245cbbc5ce3a248e644b7c0c775f4f 100644 GIT binary patch delta 3103 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 delta 999 zcmeC^U|d=?L7QK;oq<8Now5Jv$5aLeYpsn|uNc{aGSf3kiYF&9$*~ndn1alrlNFg- zC%Q28FpL>NWi8jCC$n) zr)07pyJT`jZjMz>VqUtfQiX0xYFc7xPKlD8v$KIhKxtA=X0n1yer{rBo`OqiN@j9m zNoIbYLPkkRft9{~a#1RfUzVDjpPQSXSFD#`l&)U@){_F(qFkWXy# z1pzimpq)rAvC)USZ}L7CvB~pTbkr+y3m^et<(pWPotk17QdF91qmM2;`2(w}idkZ^ zk-4d%p{{vKnz?S8k%^&hl98o>uBCC3v4OdSZ<77i! zL&MZm-6RY16kQ85lQaY46idUT6qCt|*zDEP3=Is;(u`7cO-+-HbyF;XT9T5|l64J} zlZ?zwEQ}0HOf78mCm&#woUFipM1>gTlMQ&xC);yyPxj@wJ2`>hkvLZy@R;(WMf2qS zT*rZds6V+|$dSp=a`IUrDI<(attvdJ;ddi9K@o-U3d6}R5Z_U1dRz~f>Z z_^$rx%WY1M2NOQaE?E&NAUf}@VOj8mJ$`cEOMeJ3FhWs-E}K7lgD~TVF9HWT8Dds% zuXbKt?9R}`)m_cJy7;<4Ld(%`CV{lC84Nyp{Hu+wAgWFx@u-i^MRkC3{~mv z>t;Tgmtnm2{>y)_Kb%;`T3vbgqrQht+q0uag>M-jtUWBv$-FqLQJ?q4#gmO2Q{>9{ z8l2~CpTo19@x#+ea&d+_k8OInk7h}Kv*XnJpU%8jLz96?0UfdT-DhB~DNQw1d#0g?yKv=xo;&M6XTsY@Gd7LgUr}tIuRClFV%-R$X zuX=z*L1=+de4WWA28;&;7Z?|e#ocwbWpl2+8eeSdFyNe08XKVmiVLkXdC9cn zgji6>i{GM(kpN0MuLLEWNfqCrzFiVvJ%R&G_7zR^X4~{A-oh42fIXxA>w+_V1 zdtc?_z~ik+)%@GIVf#~Tbo(*e|1|EIoXM&6PTSG~!A^pd%!0v0gVu&2Edq9dS2D7N zF(5fWsGz){dX(-vpXQ7hTN2M9a8`nrOn{L}17gl_8j#l#ZIT-m`A=4(^@&zGYIG0R z@-Zy5Tj_CqVzu&rdo%~{jCKD(@9cOVaI@DRH-me<%?ui&pS`cBe&OMC9=}|g8ZOMu z&J1pU{Ps3Ylcb)ZA8U)pKOA`$-`}|MW>@>r$)zN%)p!2?u+-=z$;L*OTz#1hi_i0q PlB(uTUz~m3zkc@@TV~i* delta 2210 zcma)7ZD^Hc7~Y&No7;31nZeNX^hG`Te19B7Jx5*4vShCMW8m{?mX?~7WaunHk$yxk zQvOS61q($P6&T4VKafEzibzw${tTK0A=<|uyU+1>rqi*VALqR9dGGsvuKT*L>wb6b zs_oui`@Wv=O!wjZTXoYYA{b%XNkpEBJW<(+I@LrG<()+48P7ACHB96q{&{lZsad2= z7mG%)rJNaETuchISdc;rTqqbx+jQ2_JS%%;()1jb+6qr2!qI6&NQ}s8Dv>doVrDR7 zh7SjOZzF}LUTT0wVn7bVmzNO}!??!ASA&^i3MXSwls;Vx)?NtYxrv&lASrd#U~Xx^ z$wp*2U@2GDiBXh@vw>nBF}@DtzB$?vEh$D(aXwaI6RbW^uIfAxBWYVz6 zViiVU-Z~aM(l+^Pl`Z!cX~8I^#A7&cI9O6+Nlbt_RAw?d&A|fkMj2#CEKeH-=-?Ix z#~h_X8bzv=BZxsuTZT~y9vwzB-tqtx8!m8#jZp?TJr`|s!2=tB`FilE(ujcvYIQ2H zF*c0IC~+JxCsAR;T1Al+ky{;fB4k+mF-0j1w}>fQQ7FhBBcrVmpk5tqsIrkLp-clC zTmta2LM={!D&Z&?^HjMTf&~TlfRLa_W!$%|EEcR;yM9AHyz1A6eEAY|W3`nMF(DJ; zj)N7kW=N9|E%;P(T{Z$*ux0&*xdGCI*DH;?6PhfWkeM<)!nnz8<%^69MU^teDI&G1#;5)FeMv_V&u-9H0Ga|!kOsOYG z!ZSFiG!n%LN(|HFF@+WxWZat#Osmh1Pg(({HeP5jhj1RCC}PaB#|!LU%&7n99jjg7$=NJqwM^7 zSzrB(Y}Osea^nflaHF_&Coi9TE?Ygd0LYAtRvSbGkf|icNc$j=1nCGa9Z^9+1vLee z(oUx=&v|cO!&9|6tu!p!M3JM0BZWbdIsg?KCa9Q8-lSB@Y%XQ8PK@)VWCF=kYO}7U zVz%zio@`z7GWZ?J!Bz~^vxHzD1DlD%hT=pau(;Gl7@V-beKA17l-C3nG@>3{qaBFJ zSP9*DC72d2C3qd+Mt$=urwpXGtLcFWxp9oq-C7{)Yd8T)*zwqS&YwT;wap!%>8X=v zWP4g3$&G7WUT7(fYs9@z+|@!Ro`m;nwrcUb?fJ=9s_FT?`<@vme|ULN{#g6rr2}uK@6CaYKmT$6zDu}$+vZ0vHtX%rZu|F* z(_2^0S+VuXpna*Q?t`8qJUJyh4Rx$BqKf!2ln6V85fdhqhu_Va%q&Al_U@%3ujv@edr_0_9&HM_sO+%oi2 S>vv`R?Mt6ta^u)852Tv`nE5-?b+rkW_8VKHAS<>s8alwS?ek460)84i$ z_Wt;x<*OUq52sS9(PTU&KRr8~Xz9+<)NwoEawMp|e0Z~c=gM${G@lIJR7)EAu^gH4 zh^9hvuExsqp*J0H!&~R@BPr?R*wD~=KPE91lZh9Tsh!S16Qjl>t*0buG?@&I7eb8$ z!i#G> zC`w)@S%RKL6(UsNBFkCDInYG`bPg(VWs)Q@2TBuFmzi^K=jmgTiaBe!sYQ9xX#ups zRDp=erA0(hJ*%3)q!Q5^I|n8iq(@tDp)ilQ?}fIcF5D+C827~IKv$3;RA+t6GQ`yW z^oVPeFwR%5nN4+3Vo;g0YNgDQCyG3GncK}<&aJ5+qzu9^UZiZFTzRU6G(CwXEnw%FZZB+RlW~7^h1LNwA6| z9Wb*PBr){07~?^HoQa^7hd;3eii!@@b!{OSw@=qx`?bSAY#=$VgL2GCQi}>q@Th>} zkS(6myn;y3OhBt7F4X}IiguhOBZZUMX3#pL^z4yyO_H$`X9|m|=0#LUl{w`!5+uRZw8FjW#|(#wV*4A zBA`GYDO0Gh5pcVyKYjj*3xoWbbUqJe{|XFt;2ObeHB3kJBc|e6r0PuIDHPvL@@9MS z=tuV)HrW+YCNLX04r@xx6DW`>)!b<)yRM^qv-&JTbjC8Mt}tB(mGn^-*)F2WI)_|%^C3Huj)Y&~B zTRYMS6mPVN%n-avO6{0;E-)!@J7`wPs&>H&-y{`GyH14}tzpI0I;h-dFDh}lV6cm9 zZ7o8=iqU!0LONisaS0elM5}|WG-IpWmA;N1bg4<_OHk8Y#({Y&zgh4+lwdM+S`}?7uT=1 zt0zb8(j70im+l@mDrPLm0t*t!GHbySoZmC=gXSKKDpf)ld#p2lyUqDP(Lni~{_PL- z8*B)eEr!Yn3|i4$I|9DSltPSH9|dcEaaf4%aUuACTO3~P@2sBOJk*#hOR52}qqNLG zip*;$N06_vlU6Wt{|HE5xguy7!xpl{N`@$1c8Vz>E#4R$Jcr%GYFoI0vI9-C^c@L1 zOLx51-%?~W)?$|!!@%)u0q>?VG9p^+aF;}T;e_i55N`{D3eX_q9YhXGMyEJ>=5x2^ zgeRL);l}K;Cv;bVrh&eZfWjSSLq?`dG%Ry1VHl8=H87#dG5h)^5s;pEa2^bz>I&1y z8e)aLF}yZh&>TelStU;k@e)LS?9n(39 zW!P<;*VwAA*@`kn1> z?s?zAR_f-)=s?4^^W}}>V)@5UfAan93m-ZCz&9Tp54WGZ_WHHUYhU6=mw)p7FF*h0 zcRu*)^S7QFKK|O*FZ}(?%2!_gc>Bip{@CyRA-#F^+Px2a>i+NE|LSwUx^(>YZ=HGe z`acehR=#>^wY~W0yWi96^^Pw8_TI<;x$@j?zt8`^OFz?l<>$Zq+s9s5d!!G*iMw~+ hIMnOC_104FFW)}NhQIjpOE}ScaPsi@mC<9*{09h{QhNXZ delta 1152 zcma)4Z)lZO9NxP>=I*?DH+QFNmb>FRG(GJ6|8u=L@6gf8%|GlWZ7q7=^S*~RMH0{S?Bg4B87H7{W#}5zvuZq zzvs}jH$CQ!%JR*9Co?ZpBrre_K-`O1hOi70cA|nN2tXKM)r)ur;S7T|R*CMue5~?< z%~$1Y^W26wsKM=!0QZWS$)c5Y-=phm;44?oc)CMT+=zV5{tGK`tQNxXNU>SG8qNQLFl40a; zc6%6i6j#ctUfL+ApxYD>fC9Uus>Gao6W1lKqSqkA^#_FDcw3wB3JmFWMKYp;3Y zt)@A)ef9IR8{o?7N9?&otKE=YJF8_EKgiai%Hc=fxNOI_x9z#pwJz6N`2MG`oxW&>(rv^2h09@ z3Jdc|GEDYWk8b&G@|{%|zaIax>(bP&_VUl*bGJIL@17j+P7f6(Tfd8UT$&m@@zmg( z={w2gW5;h)eVaVe(sE^U@|hLm$F}wT{_)7f;ICV6AGo%7;okO~%?;JtO+!_Wm(4GO zWI_C^z8|vt*Cf|&)VGd~?Creo^#O12wF7&W?wTo#9sG0WCoi7*{QX7W_#^+wOR$Zu do|&mA3%C8TY2fnKeWjv;O*zW|XyTOfP$E$% zBm^yl!cDko6Qpj!rSRjtIG_8*nfLB|=IQ_6Hz5B1-n^N)=bpLm&b{}SqEp^Vr(FK1 z0KkUdzhot^l< z*>HVrZLKi@n3|fZ$SVQBX99!&V`F2D2LNoq%A5BU0OsfCqrt(!_&Yv>9b`n${X4nX z0I)D?C-`nX^%lTu5R*@g_QmwKH2^R%y%gUH?F&G7$v_tnzU)&00PVy1fq?j5J17gZM%dQ?s{o(@B*ksU55ljnuSYE{EinKg4WZP&X>SO6wKhl%0OaxEF#OW!3(9q&FV{|to1|-05pjDQZS@1 zP|e&v^Q##E%Wt#(HUMD&Lm5E;0Q$SUPSdgpS%LrK1LG>;A%hwKECPWJFu~;sVsdC6ffEh-nl}*pkO@-za!Y{nuoYU(^I0_j zcz|)iGyw992a<)Zvq&|}^8x@`7#JT&SY)XMd|sGb2(Ep(4WVV%t50kAB=fugz=IM5 zlfrolkGU9=FpVC+R}+Wu27n;g_HXEYZ_Ysg7=Yn@003v{*Z}Y`ULpJ1d;&TCv21~m z0{M&u;Wt-bXFk&2{lM!LT-6rHTtyBYV0*N~`fSCz0YEFfZ@&TnU&I=%f5Cu8)2OdJ z1p|B$Yqb6a1LR4|R{v9PH9wM}@E%dEB4db1*`d0H0h^csw!ott$k)BBg>B+;oe2id z4KV;XWg*goW;<(ZL(H`xIM={%y16C-z?fx8lXdmYxYhy?TDeNl{`B*gM>H>kjP=X_ zS2+*l8-4O9ast2#5O%DWsxPunDpppr@V*KF1|NZxY_d`m*EK1qJhp{dG6M@Q8<>s8 zh>^UP34lb(mUxhZ0b#bh!H`0yrOa*Nb1MK0HM9K1rYYq5T?tCFf5^H3b8Ky<7}|wW zTs1{Z-yw`%(g1*kU_e)i3|}oAI4>3e0I4YRl`Yqi#*PF4(ho>uL0V-9#^9i#(&9EI z%338?a)xV3OWrVp1;d{31f`H^6WE*!0+6TcOxKo*@?E0@C*cX=2Hjz^3M&g~sr@{K zC+H>!xUO9z`^xZn;xs7F1k@-ePNNhAM+=z|wrv3k0zTuQleR9ocJ?!K2S<*>X7WLv zq@U9huUBL{4Npwu`x@%1#Ax!kdp?$RyHTsTh$iOCL{S{spEPDny*6h$6GG@ r;YyemQDLpcZPb1R0~%GcTDkrKbQ;vfWu>av00000NkvXXu0mjfiF=pV diff --git a/Resources/Textures/Structures/Furniture/toilet.rsi/open_toilet_seat_up.png b/Resources/Textures/Structures/Furniture/toilet.rsi/open_toilet_seat_up.png deleted file mode 100644 index 77995657cf61bffee7e5180374375219108ba40f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1535 zcmVMGzPWMTiAqt3W|WXd{w_xCsn|gf=2+h?~GbP-v9|B@zWf zLeN4e+=QDpLAq)k80W$H+<%)lbLaWq|GxSI@$J8PGxwf*=FXja=eH%1?Z)lvN4{6y zzIxXdIb>72M+pn%H(tK+3OsPO^(%m7gNt*tFD0DXOZNtHk_0U#|806IH6ognP* z?ei;IgUeWVVi7w7|;4FHrM z9UZO7uYJ+f)Kn4+LKFba^Z`&F4%X#>@g0q`yu2I*LKFbaV!)+qLq{`{Lz$MBl!lBj zl$8l)0Q#@qO3|O0UrSb(9ywjX@Yv%7fh9=1I(4xt zRT>Ing5O{E>OjDAKEne%-#yqhjURHXO$Pu@@cg;1lmS^mkctSx`2q=0%sLEdh56^^=F)DQTN*-t7qc6fC`tjK6wd-c zSvFV*4W1hRVuXkRAk-JnW9H5UfL5MD0faIDSXfx7+y6r#U@M%Mm@w&P>ZBO}09;P+ zp9cWQV+r_n0iFh9Xy~)3T>l}<%jeel%?u#5;c!4P?UCVq5vIa9(N|c5kq`hJSNDS~ zu3d>TTIP=ifI{fR2rW;R6txQ=24LVtWnH_FeukjT5)7FD&~boNR$2v0bDJzG4v+xI zSc6+`)|Om20Au$aq|~+qLI7y#`O`uIAw;3;+v|1gha5Z@G4|I+8SEW2MWQAKV0MP1 zmYiTrEN*dZ0AY4zHU(dO9GUKudrI4@0tN13$WMw0Emght;(|>S?KaX+@39tPtF?!0IV=FJ(9k!L7+2Q znO!N|`Vs(GIcw{)I=hFpPRR3SlvcU(rmFw|)8g_r2@OgBn6pf&?W?*X z-;Y*B03dfrw>DUR{>d|EhKET=$$%<2LCFA}NR>>Oe0V>}1b|9oFmxnHRRKWCOkJd3 zqh4MBn03(ruoTV#EhVTTyu2PmUzwxhlSackNSJDW5ClL{MW&*`0DVUY2sa80skBxK zo*kZF7E62?>~sk*)$F_e0?&{A6UzWiDva-CLmW{SBcQx%KF&`-pcv%ftrE=~mhVu& zF#$lOiDp(xyy)9uT5vdQ-d1yM+1%pr>DmG%tI;O~K*j++7G#y8^`J%71YJIZ@k;2j zmQPk%zZM5zB1VF)x|_v$aZr3Rbhf+~+lQeo0SFapwb#f0sbgIvs6mkQ@=YQsSGMw0 zMuXs53R#M?uS}oUod)HZfL7&TK5q)Eqc!T7%wsPOIzG9i?Chs&2Y(%hb@4%7K#&&a z;AIv=LrVm*%9zCEq$NPE!ih5<;H$teCZKTGa+>ucDTeWsMaw1u%&Hn?CPXv{`ZB^v z_-&Buw@j{kM81-lHzVY_ot)id*#JmK?UFOs60jB{`8$F}ZGkc#z~B1HZWeR0?klnx&M0x`~ldPqtxPMGKv5I002ovPDHLkV1jyetCs)( diff --git a/Resources/migration.yml b/Resources/migration.yml index acdfbdf4dc..209434d1db 100644 --- a/Resources/migration.yml +++ b/Resources/migration.yml @@ -227,7 +227,20 @@ Observationskit: null # 2024-02-26 CrateBaseWeldable: CrateGenericSteel -# 2024-03-7 +# 2024-03-05 +BookBotanicalTextbook: BookRandomStory +BookEscalation: BookRandomStory +BookEscalationSecurity: BookRandomStory +BookDemonomiconRandom: BookRandomStory +BookDemonomicon1: BookRandomStory +BookDemonomicon2: BookRandomStory +BookDemonomicon3: BookRandomStory +BookChemistryInsane: BookRandomStory +BookGnominomicon: BookRandomStory +BookFishing: BookRandomStory +BookDetective: BookRandomStory + +# 2024-03-07 AirlockExternalEasyPry: AirlockExternal AirlockExternalGlassEasyPry: AirlockExternalGlass AirlockGlassShuttleEasyPry: AirlockGlassShuttle @@ -237,7 +250,7 @@ AirlockExternalGlassEasyPryLocked: AirlockExternalGlassLocked AirlockGlassShuttleEasyPryLocked: AirlockExternalGlassShuttleLocked AirlockShuttleEasyPryLocked: AirlockExternalShuttleLocked -#2024-03-10 +# 2024-03-10 ClothingBackpackFilledDetective: ClothingBackpackSecurityFilledDetective ClothingBackpackDuffelFilledDetective: ClothingBackpackDuffelSecurityFilledDetective ClothingBackpackSatchelFilledDetective: ClothingBackpackSatchelSecurityFilledDetective @@ -247,5 +260,18 @@ ImprovisedExplosive: FireBomb ImprovisedExplosiveEmpty: FireBombEmpty ImprovisedExplosiveFuel: FireBombFuel +# 2024-03-16 +ClothingHeadHatHairflower: FoodPoppy + # 2024-03-21 RPED: null + +# 2024-03-30 +# These are technically not equivalent, but it probably makes more sense to replace any existing SCAF stuff with SOME kind of armor, instead of just deleting it outright. +ClothingHeadHelmetScaf: ClothingHeadHelmetBasic +ClothingOuterArmorScaf: ClothingOuterArmorBasic + +# 2024-03-31 +ClothingNeckFlowerWreath: ClothingHeadHatFlowerWreath +ClothingHeadHatFlowerCrown: ClothingHeadHatFlowerWreath +BriefcaseSyndieBase: null diff --git a/RobustToolbox b/RobustToolbox index 4002cbddb9..6764ed56b0 160000 --- a/RobustToolbox +++ b/RobustToolbox @@ -1 +1 @@ -Subproject commit 4002cbddb9c9de9030a81480b45b13d978b87526 +Subproject commit 6764ed56b06309b56bd35c8ebffdf64882d4c4c1 From 23ed68f09fa6627e5e80d05cd529cf16ac62b833 Mon Sep 17 00:00:00 2001 From: Ed <96445749+TheShuEd@users.noreply.github.com> Date: Wed, 3 Apr 2024 14:20:28 +0300 Subject: [PATCH 5/7] =?UTF-8?q?=D0=9D=D0=BE=D0=B2=D1=8B=D0=B9=20=D1=81?= =?UTF-8?q?=D0=BF=D1=80=D0=B0=D0=B9=D1=82=20=D0=BB=D1=8E=D0=B4=D0=B5=D0=B9?= =?UTF-8?q?=20(#28)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * new race * remove old races --- Resources/Prototypes/Body/Parts/human.yml | 10 ++ .../Prototypes/Entities/Mobs/Player/human.yml | 4 + Resources/Prototypes/Species/arachnid.yml | 2 +- Resources/Prototypes/Species/diona.yml | 2 +- Resources/Prototypes/Species/dwarf.yml | 2 +- Resources/Prototypes/Species/human.yml | 2 +- Resources/Prototypes/Species/moth.yml | 2 +- Resources/Prototypes/Species/reptilian.yml | 2 +- Resources/Prototypes/Species/slime.yml | 2 +- .../Prototypes/_CP14/Body/Parts/human.yml | 70 ++++++++++ .../_CP14/Body/Prototypes/human.yml | 49 +++++++ .../_CP14/Entities/Mobs/Player/human.yml | 4 + .../_CP14/Entities/Mobs/Species/human.yml | 22 +++ Resources/Prototypes/_CP14/Species/human.yml | 126 ++++++++++++++++++ .../Mobs/Customization/eyes.rsi/eyes.png | Bin 0 -> 125 bytes .../Mobs/Customization/eyes.rsi/meta.json | 18 +++ .../Mobs/Customization/eyes.rsi/no_eyes.png | Bin 0 -> 4683 bytes .../Mobs/Species/Human/parts.rsi/full.png | Bin 0 -> 700 bytes .../Mobs/Species/Human/parts.rsi/head_f.png | Bin 0 -> 511 bytes .../Mobs/Species/Human/parts.rsi/head_m.png | Bin 0 -> 508 bytes .../Mobs/Species/Human/parts.rsi/l_arm.png | Bin 0 -> 468 bytes .../Mobs/Species/Human/parts.rsi/l_foot.png | Bin 0 -> 404 bytes .../Mobs/Species/Human/parts.rsi/l_hand.png | Bin 0 -> 321 bytes .../Mobs/Species/Human/parts.rsi/l_leg.png | Bin 0 -> 382 bytes .../Mobs/Species/Human/parts.rsi/meta.json | 62 +++++++++ .../Mobs/Species/Human/parts.rsi/r_arm.png | Bin 0 -> 366 bytes .../Mobs/Species/Human/parts.rsi/r_foot.png | Bin 0 -> 365 bytes .../Mobs/Species/Human/parts.rsi/r_hand.png | Bin 0 -> 346 bytes .../Mobs/Species/Human/parts.rsi/r_leg.png | Bin 0 -> 396 bytes .../Mobs/Species/Human/parts.rsi/torso_f.png | Bin 0 -> 769 bytes .../Mobs/Species/Human/parts.rsi/torso_m.png | Bin 0 -> 660 bytes 31 files changed, 372 insertions(+), 7 deletions(-) create mode 100644 Resources/Prototypes/_CP14/Body/Parts/human.yml create mode 100644 Resources/Prototypes/_CP14/Body/Prototypes/human.yml create mode 100644 Resources/Prototypes/_CP14/Entities/Mobs/Player/human.yml create mode 100644 Resources/Prototypes/_CP14/Entities/Mobs/Species/human.yml create mode 100644 Resources/Prototypes/_CP14/Species/human.yml create mode 100644 Resources/Textures/CrystallPunk/Mobs/Customization/eyes.rsi/eyes.png create mode 100644 Resources/Textures/CrystallPunk/Mobs/Customization/eyes.rsi/meta.json create mode 100644 Resources/Textures/CrystallPunk/Mobs/Customization/eyes.rsi/no_eyes.png create mode 100644 Resources/Textures/CrystallPunk/Mobs/Species/Human/parts.rsi/full.png create mode 100644 Resources/Textures/CrystallPunk/Mobs/Species/Human/parts.rsi/head_f.png create mode 100644 Resources/Textures/CrystallPunk/Mobs/Species/Human/parts.rsi/head_m.png create mode 100644 Resources/Textures/CrystallPunk/Mobs/Species/Human/parts.rsi/l_arm.png create mode 100644 Resources/Textures/CrystallPunk/Mobs/Species/Human/parts.rsi/l_foot.png create mode 100644 Resources/Textures/CrystallPunk/Mobs/Species/Human/parts.rsi/l_hand.png create mode 100644 Resources/Textures/CrystallPunk/Mobs/Species/Human/parts.rsi/l_leg.png create mode 100644 Resources/Textures/CrystallPunk/Mobs/Species/Human/parts.rsi/meta.json create mode 100644 Resources/Textures/CrystallPunk/Mobs/Species/Human/parts.rsi/r_arm.png create mode 100644 Resources/Textures/CrystallPunk/Mobs/Species/Human/parts.rsi/r_foot.png create mode 100644 Resources/Textures/CrystallPunk/Mobs/Species/Human/parts.rsi/r_hand.png create mode 100644 Resources/Textures/CrystallPunk/Mobs/Species/Human/parts.rsi/r_leg.png create mode 100644 Resources/Textures/CrystallPunk/Mobs/Species/Human/parts.rsi/torso_f.png create mode 100644 Resources/Textures/CrystallPunk/Mobs/Species/Human/parts.rsi/torso_m.png diff --git a/Resources/Prototypes/Body/Parts/human.yml b/Resources/Prototypes/Body/Parts/human.yml index a1510fcdbb..2951195e78 100644 --- a/Resources/Prototypes/Body/Parts/human.yml +++ b/Resources/Prototypes/Body/Parts/human.yml @@ -15,6 +15,7 @@ Quantity: 10 - type: entity + noSpawn: true id: TorsoHuman name: "human torso" parent: [PartHuman, BaseTorso] @@ -31,6 +32,7 @@ Quantity: 20 - type: entity + noSpawn: true id: HeadHuman name: "human head" parent: [PartHuman, BaseHead] @@ -47,6 +49,7 @@ Quantity: 10 - type: entity + noSpawn: true id: LeftArmHuman name: "left human arm" parent: [PartHuman, BaseLeftArm] @@ -56,6 +59,7 @@ state: "l_arm" - type: entity + noSpawn: true id: RightArmHuman name: "right human arm" parent: [PartHuman, BaseRightArm] @@ -65,6 +69,7 @@ state: "r_arm" - type: entity + noSpawn: true id: LeftHandHuman name: "left human hand" parent: [PartHuman, BaseLeftHand] @@ -74,6 +79,7 @@ state: "l_hand" - type: entity + noSpawn: true id: RightHandHuman name: "right human hand" parent: [PartHuman, BaseRightHand] @@ -83,6 +89,7 @@ state: "r_hand" - type: entity + noSpawn: true id: LeftLegHuman name: "left human leg" parent: [PartHuman, BaseLeftLeg] @@ -92,6 +99,7 @@ state: "l_leg" - type: entity + noSpawn: true id: RightLegHuman name: "right human leg" parent: [PartHuman, BaseRightLeg] @@ -101,6 +109,7 @@ state: "r_leg" - type: entity + noSpawn: true id: LeftFootHuman name: "left human foot" parent: [PartHuman, BaseLeftFoot] @@ -110,6 +119,7 @@ state: "l_foot" - type: entity + noSpawn: true id: RightFootHuman name: "right human foot" parent: [PartHuman, BaseRightFoot] diff --git a/Resources/Prototypes/Entities/Mobs/Player/human.yml b/Resources/Prototypes/Entities/Mobs/Player/human.yml index 2c7ad4972c..0db72b5a6d 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/human.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/human.yml @@ -1,11 +1,13 @@ - type: entity save: false + noSpawn: true name: Urist McHands parent: BaseMobHuman id: MobHuman #Syndie - type: entity + noSpawn: true parent: MobHuman id: MobHumanSyndicateAgentBase name: syndicate agent @@ -20,6 +22,7 @@ - Syndicate - type: entity + noSpawn: true parent: MobHumanSyndicateAgentBase id: MobHumanSyndicateAgent name: syndicate agent @@ -31,6 +34,7 @@ giveObjectives: false - type: entity + noSpawn: true parent: MobHumanSyndicateAgentBase id: MobHumanSyndicateAgentNukeops # Reinforcement exclusive to nukeops uplink suffix: Human, NukeOps diff --git a/Resources/Prototypes/Species/arachnid.yml b/Resources/Prototypes/Species/arachnid.yml index 07a72cda17..d7182128ca 100644 --- a/Resources/Prototypes/Species/arachnid.yml +++ b/Resources/Prototypes/Species/arachnid.yml @@ -1,7 +1,7 @@ - type: species id: Arachnid name: species-name-arachnid - roundStart: true + roundStart: false prototype: MobArachnid sprites: MobArachnidSprites defaultSkinTone: "#385878" diff --git a/Resources/Prototypes/Species/diona.yml b/Resources/Prototypes/Species/diona.yml index 19fafaa3e1..4dd2cc1143 100644 --- a/Resources/Prototypes/Species/diona.yml +++ b/Resources/Prototypes/Species/diona.yml @@ -1,7 +1,7 @@ - type: species id: Diona name: species-name-diona - roundStart: true + roundStart: false prototype: MobDiona sprites: MobDionaSprites defaultSkinTone: "#cdb369" diff --git a/Resources/Prototypes/Species/dwarf.yml b/Resources/Prototypes/Species/dwarf.yml index fc800213c1..9116092901 100644 --- a/Resources/Prototypes/Species/dwarf.yml +++ b/Resources/Prototypes/Species/dwarf.yml @@ -1,7 +1,7 @@ - type: species id: Dwarf name: species-name-dwarf - roundStart: true + roundStart: false prototype: MobDwarf sprites: MobHumanSprites markingLimits: MobHumanMarkingLimits diff --git a/Resources/Prototypes/Species/human.yml b/Resources/Prototypes/Species/human.yml index 0cbd9cc03f..a5e62de92b 100644 --- a/Resources/Prototypes/Species/human.yml +++ b/Resources/Prototypes/Species/human.yml @@ -1,7 +1,7 @@ - type: species id: Human name: species-name-human - roundStart: true + roundStart: false prototype: MobHuman sprites: MobHumanSprites markingLimits: MobHumanMarkingLimits diff --git a/Resources/Prototypes/Species/moth.yml b/Resources/Prototypes/Species/moth.yml index 4f587eb40e..1479420b15 100644 --- a/Resources/Prototypes/Species/moth.yml +++ b/Resources/Prototypes/Species/moth.yml @@ -1,7 +1,7 @@ - type: species id: Moth name: species-name-moth - roundStart: true + roundStart: false prototype: MobMoth sprites: MobMothSprites defaultSkinTone: "#ffda93" diff --git a/Resources/Prototypes/Species/reptilian.yml b/Resources/Prototypes/Species/reptilian.yml index f5cf1fa6eb..738895bcdf 100644 --- a/Resources/Prototypes/Species/reptilian.yml +++ b/Resources/Prototypes/Species/reptilian.yml @@ -1,7 +1,7 @@ - type: species id: Reptilian name: species-name-reptilian - roundStart: true + roundStart: false prototype: MobReptilian sprites: MobReptilianSprites defaultSkinTone: "#34a223" diff --git a/Resources/Prototypes/Species/slime.yml b/Resources/Prototypes/Species/slime.yml index ef49e9b7cf..f4e4057e54 100644 --- a/Resources/Prototypes/Species/slime.yml +++ b/Resources/Prototypes/Species/slime.yml @@ -1,7 +1,7 @@ - type: species id: SlimePerson name: species-name-slime - roundStart: true + roundStart: false prototype: MobSlimePerson sprites: MobSlimeSprites defaultSkinTone: "#b8b8b8" diff --git a/Resources/Prototypes/_CP14/Body/Parts/human.yml b/Resources/Prototypes/_CP14/Body/Parts/human.yml new file mode 100644 index 0000000000..7e06bbb347 --- /dev/null +++ b/Resources/Prototypes/_CP14/Body/Parts/human.yml @@ -0,0 +1,70 @@ + +- type: entity + id: CPTorsoHuman + parent: TorsoHuman + components: + - type: Sprite + sprite: CrystallPunk/Mobs/Species/Human/parts.rsi + +- type: entity + id: CPHeadHuman + parent: HeadHuman + components: + - type: Sprite + sprite: CrystallPunk/Mobs/Species/Human/parts.rsi + +- type: entity + id: CPLeftArmHuman + parent: LeftArmHuman + components: + - type: Sprite + sprite: CrystallPunk/Mobs/Species/Human/parts.rsi + +- type: entity + id: CPRightArmHuman + parent: RightArmHuman + components: + - type: Sprite + sprite: CrystallPunk/Mobs/Species/Human/parts.rsi + +- type: entity + id: CPLeftHandHuman + parent: LeftHandHuman + components: + - type: Sprite + sprite: CrystallPunk/Mobs/Species/Human/parts.rsi + +- type: entity + id: CPRightHandHuman + parent: RightHandHuman + components: + - type: Sprite + sprite: CrystallPunk/Mobs/Species/Human/parts.rsi + +- type: entity + id: CPLeftLegHuman + parent: LeftLegHuman + components: + - type: Sprite + sprite: CrystallPunk/Mobs/Species/Human/parts.rsi + +- type: entity + id: CPRightLegHuman + parent: RightLegHuman + components: + - type: Sprite + sprite: CrystallPunk/Mobs/Species/Human/parts.rsi + +- type: entity + id: CPLeftFootHuman + parent: LeftFootHuman + components: + - type: Sprite + sprite: CrystallPunk/Mobs/Species/Human/parts.rsi + +- type: entity + id: CPRightFootHuman + parent: RightFootHuman + components: + - type: Sprite + sprite: CrystallPunk/Mobs/Species/Human/parts.rsi \ No newline at end of file diff --git a/Resources/Prototypes/_CP14/Body/Prototypes/human.yml b/Resources/Prototypes/_CP14/Body/Prototypes/human.yml new file mode 100644 index 0000000000..4bfa51a518 --- /dev/null +++ b/Resources/Prototypes/_CP14/Body/Prototypes/human.yml @@ -0,0 +1,49 @@ +- type: body + id: CPHuman + name: "человек" + root: torso + slots: + head: + part: CPHeadHuman + connections: + - torso + organs: + brain: OrganHumanBrain + eyes: OrganHumanEyes + torso: + part: TorsoHuman + connections: + - right_arm + - left_arm + - right_leg + - left_leg + organs: + heart: OrganHumanHeart + lungs: OrganHumanLungs + stomach: OrganHumanStomach + liver: OrganHumanLiver + kidneys: OrganHumanKidneys + right_arm: + part: CPRightArmHuman + connections: + - right_hand + left_arm: + part: CPLeftArmHuman + connections: + - left_hand + right_hand: + part: CPRightHandHuman + left_hand: + part: CPLeftHandHuman + right_leg: + part: CPRightLegHuman + connections: + - right_foot + left_leg: + part: CPLeftLegHuman + connections: + - left_foot + right_foot: + part: CPRightFootHuman + left_foot: + part: CPLeftFootHuman diff --git a/Resources/Prototypes/_CP14/Entities/Mobs/Player/human.yml b/Resources/Prototypes/_CP14/Entities/Mobs/Player/human.yml new file mode 100644 index 0000000000..1479464295 --- /dev/null +++ b/Resources/Prototypes/_CP14/Entities/Mobs/Player/human.yml @@ -0,0 +1,4 @@ +- type: entity + save: false + parent: CPBaseMobHuman + id: CPMobHuman diff --git a/Resources/Prototypes/_CP14/Entities/Mobs/Species/human.yml b/Resources/Prototypes/_CP14/Entities/Mobs/Species/human.yml new file mode 100644 index 0000000000..ae2dc51a4d --- /dev/null +++ b/Resources/Prototypes/_CP14/Entities/Mobs/Species/human.yml @@ -0,0 +1,22 @@ +# Anything human specific (e.g. UI, input) goes under MobHuman +- type: entity + parent: BaseMobSpeciesOrganic + id: CPBaseMobHuman + name: человеческая оболочка + abstract: true + components: + - type: HumanoidAppearance + species: CPHuman + - type: Hunger + - type: Icon # It will not have an icon in the adminspawn menu without this. Body parts seem fine for whatever reason. + sprite: CrystallPunk/Mobs/Species/Human/parts.rsi + state: full + - type: Thirst + - type: Butcherable + butcheringType: Spike + spawned: + - id: FoodMeatHuman + amount: 5 + - type: Body + prototype: CPHuman + requiredLegs: 2 diff --git a/Resources/Prototypes/_CP14/Species/human.yml b/Resources/Prototypes/_CP14/Species/human.yml new file mode 100644 index 0000000000..dee0257d23 --- /dev/null +++ b/Resources/Prototypes/_CP14/Species/human.yml @@ -0,0 +1,126 @@ +- type: species + id: CPHuman + name: species-name-human + roundStart: true + prototype: CPMobHuman + sprites: CPMobHumanSprites + markingLimits: MobHumanMarkingLimits + dollPrototype: MobHumanDummy + skinColoration: HumanToned + +- type: speciesBaseSprites + id: CPMobHumanSprites + sprites: + Head: CPMobHumanHead + Hair: MobHumanoidAnyMarking + FacialHair: MobHumanoidAnyMarking + Snout: MobHumanoidAnyMarking + Chest: CPMobHumanTorso + Eyes: CPMobHumanoidEyes + LArm: CPMobHumanLArm + RArm: CPMobHumanRArm + LHand: CPMobHumanLHand + RHand: CPMobHumanRHand + LLeg: CPMobHumanLLeg + RLeg: CPMobHumanRLeg + LFoot: CPMobHumanLFoot + RFoot: CPMobHumanRFoot + + + +- type: humanoidBaseSprite + id: CPMobHumanoidEyes + baseSprite: + sprite: CrystallPunk/Mobs/Customization/eyes.rsi + state: eyes + +- type: humanoidBaseSprite + id: CPMobHumanoidAnyMarking + +- type: humanoidBaseSprite + id: CPMobHumanoidMarkingMatchSkin + markingsMatchSkin: true + +- type: humanoidBaseSprite + id: CPMobHumanHead + baseSprite: + sprite: CrystallPunk/Mobs/Species/Human/parts.rsi + state: head_m + +- type: humanoidBaseSprite + id: CPMobHumanHeadMale + baseSprite: + sprite: CrystallPunk/Mobs/Species/Human/parts.rsi + state: head_m + +- type: humanoidBaseSprite + id: CPMobHumanHeadFemale + baseSprite: + sprite: CrystallPunk/Mobs/Species/Human/parts.rsi + state: head_f + +- type: humanoidBaseSprite + id: CPMobHumanTorso + baseSprite: + sprite: CrystallPunk/Mobs/Species/Human/parts.rsi + state: torso_m + +- type: humanoidBaseSprite + id: CPMobHumanTorsoMale + baseSprite: + sprite: CrystallPunk/Mobs/Species/Human/parts.rsi + state: torso_m + +- type: humanoidBaseSprite + id: CPMobHumanTorsoFemale + baseSprite: + sprite: CrystallPunk/Mobs/Species/Human/parts.rsi + state: torso_f + +- type: humanoidBaseSprite + id: CPMobHumanLLeg + baseSprite: + sprite: CrystallPunk/Mobs/Species/Human/parts.rsi + state: l_leg + +- type: humanoidBaseSprite + id: CPMobHumanLArm + baseSprite: + sprite: CrystallPunk/Mobs/Species/Human/parts.rsi + state: l_arm + +- type: humanoidBaseSprite + id: CPMobHumanLHand + baseSprite: + sprite: CrystallPunk/Mobs/Species/Human/parts.rsi + state: l_hand + +- type: humanoidBaseSprite + id: CPMobHumanLFoot + baseSprite: + sprite: CrystallPunk/Mobs/Species/Human/parts.rsi + state: l_foot + +- type: humanoidBaseSprite + id: CPMobHumanRLeg + baseSprite: + sprite: CrystallPunk/Mobs/Species/Human/parts.rsi + state: r_leg + +- type: humanoidBaseSprite + id: CPMobHumanRArm + baseSprite: + sprite: CrystallPunk/Mobs/Species/Human/parts.rsi + state: r_arm + +- type: humanoidBaseSprite + id: CPMobHumanRHand + baseSprite: + sprite: CrystallPunk/Mobs/Species/Human/parts.rsi + state: r_hand + +- type: humanoidBaseSprite + id: CPMobHumanRFoot + baseSprite: + sprite: CrystallPunk/Mobs/Species/Human/parts.rsi + state: r_foot \ No newline at end of file diff --git a/Resources/Textures/CrystallPunk/Mobs/Customization/eyes.rsi/eyes.png b/Resources/Textures/CrystallPunk/Mobs/Customization/eyes.rsi/eyes.png new file mode 100644 index 0000000000000000000000000000000000000000..f57521ee7c491bd0ed39183509e7862e5a6ef53a GIT binary patch literal 125 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|%spKkLn`LH zy|qvfsEWn#SN^XJ`SOhkLYsYaL>X$lCv68R0)Yd$v)4E1GlJO(D;R5!iNBomW0eYs N@9FC2vd$@?2>_*hBI5u6 literal 0 HcmV?d00001 diff --git a/Resources/Textures/CrystallPunk/Mobs/Customization/eyes.rsi/meta.json b/Resources/Textures/CrystallPunk/Mobs/Customization/eyes.rsi/meta.json new file mode 100644 index 0000000000..d84bc34b33 --- /dev/null +++ b/Resources/Textures/CrystallPunk/Mobs/Customization/eyes.rsi/meta.json @@ -0,0 +1,18 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Created by TheShuEd (Github) for CrystallPunk", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "eyes", + "directions": 4 + }, + { + "name": "no_eyes" + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/CrystallPunk/Mobs/Customization/eyes.rsi/no_eyes.png b/Resources/Textures/CrystallPunk/Mobs/Customization/eyes.rsi/no_eyes.png new file mode 100644 index 0000000000000000000000000000000000000000..1cdeb2aead2aea5b0a58d9d4f8154a9b42b0cb41 GIT binary patch literal 4683 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/CrystallPunk/Mobs/Species/Human/parts.rsi/l_arm.png b/Resources/Textures/CrystallPunk/Mobs/Species/Human/parts.rsi/l_arm.png new file mode 100644 index 0000000000000000000000000000000000000000..3e367da72ba63af4f00e91b78bc611c6d4e33641 GIT binary patch literal 468 zcmV;_0W1EAP)Px$j!8s8RCt{2+P!K5K@htp@34j2m?iHKkQ5TMNRwv>W(#)- zLeixSA)v%`x?r;y1kpUebdx3nnnG|rGn*yn>phHjW@p8Fg&-m#A|i}>qoqvb`ax(U z7cPn?3S9(02vrnMvQYpjr9u`#e|agTkpk?P2rU-!e>%@7DWyW4g5}*e^$5UEz{BH{ z5CXSr#X?@hv$+`bdyu@};036;)toK@%Ans9HMg3BhW;>e2kh-1K=X#9F*I)(ya3Oy zZ>mx*K{LM=3*oq4Htv8*xg_G*9FnDX{`RH`$+M!~Xes?BKk(}dDD*cuBnCDvTYYS^N+yG`$yVKSd~Uc z$PYr5bT9*c0@ApMhNE%fhAg}Q$47_gNTc8d=yba1$hEeeLxLBe8?=p#vaI7>oQu!t zG|^`>{}#~nU`G4yUR+;YTHl0JIj*Pl52AlNm%yP6A|fIp+RQgyjn7Mmz@qE`0000< KMNUMnLSTXpO3!-$ literal 0 HcmV?d00001 diff --git a/Resources/Textures/CrystallPunk/Mobs/Species/Human/parts.rsi/l_foot.png b/Resources/Textures/CrystallPunk/Mobs/Species/Human/parts.rsi/l_foot.png new file mode 100644 index 0000000000000000000000000000000000000000..de5511c6a465d23e9783a8616b28a9180e459a41 GIT binary patch literal 404 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D%z{XAV9Ln`LH zy|vNnaDWKggZ+<`O}3ec+_}0?Y_3l3OYR*jn%Bizm5Mew3w&bP*BBhTi`}tZz(c`1 z`h*0NS7uE^&T&UxD-o&Ug)IN_Z4TE@s`g(d+|Ypx%o1lzYYEgz6zP7uBWcF8oZmA) z-3S#F`XRTat&D2s+mXTJ-hF`|a=V)4PL*+ZZ96>qq{xBmejCEpuk2XjE3r&<+hea;%Y@uE z^0+^~b9wm_;Tvp+w=A)Kv2f+<$hY>F!*4M&G%Q<}ynkPN#!jaP)ichE?KJk8W_wBp00i_>zopr0B%yTu>b%7 literal 0 HcmV?d00001 diff --git a/Resources/Textures/CrystallPunk/Mobs/Species/Human/parts.rsi/l_hand.png b/Resources/Textures/CrystallPunk/Mobs/Species/Human/parts.rsi/l_hand.png new file mode 100644 index 0000000000000000000000000000000000000000..1c015eaba72961f1748e6f96a07ad068db37145a GIT binary patch literal 321 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|etWt&hE&XX zduw6dp#YI%AC2#^8YVRPyqC>dm9fmwI76g~>&(1FMizxv%Q^EId<}f3t8x1m+?lCx zCU?n8&6W@Uf7b2%`>ynP2hc1aSTO7S*JB}9L$0~!tm(AWEUbvPD#Mb>9l zusfK&18M|E{$^Kk_`TX+8yj4-VIKDGYdiv#{_2)S+wyMXw zDk>dUI#u&J?!eYLV#dqlH)qQ~{nTWz$>g-|*-yXkdM9Wy1Fd-ahr#(m^83UuXQzWK N^mO%eS?83{1OUSthOz(v literal 0 HcmV?d00001 diff --git a/Resources/Textures/CrystallPunk/Mobs/Species/Human/parts.rsi/l_leg.png b/Resources/Textures/CrystallPunk/Mobs/Species/Human/parts.rsi/l_leg.png new file mode 100644 index 0000000000000000000000000000000000000000..7e045922af8422e63d72bda74cc6411694d9ff5a GIT binary patch literal 382 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D%zEj(QuLn`LH zy|vNnaDd3MkHLi}n7?dWxbVVJNAp6V!Y_d_b7HtJIda*BJfCoJt?Vw2htsZoVLT_s z&MvO&`Oa|Rum5jjeNKy)H{71HR^YaOcP1#qhHdBoiDDLW``dG#AtTiw1jPuL({>;hRINhu0eRMQ8!~qNp zHS4=C{!lvGblqeo&&n+I_e@>A{BhP5Mk=37H{{$d+A3yVB^s)`SmTxHNsCn%MF)V_wSdI0lA) ZQ~BQ%CPxUmy7PnV^mO%eS?83{1OV*QtYh7tMO8 z>6eiE<0Jpq`#qRF-8}PNFv!a3yl#^<-t!1uzPbJHoaT!vTqQ4D7@1_g^!g8C&<9T>svS{Yd4~*n+LhkFw5*dvkw$m%lqwyVj<2w?hf* zv+kv@e%`(0ds1%6^K$RoXQTe?S-~*%d;ginPaAH_f9eC;2?1RT9)F)ZL(r>J&DnG9 zx8+5t;Rkj-*o>#V7ROp1Vn@E3kl9dBl5O+=9k)>_ku}=qNKwM8(KbLh* G2~7aCewzgV literal 0 HcmV?d00001 diff --git a/Resources/Textures/CrystallPunk/Mobs/Species/Human/parts.rsi/r_foot.png b/Resources/Textures/CrystallPunk/Mobs/Species/Human/parts.rsi/r_foot.png new file mode 100644 index 0000000000000000000000000000000000000000..947a8d91f8f4c0e0715a590151b4fe4ff9454bdc GIT binary patch literal 365 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D%z)jeGtLn`LH zy|vNnaDc?okBfhBxVebOFPv7U&9$$Y@0_0BE{oJtlf+jx7rwl=uz6b3B0f)rWR5Kz zFPT$z^UYf1*QvI#^?&}JJJNjeHJ3YCfaXKM1MS;|XA5i$1Lw@p@auWIZQY84Mq*};noFWn4Td~xrkl641j>({>c{dJM}t@alb3zYPfuMIv%N-^**<1f49seVAKbSK zeMQvMEars-ofFe?pY9shVrOp`^6l(YsRotG>*l|11~2mb$(I(n?Z(m2f02v6aIw_= z*w{RG-M4MqU!AzJ;u756w literal 0 HcmV?d00001 diff --git a/Resources/Textures/CrystallPunk/Mobs/Species/Human/parts.rsi/r_hand.png b/Resources/Textures/CrystallPunk/Mobs/Species/Human/parts.rsi/r_hand.png new file mode 100644 index 0000000000000000000000000000000000000000..192a4b09e57f929b820600464576a7bf38103baf GIT binary patch literal 346 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D%zMLb;`Ln`LH zy|veiIZ&YOq5nszBbU@#>suqL`EToR=v^~2ySB1P!k{&-*`@o4(%!8VjQ@0R=x8&3 zAZgO#>OFg zviXa0@oy^fwf(UMUBdm3Qq<n;b(KU o$ba*n|L=G<7%(z0H2nO)x%5nIyq?a}=OBALUHx3vIVCg!0B1swwEzGB literal 0 HcmV?d00001 diff --git a/Resources/Textures/CrystallPunk/Mobs/Species/Human/parts.rsi/r_leg.png b/Resources/Textures/CrystallPunk/Mobs/Species/Human/parts.rsi/r_leg.png new file mode 100644 index 0000000000000000000000000000000000000000..1414e70d15e09a0b2019854fb90e2b7d54a16e7d GIT binary patch literal 396 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D%z-8@|!Ln`LH zy|vNnaDd3MkHQ}Xi*6?f?y`8H=BLzW*VR2aTOmcG)h5JUbMBF~vb#jQRC0eYl<)S7 zY~lOhVEFbF`U&W`jU_%H~6n*>{t67S)~?IyH6Mhrf@D3lxEZ)oP^- zk5ks@@@mZ%&D$7bnZ5Q^;|gYpMZvMv*DF{*6x6Hle)Zz+67RFV+0Q?5CG5R<%0%+y z+muCF*II8#RMu8asg3l?=_%j)O5ecOZPq5gO!-q=&-XvClsfx4Y}q^Kjws;4$NM=y8d^hN5=Mp|5q|^xVCHkd-=%xZHmu6h-G=cmUSrh zQt|lC7_gVo_gC%Se@a3*;xA+mEVN?DymQRPfARL|&oz#0-NU@%^<~%Gr081KGiM9< lyfP};6MSq|2rDsMI41v7ATw6i_0K1e-JY&~F6*2UngIP?sapU5 literal 0 HcmV?d00001 diff --git a/Resources/Textures/CrystallPunk/Mobs/Species/Human/parts.rsi/torso_f.png b/Resources/Textures/CrystallPunk/Mobs/Species/Human/parts.rsi/torso_f.png new file mode 100644 index 0000000000000000000000000000000000000000..d252de33c8f6e0c41aa4dd37cbbb0165f03ea932 GIT binary patch literal 769 zcmV+c1OEJpP)Px%yGcYrRCt{2+COU|K^O+`C&v}}0NF$mIBbN|Cdq}AA%V0CL6Q^~Nu9%%l|z<%@JQ7(Rbxc61> zm$!ZIWXR-`CZN%5!{`r@KQB15?Y`e=w#glk$+vmSVdnz?E-tS`u~ZiI+dE-dmZ;y} ziDIcNE-tS^{RFV7nl3EM5|(9&meFy_s-{cjlU4u#49sVwQ%P*DtpWfx*H)2EB{49c zW%7M_X+M}2X#(~RG9$b2OZ7oJ$>v1n_-Jfh=J*IF*&I2ayaE#Om@{zu6)^fkB;qk@ zQ&J|q>aweW^f3qk%JK>xAMWvcdBu6m>~*2I?uV)V^B1-@*2k7*kS5@!^kWWy0D!~8 zJzQVkIJd6)P?^0h>J!Q`Lho?UPO>?%pePvh2QbYiD9QqsB1?EOO?s@uYj$MbyTV~B;v7|{6V47Y$Fkmp;E0m z=YoDn?*VT1e$Z$Zf@p5)ydaQPK&4s>EI2IGK2E&??A^UsDhuyXxcxSml}fdSbSgQr z2bjGsJ|FDQ{($smqEhwr00000NkvXXu0mjfn4@SC literal 0 HcmV?d00001 diff --git a/Resources/Textures/CrystallPunk/Mobs/Species/Human/parts.rsi/torso_m.png b/Resources/Textures/CrystallPunk/Mobs/Species/Human/parts.rsi/torso_m.png new file mode 100644 index 0000000000000000000000000000000000000000..da0175612629f7db05f7c67b6cf331b61bad2de7 GIT binary patch literal 660 zcmV;F0&D$=P)Px%PDw;TRCt{2+OclhKo|$`f2s~VK%5|~R4kR+ZfVppZxEykwHex~bC(Y35UG;Y z0afzWrAr^6VhAXTl)OPUP|1)4kXS4tBf{|jY}e`B<6=_2i)}#qehY`s_<#P+V8j71 z#u#IavHz>q>hdA|N#u8fer!fJ=u4aYHOkJD$wUUj5uO#F+<9F$=*wb$1G!v|bWCc# zY6rtnw7r<$h}zVAaskY6a}Ze-K#fB`d7J#ll$}+e8LIcEDeiBR=C=c+#~?M`p1_-5NCpHu)dbe`?Yj$D96y9vXntzU`yb_!Af zt}d^q-e>x(x0(%HU0z!aVqRk*u;se3eOs=Ju@K~AT3rF^#MKOBdHK(}3*2{ixDV+z z2mnsOMXTAsP2t~6h(QRa5I-|XJO6Wm-JR{&whdANPHMl`07wAX-+zsxqm$@S>ra&! zggBqkwvqaPllJNJ7rE{@xEz9h>=0jD^6jpFdXad>CVlF~%5Uj4{R-V@uAf z_*Q>JNL#g5mtMsukBjuPxL5I|cX$v5>V54_58uCi&E!{Euj0!W&!0|hE0^|AE&%`} zWgO&%5j{}%^3{kOZo{ki^25jX)+<4##1==B8c^0*a~D9r{7s8k8lRQv9Ug%4S&+yT zkmc+row;)V4@erR0LQ0iX^kT>)G^L|7f_$>)mmMeOX0ga+nE;U`1B0r(%zjVaWM$- u?(LiG7f2WJ#b_D7j4{R-V~jDzR>xmbVFZW9&$KK60000 Date: Wed, 3 Apr 2024 16:37:23 +0300 Subject: [PATCH 6/7] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 279f94663b..18e03b7b47 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -

Space Station 14

+

CrystallPunk

Space Station 14 is a remake of SS13 that runs on [Robust Toolbox](https://github.com/space-wizards/RobustToolbox), our homegrown engine written in C#. @@ -31,8 +31,8 @@ We are not currently accepting translations of the game on our main repository. ## License -All code for the content repository is licensed under [MIT](https://github.com/space-wizards/space-station-14/blob/master/LICENSE.TXT). +All code for the content repository is licensed under [MIT](https://github.com/crystallpunk-14/crystall-punk-14/blob/master/LICENSE.TXT). -Most assets are licensed under [CC-BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/) unless stated otherwise. Assets have their license and the copyright in the metadata file. [Example](https://github.com/space-wizards/space-station-14/blob/master/Resources/Textures/Objects/Tools/crowbar.rsi/meta.json). +Most assets are licensed under [CC-BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/) unless stated otherwise. Assets have their license and the copyright in the metadata file. [Example](https://github.com/crystallpunk-14/crystall-punk-14/blob/master/Resources/Textures/Objects/Tools/crowbar.rsi/meta.json). Note that some assets are licensed under the non-commercial [CC-BY-NC-SA 3.0](https://creativecommons.org/licenses/by-nc-sa/3.0/) or similar non-commercial licenses and will need to be removed if you wish to use this project commercially. From 3c2f19856709a768958d7ae8c68c5572a0e00caf Mon Sep 17 00:00:00 2001 From: Ed <96445749+TheShuEd@users.noreply.github.com> Date: Thu, 4 Apr 2024 00:56:54 +0300 Subject: [PATCH 7/7] Setup melee. Add Zweichender (#34) * Setup melee. Add Zweichender * Update base.yml * Update base.yml --- .../Weapons/Melee/MeleeWeaponComponent.cs | 5 ++ .../Weapons/Melee/SharedMeleeWeaponSystem.cs | 5 ++ .../Entities/Objects/Weapons/Melee/base.yml | 57 ++++++++++++++++++ .../Objects/Weapons/Melee/twoHandedSword.yml | 17 ++++++ .../Entities/Objects/Weapons/Ranged/base.yml | 14 +++++ .../Mobs/Species/Human/parts.rsi/full.png | Bin 700 -> 639 bytes .../zweichhender.rsi/equipped-BACKPACK.png | Bin 0 -> 1237 bytes .../Weapons/Melee/zweichhender.rsi/icon.png | Bin 0 -> 780 bytes .../Melee/zweichhender.rsi/inhand-left.png | Bin 0 -> 802 bytes .../Melee/zweichhender.rsi/inhand-right.png | Bin 0 -> 785 bytes .../Weapons/Melee/zweichhender.rsi/meta.json | 34 +++++++++++ .../zweichhender.rsi/wielded-inhand-left.png | Bin 0 -> 586 bytes .../zweichhender.rsi/wielded-inhand-right.png | Bin 0 -> 598 bytes 13 files changed, 132 insertions(+) create mode 100644 Resources/Prototypes/_CP14/Entities/Objects/Weapons/Melee/base.yml create mode 100644 Resources/Prototypes/_CP14/Entities/Objects/Weapons/Melee/twoHandedSword.yml create mode 100644 Resources/Prototypes/_CP14/Entities/Objects/Weapons/Ranged/base.yml create mode 100644 Resources/Textures/CrystallPunk/Objects/Weapons/Melee/zweichhender.rsi/equipped-BACKPACK.png create mode 100644 Resources/Textures/CrystallPunk/Objects/Weapons/Melee/zweichhender.rsi/icon.png create mode 100644 Resources/Textures/CrystallPunk/Objects/Weapons/Melee/zweichhender.rsi/inhand-left.png create mode 100644 Resources/Textures/CrystallPunk/Objects/Weapons/Melee/zweichhender.rsi/inhand-right.png create mode 100644 Resources/Textures/CrystallPunk/Objects/Weapons/Melee/zweichhender.rsi/meta.json create mode 100644 Resources/Textures/CrystallPunk/Objects/Weapons/Melee/zweichhender.rsi/wielded-inhand-left.png create mode 100644 Resources/Textures/CrystallPunk/Objects/Weapons/Melee/zweichhender.rsi/wielded-inhand-right.png diff --git a/Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs b/Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs index 85d2e4675f..2027c2d2c6 100644 --- a/Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs +++ b/Content.Shared/Weapons/Melee/MeleeWeaponComponent.cs @@ -113,6 +113,11 @@ public sealed partial class MeleeWeaponComponent : Component [ViewVariables(VVAccess.ReadWrite), DataField] public bool SwingLeft; + /// + /// CrystallPunk Melee improvment. Allows each attack to take turns being either left or right + /// + [DataField] + public bool CPSwingBeverage = true; // Sounds diff --git a/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs b/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs index e59b4a13fe..8fe0dc6e59 100644 --- a/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs +++ b/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs @@ -428,6 +428,11 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem var attackEv = new MeleeAttackEvent(weaponUid); RaiseLocalEvent(user, ref attackEv); + //CrystallPun melee improvment + if (weapon.CPSwingBeverage) + weapon.SwingLeft = !weapon.SwingLeft; + //CrystallPun melee improvment end + weapon.Attacking = true; return true; } diff --git a/Resources/Prototypes/_CP14/Entities/Objects/Weapons/Melee/base.yml b/Resources/Prototypes/_CP14/Entities/Objects/Weapons/Melee/base.yml new file mode 100644 index 0000000000..01e9806cef --- /dev/null +++ b/Resources/Prototypes/_CP14/Entities/Objects/Weapons/Melee/base.yml @@ -0,0 +1,57 @@ +# Simple melee weapons + +# Battle Staff +# Mace +# Stick +# Dagger +# Spear +# Light Hammer +# Throwing spear +# Hand axe +# Sickle + +# Military melee weapons + +# Halberd +# Battle pick +# Warhammer +# Battle axe +# Glaive + +- type: entity + name: двуручный меч + abstract: true + parent: BaseItem + id: CPBaseTwoHandedSword + description: Мощное оружие, требующее огромной силы и умения для эффективного использования. + components: + - type: Sharp + - type: MeleeWeapon + attackRate: 0.75 + damage: + types: + Slash: 10 + Structural: 5 + soundHit: + collection: MetalThud + - type: Wieldable + - type: IncreaseDamageOnWield + damage: + types: + Slash: 30 + Structural: 5 + - type: Item + size: Ginormous + +# Long spear +# Long sword +# Whip +# Short sword +# Hammer +# Morgenstern +# Pika +# Rapier +# Axe +# Scimitar +# Trident +# Chain \ No newline at end of file diff --git a/Resources/Prototypes/_CP14/Entities/Objects/Weapons/Melee/twoHandedSword.yml b/Resources/Prototypes/_CP14/Entities/Objects/Weapons/Melee/twoHandedSword.yml new file mode 100644 index 0000000000..4d50550d63 --- /dev/null +++ b/Resources/Prototypes/_CP14/Entities/Objects/Weapons/Melee/twoHandedSword.yml @@ -0,0 +1,17 @@ + +- type: entity + name: цвайхендер + parent: CPBaseTwoHandedSword + id: CPZweichender + components: + - type: MeleeWeapon + wideAnimationRotation: 225 + - type: Sprite + sprite: CrystallPunk/Objects/Weapons/Melee/zweichhender.rsi + state: icon + - type: Clothing + sprite: CrystallPunk/Objects/Weapons/Melee/zweichhender.rsi + quickEquip: false + slots: + - back + #TODO двуручный хват требует перчаток чтобы не получать урона самому \ No newline at end of file diff --git a/Resources/Prototypes/_CP14/Entities/Objects/Weapons/Ranged/base.yml b/Resources/Prototypes/_CP14/Entities/Objects/Weapons/Ranged/base.yml new file mode 100644 index 0000000000..fd817a5aa7 --- /dev/null +++ b/Resources/Prototypes/_CP14/Entities/Objects/Weapons/Ranged/base.yml @@ -0,0 +1,14 @@ +# Simple ranged weapon + +# Crossbow +# Dart +# Short bow +# Slingshot + +# Military ranged weapon + +# Handheld crossbow +# Heavy Crossbow +# Longbow +# Blowpipe +# Net \ No newline at end of file diff --git a/Resources/Textures/CrystallPunk/Mobs/Species/Human/parts.rsi/full.png b/Resources/Textures/CrystallPunk/Mobs/Species/Human/parts.rsi/full.png index 27ed4871786d8cb6febe44f9d627fdc5a131df2a..a0e572d045c74397a1a720af8b5b8a634cd3d2a7 100644 GIT binary patch delta 601 zcmV-f0;c`E1^)z)F@HHpL_t(oh0RwnXxl&(eNF?V6hSD(ZI(zugTd}(XrUB3WX+(^ z$(XL0vK10MXlTGgNT6G$tRZwVbs%eoEQJO<$p#Gqc{0^1N|w;eVE@ZWK1+A9L-Llh z?*F^@{=d6_XW)@hDl+J7Z=0q2nujNa=F%Q?wztjdH4~O?@PEEAh|%j03yIJgAS0hw z#FCCP04aG^|3U@SYvx?`xdn)5A6+KeqIjm`yuys{Yj0m;<<)b1{o0t%loNgc-pxJ*>!|0tCACGeL|LoXa~Sl zMdUh(A_ zB^R5{n6`jle}0!5-@xd%>o{y2wTag81@}AH*@R^qc(+hNcyIxa`X-!3R+Jo2EJPw?sV*s{>`xYV-oz2*f#XzM00000NkvXXu0mjfRJI^e delta 663 zcmV;I0%-mJ1iS^1F@JVRL_t(og~e9CYui8=eQs--#kDDw(++Z6Ol0F^a_Lmml*F=6@1_&1-g0tGARyNG0&d z#}#o$CKv#hJjy;%0j0T_vHW8TU{U^Z5E@l+S0*?`5}z`UA0hSdK3=|f3IM_AH9Od@ zoZ_eJewLY2ssiO|HS&Os^79~^U|SX`=F@1nKHj}~e(f4=S586wGD7Z&l2g)Bk8BXE z9{>>*F*1lHr+@IeBq8uBA|gVl0(5e(*+Dj!7<%VN`FV&ugmm>3wR$Tc8YE`@KzB=Q z%ewYvNC^P?tFP=iXt;jJHW<@zeN^@wZj7=3N=|z`Z~s~Q^7>|sikO%H%}5GQC>t*% zz%1z4-&!S3+YjwCTa8-11*h#}e`}SP1%0vtyk-aNq<@r{y&bIBVcWz*eUs=HJ$#LxMdl33E)i;rhtt642wRkX?_bkj*86R()dvD2BZSDiC^(f$qz=usF-z0%}`W zoCRPB|BMI=uq}(w=5qAw92aMoA%Csj3VK1WV+xB9-U7Nxv!FvWl0lbq+I~RJ#)(3x x0)ONG@Nwf?$VQt@ZzLOxPs>b6iMUn#2UT|+&Ja_qZ6^Q#002ovPDHLkV1l&OI2!-} diff --git a/Resources/Textures/CrystallPunk/Objects/Weapons/Melee/zweichhender.rsi/equipped-BACKPACK.png b/Resources/Textures/CrystallPunk/Objects/Weapons/Melee/zweichhender.rsi/equipped-BACKPACK.png new file mode 100644 index 0000000000000000000000000000000000000000..73e424ea6540a182faecc751089c0cef6cf1434c GIT binary patch literal 1237 zcmV;`1SPx(bxA})RCt{2nonrkRvgE_Z*=LOVX&2fyHYn~8?=zjxQC{3Iv1LlHn1`nEZb;s zPuZp5xfEx|Ko8xe(4NK^yA4*_wX|$(#f)?Zcfnc0pg0QjP*%3mtuSf?cI{0H{B{^J zlB+*YiWF&yKA?lGr{DX%uYSMZd(smS5fKp)5fNcTsaU4-a~B8zh$s*rh{*8)0O#i} zP@ynm>-09OlMP8iLy|Bxk)!GS2qPl2ItnU3{)~6udb8W^#`izzuA3Y`3;>Aj>f;_{ zFN`tW@5R{^0ATduBU3xm`4IrX)I^Q|K#0d}`(}0xvY9mX$6mtDzHRt=zRFYq0GNv4 zr2ux3#~ACjna+bL>*S!Jamsp(C$7cV0Vatr#1{>C+$T z!dyG}OZf)lNn2ZmdW~o!K*cB$CdUu^9sy@Rnx%#$;q}2mhzk{H2M_$0F1@MrTt7~o zGZFwW7GdgS&d$7H9{_&}tgf!m7oUF#A(24k+iSQn_X-;?-NXIgpXltE!6iVi5hCI$ zN_L%V?U`Ns*OO~_Ir*OMT&trH0K|6nF6HB_VLXVy8mm{h3-jNmZ?@`b!a$YEOn9^X9S-cujY4t{9p zjqYI88ON$7dB#T80PTO;oY&R_BEt3W?z-~9HUiwz>L{MtGrRMnxv_QSsI36KirS@w zIz@Sj+2Fmv@?l8J;%o~0#)d50FvcK?bpW8@;j|}?sy6)?Jm4S&w8e!nW_SRAI`C#& z=8gm-TWbEQb_QNOz*-#zX2(Ek4{vwQa9i9&u})4zFrwL(NfhhBE=JZ<-PIMEn|{@5 z-)zfnF6YMa!w?Ys;)wSq@c8N5H28mE%L`yT4F(LY-zF0;;saU3lB;k)+le+Du zASe~fBqS1;&X2IK=9fIPYZ(DTA^{;D$JtNYq<(x5Bo7`w#FabC@X{Ac0gksnV@r2` zKu2DKf*pa0P%H1n2ivc*2P;cBnah%wB3LF>t-KciaBg1cekJlE{$^M1EPK+q7PY_` zD0s_oSHbaKBE?W*-_0z zU-N8d%61{7erPcH_WLLv{FBS58+h(kLy`ahpB(?kH$QZ!N~+4QUe1JK%iPPoNv@@^ zs{CezOMo-U3R}IL@!OX`;1Xc;;v>Wdl86r^{q|?Wv8+5{eHe;1Mm%KG3BVXbtD_Ka zlx{i!M6pi4{d%9fy(Px%tVu*cR9J=WmO)4qQ5eU6Pf|n>cNP(fE=!9AX)L013nGI+i4LKMx)^nhI&>;f z6zbHW=oA%E&=Pg(uuJDaj2SGEP0}(VI=Q&BArU-+*I}9I&Cbs5%(PyjKRgCzKHl&D zz4yNF4g43Nl-l)CC=@6Z3IIqcRjIV90QST&YTI_A1jok40GOPdL`tbPHa_rm^Bb`Y z6pO`3apiKk;rn{{#OVnU%RnoQA9w-4v+^E18AD2Z^>P_Wm)8MIl8*Kyx5M&vxb18!29?13xHfMM?RnT z#V6W=M&MR(DP;f-305EpyqO{y*nGUdrKu!vh_MCj&fHa`DzI%k)Ic-1X_{D;1=J3p zE4>Q-st>fv+=aVZSy>6p5$h1@w^%)V%h`&&?7AYafD0TNIwBf188@yz>$VtJTU(>2 zr@JLQi2?=|=5DHNCd0Y&XN6MA*Mi%bxvLHUA%r(7jzh(9c={->gb`{a8XP=C zBlyzm#fBwhnr3L_1Pti9bN7}2JQJnTY5;B+eE<|+7FBP$H&N!U0{eGmr1soCd{JdH z834{qpYomd0b@V`7)BrKpFaxs?zb$fS-%_mf!l9u&naV_Pe3}A;{LrSoIG*d zD>dyID_i&9P*>AF;Cy*crCJ5RUVaz&u4kU~5H>8Ksqv%gr~JkC&JO^x!zSreinL)c zw{TrZDMKgJ+pI1rC7qp}HK_Q54H(ejODn71_sf^ADuA?MFgt%OwD$GMb?Ntw9^>1B zFgVnzqf)I>ahx!A02D<6V1D+7DlNVu4DRar1(TF0000< KMNUMnLSTYZDqy<+ literal 0 HcmV?d00001 diff --git a/Resources/Textures/CrystallPunk/Objects/Weapons/Melee/zweichhender.rsi/inhand-left.png b/Resources/Textures/CrystallPunk/Objects/Weapons/Melee/zweichhender.rsi/inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..65a012c1e13cd9c3d3f9c78715159ce8ccc991d0 GIT binary patch literal 802 zcmV+-1Ks?IP)Px%!bwCyRCt{2nz3u!KorKmD%(=3xT9S1qOXmIHKo-{dy^nYA z&Uz1E7=~e(nY0>BTC@#eaR$SQ&q21|2s5dXH{cA0nGnHPT^V0HgCQAtL(Rmt-KMOF z0F0cs?Y3Hb(;xy7!5IvFheV6>l0}O^L^H?H$FGs*3zY-h6bh#3UR`7+Cj@bGo`;;C zgDyrQ7^^EnwNVnH6l>gSG|9UhRBx9-;qEuQ+n`qbL{Paj+>TuzZ{qrRGf;r2M9u+j ztc{XzdJc5u1R+MN>)ZaV(9a|u1%Q7f?Cd;JB8WE%R4;>A5g^yRUnJynxj0kLjSynu zG^m~WNuBB^bprlHLbX!Uk_Y_m#mxcAX*HTk1=zl`KAx*usZpwupdas!KH%B&rvjKX zejW~9y`e&B3s%u20J!XQRG2t{ashh%J^;Wfn)K`UAH<1FD7!0vArhAVm9EnuigspIZx>yB)lQhw z_0ozErEb4;BFxjYkc0?{Btd5|r0&%PoSqZuxg>fKvKQC$Q zMexNcnzUQqBUK$DZglq|#735}lR|YbLgtXw=Qu3v@30DFFM`A>niRDuBU9DkAgrQE zTlXI#pUa{APx%u}MThRCt{2n!jt?P!Pwzuapb{L-5}Jz?f{UapR#G64IedGkVJ!vZPbN!2x$^ z2^5p9Tb34=l$6wTP8wXgBp44KLX2rMR=7OSpyfI=ulR@ZELnPz?A!;m82h;U-o1B5 zcL2jM48w#@?>NWCJl>_Xu=F$;UTk+$$D0V$ZzS^7oT{z+(lZ7Z#KgBbkp{h}bBXDg&9XAJwUTRF5opKbM`K z3b^mbiT=#5JzGm$&nF`6?z|##bMV)fmk5B?&#_0~#t3$HUyAp&PoX$!lFLp90FYbE zQYOEO>fXM#47382OBMR{`ww!9Spop7*9*;2Qyd(;6GVi@MN?dMI%9p-mdDoSHUYrf z>YLch-D?XJLV$=ox4+l}^NLOY)$<>{{yDn>)Q(R90MDO3{{Pv>FW*MKxBBGabi6oW z7=~dOhG7`yZWH%AMI+=!U0LHwO2Mm&x(Wir{B#K64^WvNI612)^b5 zewcJ;Kw1)AwEyiH&CeNsWoK+jYSNv7Tp=%{CDFZV4|IpP+ocv0I|GfAGa5b)iM$_7 z?hFizkZ1u+jm_OEArY9~8R)mAL@1Xkp^Gr_C1`qQAXmr>HG)?cW8#QvXP{Wzpsmeq zQbXFrP%c#>UzJIm2x@{nt@yeF)|Zz?%5WNX26TA-t6AOKC#%=P*Uul&xM)tzRCyep zE8xfZIRMO5@C?H+48z=Q{sP+P@sO=Mll1@q01jnXNoGw=04e|g00;m8000000Mb*F P00000NkvXXu0mjfBoSx{ literal 0 HcmV?d00001 diff --git a/Resources/Textures/CrystallPunk/Objects/Weapons/Melee/zweichhender.rsi/meta.json b/Resources/Textures/CrystallPunk/Objects/Weapons/Melee/zweichhender.rsi/meta.json new file mode 100644 index 0000000000..5b9a69edac --- /dev/null +++ b/Resources/Textures/CrystallPunk/Objects/Weapons/Melee/zweichhender.rsi/meta.json @@ -0,0 +1,34 @@ +{ + "version": 1, + "license": "CC-BY-NC-SA-3.0", + "copyright": "Created by Hemo (Discord) for CrystallPunk", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + }, + { + "name": "wielded-inhand-left", + "directions": 4 + }, + { + "name": "wielded-inhand-right", + "directions": 4 + }, + { + "name": "equipped-BACKPACK", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/CrystallPunk/Objects/Weapons/Melee/zweichhender.rsi/wielded-inhand-left.png b/Resources/Textures/CrystallPunk/Objects/Weapons/Melee/zweichhender.rsi/wielded-inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..3047bb47cc164bf13ddfebb2e24583b88153a8a8 GIT binary patch literal 586 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D%zUwOJXhE&XX zd&@BUwu1=!hvh;|nk`l*Z>e6mDB;h@Kac4z+sCvW2crdr9Oo+rWVBE4pLp@1!Axe= z1uHptRcFj{x~`_jq_|}d&$BbJYi@MD4R-nQU(H+HcJFr;zQeMDKD{~cogFV8|7&;cubgPVzh3hAE7z5eb!!t$cEw8M+^i4`J#)YQ|I0k1g%>Mg zD(-GFf3uTu{U^~EN25$-cxGnITG9Js+p}rC0Y`;HZ2}=40Fw=yR5H&6o!Y*;K&b6u zOrhtj;z`eB+7!im^&jtKTzz$!*IKL6-LcA&do4o0Shc>kF@I3D`sB82vf)ZC29q?k zs_q^tJ?<_$Eojp|$;VfJ?#thrvGn@u&Cl6njti=1o-33&D`hCd6B$2e>#H9tl5I|W z|GRV1(ka)}t*(~r6}-l&7;*otqe-rVCcplIeQiNfiY*V8ch%ZRPJ8<7*YP_`qF;#z zx>hOAtM<42o$fVliRJ3EflJ>Cu3BXN|GY2*LxL?o*At(MAKmtM0R6(38sVAd>&u`8 WWOG1$cqw=?h~??(=d#Wzp$Pz1#RKX9 literal 0 HcmV?d00001 diff --git a/Resources/Textures/CrystallPunk/Objects/Weapons/Melee/zweichhender.rsi/wielded-inhand-right.png b/Resources/Textures/CrystallPunk/Objects/Weapons/Melee/zweichhender.rsi/wielded-inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..91c02785e5d3b3c28951762186b56ecb069d5d8f GIT binary patch literal 598 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D%zzj?YihE&XX zd&}N~DNu&}L%yJ*W5_mFfh{6}kHq+Vbsq*yHo1FEOE0f6P=KXX;L){fH$*y|FHCB= zB63_=Nkw;&u4&VRY1d0Wy?e8%d|76VefQzL_1|}YujAOyE+7a7f$NQXN>^UqcmMSR zrx{VgrCs$UA*=s3Oh4Fa@bpj30{`q~@>SLUSFo2=WCT?AHDB4c)?Y(nMgR6ao7#$& zCS@mcJ7~?E)|w<3zB8D?;oq$-ywBvNo!5p&~Feiac(Ig%K`0qt=%9=;)q$ym?OU!PY}_uQAPeyZ^TB{*9}XF761~ zzhT$EKU;79dcZKj_GH=9pX^^IFL-`%wR0?Tx!%6+UUz8SFm zdTMCb)ozKrrZYGlZ17RN{5G=x zw)p?mXWmTvvrWiaSN$Q|+*_~aUNfm&!FlfV+O_k(>HnJvjFO47{bes2y(^CJ%>gC{ gzSIcMG+$o^Eg+i%h(X{|@MI9>>FVdQ&MBb@0NtnyH~;_u literal 0 HcmV?d00001