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 0000000000..72707cce76 Binary files /dev/null and b/Resources/Audio/_CP14/Items/key_drop.ogg differ diff --git a/Resources/Audio/_CP14/Items/lockpick_fail.ogg b/Resources/Audio/_CP14/Items/lockpick_fail.ogg new file mode 100644 index 0000000000..c2177b04a4 Binary files /dev/null and b/Resources/Audio/_CP14/Items/lockpick_fail.ogg differ diff --git a/Resources/Audio/_CP14/Items/lockpick_use.ogg b/Resources/Audio/_CP14/Items/lockpick_use.ogg new file mode 100644 index 0000000000..04b5b58306 Binary files /dev/null and b/Resources/Audio/_CP14/Items/lockpick_use.ogg differ 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 3832afa906..0000000000 Binary files a/Resources/Textures/CrystallPunk/Objects/keys.rsi/base.png and /dev/null differ 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 0000000000..f1cbbc5907 Binary files /dev/null and b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key1.png differ diff --git a/Resources/Textures/CrystallPunk/Objects/keys.rsi/key10.png b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key10.png new file mode 100644 index 0000000000..bc695dbe92 Binary files /dev/null and b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key10.png differ diff --git a/Resources/Textures/CrystallPunk/Objects/keys.rsi/key11.png b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key11.png new file mode 100644 index 0000000000..68961b0f3c Binary files /dev/null and b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key11.png differ 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 0000000000..ecfa6ab9a2 Binary files /dev/null and b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key12.png differ 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 0000000000..3ccfd05437 Binary files /dev/null and b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key13.png differ diff --git a/Resources/Textures/CrystallPunk/Objects/keys.rsi/key14.png b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key14.png new file mode 100644 index 0000000000..fffa42b927 Binary files /dev/null and b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key14.png differ 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 0000000000..18a372694f Binary files /dev/null and b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key15.png differ diff --git a/Resources/Textures/CrystallPunk/Objects/keys.rsi/key16.png b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key16.png new file mode 100644 index 0000000000..75aadff5f8 Binary files /dev/null and b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key16.png differ 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 0000000000..124b5c012e Binary files /dev/null and b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key17.png differ 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 0000000000..a60de847dd Binary files /dev/null and b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key18.png differ diff --git a/Resources/Textures/CrystallPunk/Objects/keys.rsi/key2.png b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key2.png new file mode 100644 index 0000000000..fa87249f19 Binary files /dev/null and b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key2.png differ 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 0000000000..96d8786e24 Binary files /dev/null and b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key3.png differ 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 0000000000..0aa950808d Binary files /dev/null and b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key4.png differ 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 0000000000..6d16265fc3 Binary files /dev/null and b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key5.png differ diff --git a/Resources/Textures/CrystallPunk/Objects/keys.rsi/key6.png b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key6.png new file mode 100644 index 0000000000..ddba7240e4 Binary files /dev/null and b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key6.png differ diff --git a/Resources/Textures/CrystallPunk/Objects/keys.rsi/key7.png b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key7.png new file mode 100644 index 0000000000..a2964799cc Binary files /dev/null and b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key7.png differ diff --git a/Resources/Textures/CrystallPunk/Objects/keys.rsi/key8.png b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key8.png new file mode 100644 index 0000000000..b6ef21e681 Binary files /dev/null and b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key8.png differ diff --git a/Resources/Textures/CrystallPunk/Objects/keys.rsi/key9.png b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key9.png new file mode 100644 index 0000000000..e44490af77 Binary files /dev/null and b/Resources/Textures/CrystallPunk/Objects/keys.rsi/key9.png differ 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 0000000000..d963290989 Binary files /dev/null and b/Resources/Textures/CrystallPunk/Objects/keys.rsi/keyring.png differ 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 0000000000..f5da11ad68 Binary files /dev/null and b/Resources/Textures/CrystallPunk/Objects/keys.rsi/lock.png differ 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 0000000000..09bc94a0e1 Binary files /dev/null and b/Resources/Textures/CrystallPunk/Objects/keys.rsi/lockpick.png differ diff --git a/Resources/Textures/CrystallPunk/Objects/keys.rsi/meta.json b/Resources/Textures/CrystallPunk/Objects/keys.rsi/meta.json index cbabff4254..c62949bab4 100644 --- a/Resources/Textures/CrystallPunk/Objects/keys.rsi/meta.json +++ b/Resources/Textures/CrystallPunk/Objects/keys.rsi/meta.json @@ -8,7 +8,79 @@ "copyright": "Created by TheShuEd (Github) for CrystallPunk14", "states": [ { - "name": "base" + "name": "key1" + }, + { + "name": "key2" + }, + { + "name": "key3" + }, + { + "name": "key4" + }, + { + "name": "key5" + }, + { + "name": "key6" + }, + { + "name": "key7" + }, + { + "name": "key8" + }, + { + "name": "key9" + }, + { + "name": "key10" + }, + { + "name": "key11" + }, + { + "name": "key12" + }, + { + "name": "key13" + }, + { + "name": "key14" + }, + { + "name": "key15" + }, + { + "name": "key16" + }, + { + "name": "key17" + }, + { + "name": "key18" + }, + { + "name": "lock" + }, + { + "name": "lockpick" + }, + { + "name": "keyring" + }, + { + "name": "ring-0" + }, + { + "name": "ring-1" + }, + { + "name": "ring-2" + }, + { + "name": "ring-3" } ] } \ No newline at end of file diff --git a/Resources/Textures/CrystallPunk/Objects/keys.rsi/ring-0.png b/Resources/Textures/CrystallPunk/Objects/keys.rsi/ring-0.png new file mode 100644 index 0000000000..7244b37f5c Binary files /dev/null and b/Resources/Textures/CrystallPunk/Objects/keys.rsi/ring-0.png differ diff --git a/Resources/Textures/CrystallPunk/Objects/keys.rsi/ring-1.png b/Resources/Textures/CrystallPunk/Objects/keys.rsi/ring-1.png new file mode 100644 index 0000000000..30ec4253aa Binary files /dev/null and b/Resources/Textures/CrystallPunk/Objects/keys.rsi/ring-1.png differ 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 0000000000..22bed39b42 Binary files /dev/null and b/Resources/Textures/CrystallPunk/Objects/keys.rsi/ring-2.png differ 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 0000000000..289e821b5a Binary files /dev/null and b/Resources/Textures/CrystallPunk/Objects/keys.rsi/ring-3.png differ diff --git a/Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/full.png b/Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/full.png new file mode 100644 index 0000000000..d1e3a0d545 Binary files /dev/null and b/Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/full.png differ 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 0000000000..7379d543e1 Binary files /dev/null and b/Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/wood0.png differ diff --git a/Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/wood1.png b/Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/wood1.png new file mode 100644 index 0000000000..399db547df Binary files /dev/null and b/Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/wood1.png differ 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 0000000000..7379d543e1 Binary files /dev/null and b/Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/wood2.png differ diff --git a/Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/wood3.png b/Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/wood3.png new file mode 100644 index 0000000000..399db547df Binary files /dev/null and b/Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/wood3.png differ 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 0000000000..4e2f0b9e1a Binary files /dev/null and b/Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/wood4.png differ diff --git a/Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/wood5.png b/Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/wood5.png new file mode 100644 index 0000000000..fa56cc73c8 Binary files /dev/null and b/Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/wood5.png differ 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 0000000000..4e2f0b9e1a Binary files /dev/null and b/Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/wood6.png differ diff --git a/Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/wood7.png b/Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/wood7.png new file mode 100644 index 0000000000..5bb8ee8918 Binary files /dev/null and b/Resources/Textures/CrystallPunk/Structures/Walls/TEMPLATE_LONG.rsi/wood7.png differ 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 0000000000..1a8030fc55 Binary files /dev/null and b/Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/full.png differ diff --git a/Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/meta.json b/Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/meta.json new file mode 100644 index 0000000000..0a28ec14a1 --- /dev/null +++ b/Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/meta.json @@ -0,0 +1,46 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "Created by KREKS (Discord) for CrystallPunk14", + "states": [ + { + "name": "stone0", + "directions": 4 + }, + { + "name": "stone1", + "directions": 4 + }, + { + "name": "stone2", + "directions": 4 + }, + { + "name": "stone3", + "directions": 4 + }, + { + "name": "stone4", + "directions": 4 + }, + { + "name": "stone5", + "directions": 4 + }, + { + "name": "stone6", + "directions": 4 + }, + { + "name": "stone7", + "directions": 4 + }, + { + "name": "full" + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/stone0.png b/Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/stone0.png new file mode 100644 index 0000000000..d937d056a3 Binary files /dev/null and b/Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/stone0.png differ diff --git a/Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/stone1.png b/Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/stone1.png new file mode 100644 index 0000000000..d271cba4cc Binary files /dev/null and b/Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/stone1.png differ diff --git a/Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/stone2.png b/Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/stone2.png new file mode 100644 index 0000000000..d937d056a3 Binary files /dev/null and b/Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/stone2.png differ diff --git a/Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/stone3.png b/Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/stone3.png new file mode 100644 index 0000000000..d271cba4cc Binary files /dev/null and b/Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/stone3.png differ diff --git a/Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/stone4.png b/Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/stone4.png new file mode 100644 index 0000000000..8fe504833c Binary files /dev/null and b/Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/stone4.png differ diff --git a/Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/stone5.png b/Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/stone5.png new file mode 100644 index 0000000000..07b563a942 Binary files /dev/null and b/Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/stone5.png differ 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 0000000000..8fe504833c Binary files /dev/null and b/Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/stone6.png differ diff --git a/Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/stone7.png b/Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/stone7.png new file mode 100644 index 0000000000..c84c3b1bb2 Binary files /dev/null and b/Resources/Textures/CrystallPunk/Structures/Walls/cave_stone.rsi/stone7.png differ