From f8d194b11751469e2cfc37f84cb8dc5440dd3273 Mon Sep 17 00:00:00 2001 From: Kara Date: Fri, 22 Sep 2023 02:45:21 -0700 Subject: [PATCH] Bows & arrows (#19771) --- .../StorageContainerVisualsComponent.cs | 29 ++++++ .../Systems/StorageContainerVisualsSystem.cs | 44 +++++++++ Content.Server/Item/ItemSystem.cs | 7 +- .../Projectiles/ProjectileSystem.cs | 6 +- .../EmbeddableProjectileComponent.cs | 6 ++ .../Projectiles/ProjectileComponent.cs | 14 ++- .../Projectiles/SharedProjectileSystem.cs | 13 ++- .../Storage/Components/ItemMapperComponent.cs | 7 +- .../EntitySystems/SharedStorageSystem.cs | 7 +- .../Storage/SharedStorageComponent.cs | 0 Content.Shared/Storage/StorageComponent.cs | 4 +- Content.Shared/Throwing/ThrowingSystem.cs | 3 +- .../Marker/SharedDamageMarkerSystem.cs | 4 +- .../Weapons/Reflect/SharedReflectSystem.cs | 2 +- .../Components/WieldableComponent.cs | 7 ++ Content.Shared/Wieldable/WieldableSystem.cs | 4 + Resources/Audio/Items/attributions.yml | 5 ++ Resources/Audio/Items/bow_pull.ogg | Bin 0 -> 17266 bytes .../Audio/Weapons/Guns/Misc/arrow_nock.ogg | Bin 0 -> 6503 bytes .../Audio/Weapons/Guns/Misc/attributions.yml | 4 + .../Prototypes/Catalog/Fills/Lockers/misc.yml | 2 + .../Entities/Clothing/Belt/quiver.yml | 22 +++++ .../Entities/Objects/Weapons/Guns/Bow/bow.yml | 81 +++++++++++++++++ .../Weapons/Guns/Projectiles/arrows.yml | 84 ++++++++++++++++++ .../Graphs/weapons/improvised_arrow.yml | 23 +++++ .../Graphs/weapons/improvised_bow.yml | 17 ++++ .../Recipes/Construction/weapons.yml | 24 ++++- Resources/Prototypes/tags.yml | 9 +- .../Belt/quiver.rsi/equipped-BELT.png | Bin 0 -> 510 bytes .../Clothing/Belt/quiver.rsi/fill-1.png | Bin 0 -> 116 bytes .../Clothing/Belt/quiver.rsi/fill-2.png | Bin 0 -> 129 bytes .../Clothing/Belt/quiver.rsi/fill-3.png | Bin 0 -> 133 bytes .../Clothing/Belt/quiver.rsi/icon.png | Bin 0 -> 473 bytes .../Clothing/Belt/quiver.rsi/meta.json | 27 ++++++ .../Guns/Bow/bow.rsi/equipped-BACKPACK.png | Bin 0 -> 472 bytes .../Weapons/Guns/Bow/bow.rsi/inhand-left.png | Bin 0 -> 588 bytes .../Weapons/Guns/Bow/bow.rsi/inhand-right.png | Bin 0 -> 584 bytes .../Weapons/Guns/Bow/bow.rsi/meta.json | 43 +++++++++ .../Guns/Bow/bow.rsi/unwielded-arrow.png | Bin 0 -> 354 bytes .../Weapons/Guns/Bow/bow.rsi/unwielded.png | Bin 0 -> 511 bytes .../Guns/Bow/bow.rsi/wielded-arrow.png | Bin 0 -> 349 bytes .../Guns/Bow/bow.rsi/wielded-inhand-left.png | Bin 0 -> 415 bytes .../Guns/Bow/bow.rsi/wielded-inhand-right.png | Bin 0 -> 410 bytes .../Weapons/Guns/Bow/bow.rsi/wielded.png | Bin 0 -> 596 bytes .../Projectiles/arrows.rsi/inhand-left.png | Bin 0 -> 435 bytes .../Projectiles/arrows.rsi/inhand-right.png | Bin 0 -> 440 bytes .../Guns/Projectiles/arrows.rsi/meta.json | 31 +++++++ .../Guns/Projectiles/arrows.rsi/rod.png | Bin 0 -> 157 bytes .../Guns/Projectiles/arrows.rsi/solution.png | Bin 0 -> 257 bytes .../Guns/Projectiles/arrows.rsi/tail.png | Bin 0 -> 153 bytes .../Guns/Projectiles/arrows.rsi/tip.png | Bin 0 -> 161 bytes 51 files changed, 507 insertions(+), 22 deletions(-) create mode 100644 Content.Client/Storage/Components/StorageContainerVisualsComponent.cs create mode 100644 Content.Client/Storage/Systems/StorageContainerVisualsSystem.cs create mode 100644 Content.Shared/Storage/SharedStorageComponent.cs create mode 100644 Resources/Audio/Items/bow_pull.ogg create mode 100644 Resources/Audio/Weapons/Guns/Misc/arrow_nock.ogg create mode 100644 Resources/Audio/Weapons/Guns/Misc/attributions.yml create mode 100644 Resources/Prototypes/Entities/Clothing/Belt/quiver.yml create mode 100644 Resources/Prototypes/Entities/Objects/Weapons/Guns/Bow/bow.yml create mode 100644 Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/arrows.yml create mode 100644 Resources/Prototypes/Recipes/Construction/Graphs/weapons/improvised_arrow.yml create mode 100644 Resources/Prototypes/Recipes/Construction/Graphs/weapons/improvised_bow.yml create mode 100644 Resources/Textures/Clothing/Belt/quiver.rsi/equipped-BELT.png create mode 100644 Resources/Textures/Clothing/Belt/quiver.rsi/fill-1.png create mode 100644 Resources/Textures/Clothing/Belt/quiver.rsi/fill-2.png create mode 100644 Resources/Textures/Clothing/Belt/quiver.rsi/fill-3.png create mode 100644 Resources/Textures/Clothing/Belt/quiver.rsi/icon.png create mode 100644 Resources/Textures/Clothing/Belt/quiver.rsi/meta.json create mode 100644 Resources/Textures/Objects/Weapons/Guns/Bow/bow.rsi/equipped-BACKPACK.png create mode 100644 Resources/Textures/Objects/Weapons/Guns/Bow/bow.rsi/inhand-left.png create mode 100644 Resources/Textures/Objects/Weapons/Guns/Bow/bow.rsi/inhand-right.png create mode 100644 Resources/Textures/Objects/Weapons/Guns/Bow/bow.rsi/meta.json create mode 100644 Resources/Textures/Objects/Weapons/Guns/Bow/bow.rsi/unwielded-arrow.png create mode 100644 Resources/Textures/Objects/Weapons/Guns/Bow/bow.rsi/unwielded.png create mode 100644 Resources/Textures/Objects/Weapons/Guns/Bow/bow.rsi/wielded-arrow.png create mode 100644 Resources/Textures/Objects/Weapons/Guns/Bow/bow.rsi/wielded-inhand-left.png create mode 100644 Resources/Textures/Objects/Weapons/Guns/Bow/bow.rsi/wielded-inhand-right.png create mode 100644 Resources/Textures/Objects/Weapons/Guns/Bow/bow.rsi/wielded.png create mode 100644 Resources/Textures/Objects/Weapons/Guns/Projectiles/arrows.rsi/inhand-left.png create mode 100644 Resources/Textures/Objects/Weapons/Guns/Projectiles/arrows.rsi/inhand-right.png create mode 100644 Resources/Textures/Objects/Weapons/Guns/Projectiles/arrows.rsi/meta.json create mode 100644 Resources/Textures/Objects/Weapons/Guns/Projectiles/arrows.rsi/rod.png create mode 100644 Resources/Textures/Objects/Weapons/Guns/Projectiles/arrows.rsi/solution.png create mode 100644 Resources/Textures/Objects/Weapons/Guns/Projectiles/arrows.rsi/tail.png create mode 100644 Resources/Textures/Objects/Weapons/Guns/Projectiles/arrows.rsi/tip.png diff --git a/Content.Client/Storage/Components/StorageContainerVisualsComponent.cs b/Content.Client/Storage/Components/StorageContainerVisualsComponent.cs new file mode 100644 index 0000000000..9f07867da8 --- /dev/null +++ b/Content.Client/Storage/Components/StorageContainerVisualsComponent.cs @@ -0,0 +1,29 @@ +using Content.Client.Chemistry.Visualizers; + +namespace Content.Client.Storage.Components; + +/// +/// Essentially a version of fill level handling but for item storage. +/// Depending on the fraction of storage that's filled, will change the sprite at to the nearest +/// fill level, up to . +/// +[RegisterComponent] +public sealed partial class StorageContainerVisualsComponent : Component +{ + [DataField("maxFillLevels")] + public int MaxFillLevels = 0; + + /// + /// A prefix to use for the fill states., i.e. {FillBaseName}{fill level} for the state + /// + [DataField("fillBaseName")] + public string? FillBaseName; + + [DataField("layer")] + public StorageContainerVisualLayers FillLayer = StorageContainerVisualLayers.Fill; +} + +public enum StorageContainerVisualLayers : byte +{ + Fill +} diff --git a/Content.Client/Storage/Systems/StorageContainerVisualsSystem.cs b/Content.Client/Storage/Systems/StorageContainerVisualsSystem.cs new file mode 100644 index 0000000000..a13d6cba22 --- /dev/null +++ b/Content.Client/Storage/Systems/StorageContainerVisualsSystem.cs @@ -0,0 +1,44 @@ +using Content.Client.Storage.Components; +using Content.Shared.Rounding; +using Content.Shared.Storage; +using Robust.Client.GameObjects; + +namespace Content.Client.Storage.Systems; + +/// +public sealed class StorageContainerVisualsSystem : VisualizerSystem +{ + protected override void OnAppearanceChange(EntityUid uid, StorageContainerVisualsComponent component, ref AppearanceChangeEvent args) + { + if (args.Sprite == null) + return; + + if (!AppearanceSystem.TryGetData(uid, StorageVisuals.StorageUsed, out var used, args.Component)) + return; + + if (!AppearanceSystem.TryGetData(uid, StorageVisuals.Capacity, out var capacity, args.Component)) + return; + + var fraction = used / (float) capacity; + + if (!args.Sprite.LayerMapTryGet(component.FillLayer, out var fillLayer)) + return; + + var closestFillSprite = Math.Min(ContentHelpers.RoundToNearestLevels(fraction, 1, component.MaxFillLevels + 1), + component.MaxFillLevels); + + if (closestFillSprite > 0) + { + if (component.FillBaseName == null) + return; + + args.Sprite.LayerSetVisible(fillLayer, true); + var stateName = component.FillBaseName + closestFillSprite; + args.Sprite.LayerSetState(fillLayer, stateName); + } + else + { + args.Sprite.LayerSetVisible(fillLayer, false); + } + } +} diff --git a/Content.Server/Item/ItemSystem.cs b/Content.Server/Item/ItemSystem.cs index 55fb5aae09..efb99ae653 100644 --- a/Content.Server/Item/ItemSystem.cs +++ b/Content.Server/Item/ItemSystem.cs @@ -1,4 +1,5 @@ -using Content.Server.Storage.EntitySystems; +using Content.Server.Storage.Components; +using Content.Server.Storage.EntitySystems; using Content.Shared.Item; using Content.Shared.Stacks; using Content.Shared.Storage; @@ -15,11 +16,9 @@ public sealed class ItemSystem : SharedItemSystem if (!Container.TryGetContainingContainer(uid, out var container) || !TryComp(container.Owner, out var storage)) - { return; - } - _storage.RecalculateStorageUsed(storage); + _storage.RecalculateStorageUsed(container.Owner, storage); _storage.UpdateUI(container.Owner, storage); } } diff --git a/Content.Server/Projectiles/ProjectileSystem.cs b/Content.Server/Projectiles/ProjectileSystem.cs index 61d67a469b..60fc0c3b5c 100644 --- a/Content.Server/Projectiles/ProjectileSystem.cs +++ b/Content.Server/Projectiles/ProjectileSystem.cs @@ -9,7 +9,6 @@ using Content.Shared.Projectiles; using Robust.Server.GameObjects; using Robust.Shared.Player; using Robust.Shared.Physics.Events; -using Content.Shared.Effects; namespace Content.Server.Projectiles; @@ -30,7 +29,8 @@ public sealed class ProjectileSystem : SharedProjectileSystem private void OnStartCollide(EntityUid uid, ProjectileComponent component, ref StartCollideEvent args) { // This is so entities that shouldn't get a collision are ignored. - if (args.OurFixtureId != ProjectileFixture || !args.OtherFixture.Hard || component.DamagedEntity) + if (args.OurFixtureId != ProjectileFixture || !args.OtherFixture.Hard + || component.DamagedEntity || component is { Weapon: null, OnlyCollideWhenShot: true }) return; var target = args.OtherEntity; @@ -60,7 +60,7 @@ public sealed class ProjectileSystem : SharedProjectileSystem _adminLogger.Add(LogType.BulletHit, HasComp(target) ? LogImpact.Extreme : LogImpact.High, - $"Projectile {ToPrettyString(uid):projectile} shot by {ToPrettyString(component.Shooter):user} hit {otherName:target} and dealt {modifiedDamage.Total:damage} damage"); + $"Projectile {ToPrettyString(uid):projectile} shot by {ToPrettyString(component.Shooter!.Value):user} hit {otherName:target} and dealt {modifiedDamage.Total:damage} damage"); } if (!deleted) diff --git a/Content.Shared/Projectiles/EmbeddableProjectileComponent.cs b/Content.Shared/Projectiles/EmbeddableProjectileComponent.cs index cf9c15a10d..cde7e637d4 100644 --- a/Content.Shared/Projectiles/EmbeddableProjectileComponent.cs +++ b/Content.Shared/Projectiles/EmbeddableProjectileComponent.cs @@ -29,6 +29,12 @@ public sealed partial class EmbeddableProjectileComponent : Component [ViewVariables(VVAccess.ReadWrite), DataField("removalTime"), AutoNetworkedField] public float? RemovalTime = 3f; + /// + /// Whether this entity will embed when thrown, or only when shot as a projectile. + /// + [ViewVariables(VVAccess.ReadWrite), DataField("embedOnThrow"), AutoNetworkedField] + public bool EmbedOnThrow = true; + /// /// How far into the entity should we offset (0 is wherever we collided). /// diff --git a/Content.Shared/Projectiles/ProjectileComponent.cs b/Content.Shared/Projectiles/ProjectileComponent.cs index 1e77e3954c..276e0943e0 100644 --- a/Content.Shared/Projectiles/ProjectileComponent.cs +++ b/Content.Shared/Projectiles/ProjectileComponent.cs @@ -15,13 +15,14 @@ public sealed partial class ProjectileComponent : Component /// /// User that shot this projectile. /// - [DataField("shooter"), AutoNetworkedField] public EntityUid Shooter; + [DataField("shooter"), AutoNetworkedField] + public EntityUid? Shooter; /// /// Weapon used to shoot. /// [DataField("weapon"), AutoNetworkedField] - public EntityUid Weapon; + public EntityUid? Weapon; [DataField("ignoreShooter"), AutoNetworkedField] public bool IgnoreShooter = true; @@ -41,5 +42,14 @@ public sealed partial class ProjectileComponent : Component [DataField("soundForce")] public bool ForceSound = false; + /// + /// Whether this projectile will only collide with entities if it was shot from a gun (if is not null) + /// + [DataField("onlyCollideWhenShot")] + public bool OnlyCollideWhenShot = false; + + /// + /// Whether this projectile has already damaged an entity. + /// public bool DamagedEntity; } diff --git a/Content.Shared/Projectiles/SharedProjectileSystem.cs b/Content.Shared/Projectiles/SharedProjectileSystem.cs index 5d4046556a..92465be2e5 100644 --- a/Content.Shared/Projectiles/SharedProjectileSystem.cs +++ b/Content.Shared/Projectiles/SharedProjectileSystem.cs @@ -73,6 +73,14 @@ public abstract partial class SharedProjectileSystem : EntitySystem _physics.SetBodyType(uid, BodyType.Dynamic, body: physics, xform: xform); _transform.AttachToGridOrMap(uid, xform); + // Reset whether the projectile has damaged anything if it successfully was removed + if (TryComp(uid, out var projectile)) + { + projectile.Shooter = null; + projectile.Weapon = null; + projectile.DamagedEntity = false; + } + // Land it just coz uhhh yeah var landEv = new LandEvent(args.User, true); RaiseLocalEvent(uid, ref landEv); @@ -81,6 +89,9 @@ public abstract partial class SharedProjectileSystem : EntitySystem private void OnEmbedThrowDoHit(EntityUid uid, EmbeddableProjectileComponent component, ThrowDoHitEvent args) { + if (!component.EmbedOnThrow) + return; + Embed(uid, args.Target, component); } @@ -91,7 +102,7 @@ public abstract partial class SharedProjectileSystem : EntitySystem // Raise a specific event for projectiles. if (TryComp(uid, out var projectile)) { - var ev = new ProjectileEmbedEvent(projectile.Shooter, projectile.Weapon, args.Target); + var ev = new ProjectileEmbedEvent(projectile.Shooter!.Value, projectile.Weapon!.Value, args.Target); RaiseLocalEvent(uid, ref ev); } } diff --git a/Content.Shared/Storage/Components/ItemMapperComponent.cs b/Content.Shared/Storage/Components/ItemMapperComponent.cs index 4512503fde..fd83120af0 100644 --- a/Content.Shared/Storage/Components/ItemMapperComponent.cs +++ b/Content.Shared/Storage/Components/ItemMapperComponent.cs @@ -66,6 +66,11 @@ namespace Content.Shared.Storage.Components [DataField("containerWhitelist")] public HashSet? ContainerWhitelist; - public readonly List SpriteLayers = new(); + /// + /// The list of map layer keys that are valid targets for changing in + /// Can be initialized if already existing on the sprite, or inferred automatically + /// + [DataField("spriteLayers")] + public List SpriteLayers = new(); } } diff --git a/Content.Shared/Storage/EntitySystems/SharedStorageSystem.cs b/Content.Shared/Storage/EntitySystems/SharedStorageSystem.cs index 6f1336a53b..5faec99fd5 100644 --- a/Content.Shared/Storage/EntitySystems/SharedStorageSystem.cs +++ b/Content.Shared/Storage/EntitySystems/SharedStorageSystem.cs @@ -92,7 +92,7 @@ public abstract class SharedStorageSystem : EntitySystem if (component.Container == default) return; - RecalculateStorageUsed(component); + RecalculateStorageUsed(uid, component); UpdateStorageVisualization(uid, component); UpdateUI(uid, component); Dirty(uid, component); @@ -394,7 +394,7 @@ public abstract class SharedStorageSystem : EntitySystem _appearance.SetData(uid, StackVisuals.Hide, !storageComp.IsUiOpen); } - public void RecalculateStorageUsed(StorageComponent storageComp) + public void RecalculateStorageUsed(EntityUid uid, StorageComponent storageComp) { storageComp.StorageUsed = 0; @@ -406,6 +406,9 @@ public abstract class SharedStorageSystem : EntitySystem var size = itemComp.Size; storageComp.StorageUsed += size; } + + _appearance.SetData(uid, StorageVisuals.StorageUsed, storageComp.StorageUsed); + _appearance.SetData(uid, StorageVisuals.Capacity, storageComp.StorageCapacityMax); } public int GetAvailableSpace(EntityUid uid, StorageComponent? component = null) diff --git a/Content.Shared/Storage/SharedStorageComponent.cs b/Content.Shared/Storage/SharedStorageComponent.cs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Content.Shared/Storage/StorageComponent.cs b/Content.Shared/Storage/StorageComponent.cs index 0a924365a4..fdcf06bf5d 100644 --- a/Content.Shared/Storage/StorageComponent.cs +++ b/Content.Shared/Storage/StorageComponent.cs @@ -130,6 +130,8 @@ namespace Content.Shared.Storage Open, HasContents, CanLock, - Locked + Locked, + StorageUsed, + Capacity } } diff --git a/Content.Shared/Throwing/ThrowingSystem.cs b/Content.Shared/Throwing/ThrowingSystem.cs index e98beb96c9..35bfc069eb 100644 --- a/Content.Shared/Throwing/ThrowingSystem.cs +++ b/Content.Shared/Throwing/ThrowingSystem.cs @@ -106,7 +106,8 @@ public sealed class ThrowingSystem : EntitySystem return; } - if (projectileQuery.HasComponent(uid)) + // Allow throwing if this projectile only acts as a projectile when shot, otherwise disallow + if (projectileQuery.TryGetComponent(uid, out var proj) && !proj.OnlyCollideWhenShot) return; var comp = EnsureComp(uid); diff --git a/Content.Shared/Weapons/Marker/SharedDamageMarkerSystem.cs b/Content.Shared/Weapons/Marker/SharedDamageMarkerSystem.cs index 7289b232dc..119b10218d 100644 --- a/Content.Shared/Weapons/Marker/SharedDamageMarkerSystem.cs +++ b/Content.Shared/Weapons/Marker/SharedDamageMarkerSystem.cs @@ -64,7 +64,7 @@ public abstract class SharedDamageMarkerSystem : EntitySystem component.Amount <= 0 || component.Whitelist?.IsValid(args.OtherEntity, EntityManager) == false || !TryComp(uid, out var projectile) || - !projectile.Weapon.IsValid()) + projectile.Weapon == null) { return; } @@ -72,7 +72,7 @@ public abstract class SharedDamageMarkerSystem : EntitySystem // Markers are exclusive, deal with it. var marker = EnsureComp(args.OtherEntity); marker.Damage = new DamageSpecifier(component.Damage); - marker.Marker = projectile.Weapon; + marker.Marker = projectile.Weapon.Value; marker.EndTime = _timing.CurTime + component.Duration; component.Amount--; Dirty(marker); diff --git a/Content.Shared/Weapons/Reflect/SharedReflectSystem.cs b/Content.Shared/Weapons/Reflect/SharedReflectSystem.cs index f6193c6898..ffa8180e1a 100644 --- a/Content.Shared/Weapons/Reflect/SharedReflectSystem.cs +++ b/Content.Shared/Weapons/Reflect/SharedReflectSystem.cs @@ -119,7 +119,7 @@ public abstract class SharedReflectSystem : EntitySystem if (Resolve(projectile, ref projectileComp, false)) { - _adminLogger.Add(LogType.BulletHit, LogImpact.Medium, $"{ToPrettyString(user)} reflected {ToPrettyString(projectile)} from {ToPrettyString(projectileComp.Weapon)} shot by {projectileComp.Shooter}"); + _adminLogger.Add(LogType.BulletHit, LogImpact.Medium, $"{ToPrettyString(user)} reflected {ToPrettyString(projectile)} from {ToPrettyString(projectileComp.Weapon!.Value)} shot by {projectileComp.Shooter!.Value}"); projectileComp.Shooter = user; projectileComp.Weapon = user; diff --git a/Content.Shared/Wieldable/Components/WieldableComponent.cs b/Content.Shared/Wieldable/Components/WieldableComponent.cs index 5a8c533c29..050b638215 100644 --- a/Content.Shared/Wieldable/Components/WieldableComponent.cs +++ b/Content.Shared/Wieldable/Components/WieldableComponent.cs @@ -1,5 +1,6 @@ using Robust.Shared.Audio; using Robust.Shared.GameStates; +using Robust.Shared.Serialization; namespace Content.Shared.Wieldable.Components; @@ -33,3 +34,9 @@ public sealed partial class WieldableComponent : Component [DataField("wieldTime")] public float WieldTime = 1.5f; } + +[Serializable, NetSerializable] +public enum WieldableVisuals : byte +{ + Wielded +} diff --git a/Content.Shared/Wieldable/WieldableSystem.cs b/Content.Shared/Wieldable/WieldableSystem.cs index d4d83dfdf7..bf5aa1b723 100644 --- a/Content.Shared/Wieldable/WieldableSystem.cs +++ b/Content.Shared/Wieldable/WieldableSystem.cs @@ -24,6 +24,7 @@ public sealed class WieldableSystem : EntitySystem [Dependency] private readonly SharedItemSystem _itemSystem = default!; [Dependency] private readonly SharedPopupSystem _popupSystem = default!; [Dependency] private readonly SharedAudioSystem _audioSystem = default!; + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; public override void Initialize() { @@ -224,6 +225,7 @@ public sealed class WieldableSystem : EntitySystem var ev = new ItemWieldedEvent(); RaiseLocalEvent(uid, ref ev); + _appearance.SetData(uid, WieldableVisuals.Wielded, true); Dirty(component); args.Handled = true; @@ -254,6 +256,8 @@ public sealed class WieldableSystem : EntitySystem ("user", args.User.Value), ("item", uid)), args.User.Value, Filter.PvsExcept(args.User.Value), true); } + _appearance.SetData(uid, WieldableVisuals.Wielded, false); + Dirty(component); _virtualItemSystem.DeleteInHandsMatching(args.User.Value, uid); } diff --git a/Resources/Audio/Items/attributions.yml b/Resources/Audio/Items/attributions.yml index 267d6f3a0a..b69704ce69 100644 --- a/Resources/Audio/Items/attributions.yml +++ b/Resources/Audio/Items/attributions.yml @@ -62,3 +62,8 @@ license: "CC-BY-4.0" copyright: "User volivieri on freesound.org. Modified by Velcroboy on github." source: "https://freesound.org/people/volivieri/sounds/37190/" + +- files: ["bow_pull.ogg"] + license: "CC-BY-3.0" + copyright: "User jzdnvdoosj on freesound.org. Converted to ogg by mirrorcult" + source: "https://freesound.org/people/jzdnvdoosj/sounds/626262/" \ No newline at end of file diff --git a/Resources/Audio/Items/bow_pull.ogg b/Resources/Audio/Items/bow_pull.ogg new file mode 100644 index 0000000000000000000000000000000000000000..728489b9762ed0576c95d25ca697df6223a04f3c GIT binary patch literal 17266 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 J4KD-ue*l0CGmHQL literal 0 HcmV?d00001 diff --git a/Resources/Audio/Weapons/Guns/Misc/arrow_nock.ogg b/Resources/Audio/Weapons/Guns/Misc/arrow_nock.ogg new file mode 100644 index 0000000000000000000000000000000000000000..2285c47edf6419a98e6232508476223a9b87485c GIT binary patch literal 6503 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 C5%=l< literal 0 HcmV?d00001 diff --git a/Resources/Audio/Weapons/Guns/Misc/attributions.yml b/Resources/Audio/Weapons/Guns/Misc/attributions.yml new file mode 100644 index 0000000000..066c26206e --- /dev/null +++ b/Resources/Audio/Weapons/Guns/Misc/attributions.yml @@ -0,0 +1,4 @@ +- files: ["arrow_nock.ogg"] + license: "CC-BY-NC-4.0" + copyright: "Created by LiamG_SFX, converted to ogg by mirrorcult" + source: "https://freesound.org/people/LiamG_SFX/sounds/322224/" \ No newline at end of file diff --git a/Resources/Prototypes/Catalog/Fills/Lockers/misc.yml b/Resources/Prototypes/Catalog/Fills/Lockers/misc.yml index 32c1cfb506..9ed3acc049 100644 --- a/Resources/Prototypes/Catalog/Fills/Lockers/misc.yml +++ b/Resources/Prototypes/Catalog/Fills/Lockers/misc.yml @@ -204,6 +204,8 @@ prob: 0.2 - id: ClothingHandsGlovesColorYellow prob: 0.05 + - id: ClothingBeltQuiver + prob: 0.02 - id: ClothingBeltUtility prob: 0.10 - id: ClothingHeadHatCone diff --git a/Resources/Prototypes/Entities/Clothing/Belt/quiver.yml b/Resources/Prototypes/Entities/Clothing/Belt/quiver.yml new file mode 100644 index 0000000000..10332e46aa --- /dev/null +++ b/Resources/Prototypes/Entities/Clothing/Belt/quiver.yml @@ -0,0 +1,22 @@ +- type: entity + parent: ClothingBeltStorageBase + id: ClothingBeltQuiver + name: quiver + description: Can hold up to 15 arrows, and fits snug around your waist. + components: + - type: Sprite + sprite: Clothing/Belt/quiver.rsi + layers: + - state: icon + - map: [ "enum.StorageContainerVisualLayers.Fill" ] + visible: false + - type: Clothing + - type: Storage + capacity: 150 + whitelist: + tags: + - Arrow + - type: Appearance + - type: StorageContainerVisuals + maxFillLevels: 3 + fillBaseName: fill- diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Bow/bow.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Bow/bow.yml new file mode 100644 index 0000000000..95282ee63a --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Bow/bow.yml @@ -0,0 +1,81 @@ +- type: entity + name: bow + parent: BaseItem + id: BaseBow + description: The original rooty tooty point and shooty. + abstract: true + components: + - type: Sprite + sprite: Objects/Weapons/Guns/Bow/bow.rsi + - type: Item + size: 60 + - type: Clothing + quickEquip: false + slots: + - Back + - type: Wieldable + wieldTime: 0.5 + wieldSound: + path: /Audio/Items/bow_pull.ogg + - type: GunRequiresWield + - type: Gun + minAngle: 0 + maxAngle: 5 + fireRate: 1 + selectedMode: SemiAuto + availableModes: + - SemiAuto + soundGunshot: + collection: BulletMiss + soundEmpty: null + - type: ItemSlots + slots: + arrow: + name: Arrow + startingItem: null + insertSound: /Audio/Weapons/Guns/Misc/arrow_nock.ogg + whitelist: + tags: + - Arrow + - type: ContainerContainer + containers: + arrow: !type:ContainerSlot + - type: ContainerAmmoProvider + container: arrow + +- type: entity + id: BowImprovised + parent: BaseBow + components: + - type: Sprite + layers: + - state: unwielded + map: [ base ] + - state: unwielded-arrow + map: [ arrow ] + visible: false + # to elucidate whats intended here: + # arrow is inserted -> ItemMapper sets layer with map `arrow` to visible + # bow is wielded -> generic vis sets states of layers with map `arrow` and `base` + # arrow is removed -> itemmapper sets layer with map `arrow` to invisible + - type: Appearance + - type: ItemMapper + spriteLayers: + - arrow + mapLayers: + arrow: + whitelist: + tags: + - Arrow + - type: GenericVisualizer + visuals: + enum.WieldableVisuals.Wielded: + arrow: + True: { state: wielded-arrow } + False: { state: unwielded-arrow } + base: + True: { state: wielded } + False: { state: unwielded } + - type: Construction + graph: ImprovisedBow + node: ImprovisedBow diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/arrows.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/arrows.yml new file mode 100644 index 0000000000..7112d07f2f --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/arrows.yml @@ -0,0 +1,84 @@ +- type: entity + parent: BaseItem + id: BaseArrow + abstract: true + components: + - type: Item + size: 10 + - type: Sprite + sprite: Objects/Weapons/Guns/Projectiles/arrows.rsi + - type: Fixtures + fixtures: + fix1: + shape: !type:PhysShapeCircle + radius: 0.2 + density: 5 + mask: + - ItemMask + restitution: 0.3 + friction: 0.2 + projectile: + shape: + !type:PhysShapeAabb + bounds: "-0.1,-0.1,0.1,0.1" + hard: false + mask: + - Impassable + - BulletImpassable + - type: EmbeddableProjectile + sound: /Audio/Weapons/star_hit.ogg + embedOnThrow: false + - type: ThrowingAngle + angle: 0 + - type: Ammo + muzzleFlash: null + - type: Tag + tags: + - Arrow + - type: Projectile + deleteOnCollide: false + onlyCollideWhenShot: true + damage: + types: + Piercing: 25 + +- type: entity + parent: BaseArrow + id: ArrowRegular + name: arrow + description: You can feel the power of the steppe within you. + components: + - type: Sprite + layers: + - state: tail + color: red + - state: rod + color: brown + - state: tip + - type: Projectile + damage: + types: + Piercing: 35 + +- type: entity + parent: BaseArrow + id: ArrowImprovised + name: glass shard arrow + description: The greyshirt's preferred projectile. + components: + - type: Sprite + sprite: Objects/Weapons/Guns/Projectiles/arrows.rsi + layers: + - state: tail + color: white + - state: rod + color: darkgray + - state: tip + color: lightblue + - type: Projectile + damage: + types: + Piercing: 25 + - type: Construction + graph: ImprovisedArrow + node: ImprovisedArrow diff --git a/Resources/Prototypes/Recipes/Construction/Graphs/weapons/improvised_arrow.yml b/Resources/Prototypes/Recipes/Construction/Graphs/weapons/improvised_arrow.yml new file mode 100644 index 0000000000..346b49cf2f --- /dev/null +++ b/Resources/Prototypes/Recipes/Construction/Graphs/weapons/improvised_arrow.yml @@ -0,0 +1,23 @@ +- type: constructionGraph + id: ImprovisedArrow + start: start + graph: + - node: start + edges: + - to: ImprovisedArrow + steps: + - material: MetalRod + amount: 1 + doAfter: 0.5 + - material: Cloth + amount: 1 + doAfter: 0.5 + - tag: GlassShard + name: Glass Shard + icon: + sprite: Objects/Materials/Shards/shard.rsi + state: shard1 + doAfter: 0.5 + + - node: ImprovisedArrow + entity: ArrowImprovised diff --git a/Resources/Prototypes/Recipes/Construction/Graphs/weapons/improvised_bow.yml b/Resources/Prototypes/Recipes/Construction/Graphs/weapons/improvised_bow.yml new file mode 100644 index 0000000000..33808fc0ac --- /dev/null +++ b/Resources/Prototypes/Recipes/Construction/Graphs/weapons/improvised_bow.yml @@ -0,0 +1,17 @@ +- type: constructionGraph + id: ImprovisedBow + start: start + graph: + - node: start + edges: + - to: ImprovisedBow + steps: + - material: WoodPlank + amount: 10 + doAfter: 4 + - material: Cloth + amount: 5 + doAfter: 4 + + - node: ImprovisedBow + entity: BowImprovised diff --git a/Resources/Prototypes/Recipes/Construction/weapons.yml b/Resources/Prototypes/Recipes/Construction/weapons.yml index 9d8be93601..25da0d1073 100644 --- a/Resources/Prototypes/Recipes/Construction/weapons.yml +++ b/Resources/Prototypes/Recipes/Construction/weapons.yml @@ -40,7 +40,7 @@ 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 + objectType: Item - type: construction name: crude spear @@ -118,3 +118,25 @@ 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 diff --git a/Resources/Prototypes/tags.yml b/Resources/Prototypes/tags.yml index db260b5155..61acbe2ba8 100644 --- a/Resources/Prototypes/tags.yml +++ b/Resources/Prototypes/tags.yml @@ -16,6 +16,9 @@ - type: Tag id: ArtifactFragment +- type: Tag + id: Arrow + - type: Tag id: ATVKeys @@ -26,7 +29,7 @@ id: Balloon - type: Tag - id: BaseballBat + id: BaseballBat - type: Tag id: BBQsauce @@ -306,7 +309,7 @@ id: CluwneHorn - type: Tag #Ohioans die happy - id: Corn + id: Corn - type: Tag id: Coldsauce @@ -1014,7 +1017,7 @@ - type: Tag id: WallmountSubstationElectronics - + - type: Tag id: WeaponPistolCHIMPUpgradeKit diff --git a/Resources/Textures/Clothing/Belt/quiver.rsi/equipped-BELT.png b/Resources/Textures/Clothing/Belt/quiver.rsi/equipped-BELT.png new file mode 100644 index 0000000000000000000000000000000000000000..951e4421f0f1b9f82224ec0f4c527c33e8e892c4 GIT binary patch literal 510 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9F5M?jcysy3fA0|Vm* zPZ!6KiaBp*8Tz$2NVMKptKyL6->7DC+bQv(s?HaVX>FI3*IeJQp&`e4o8m?38vz*` zd#7%^@ZgUi&$=CFHe?$;{=L72hxf@@^D{h8()pjPV3@F&$)S&n!BUF>jniN#epkh_ zc2cVFALco%cbL9jer>&O+2&u5>LmBDs54&r>E+kOD(6!yd9*a@nWJ}sP=M*%xt8l1 zIZw&h8JRPeX530XY0gTnrHQKYLSzZ^JVZQW5Kvr9AkI;p+V!yBaTz(*7V~_}Dn=vA-hoM)xJx)E-!!yy9~<>Ytr=<<-5GK*ja7nTNQRmNivq0yzwx Lu6{1-oD!MZ|^?F2-Nr> Zl3OrT)H7&pPZp5J;OXk;vd$@?2>@+%D`@}# literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Belt/quiver.rsi/fill-3.png b/Resources/Textures/Clothing/Belt/quiver.rsi/fill-3.png new file mode 100644 index 0000000000000000000000000000000000000000..8870c8892fe61d324d1a12c99ed34661556453ed GIT binary patch literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}_MR?|ArY-_ z&u!#nP!M6h_~vocyZuf&E*mZ!ddB|b9#i=xf1R6?l0V){voYFq{Iq-62eY7OCPIR} e%s|ZtRx`4ll7E}&UUC@7WAJqKb6Mw<&;$TBYb^-? literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Belt/quiver.rsi/icon.png b/Resources/Textures/Clothing/Belt/quiver.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..c719b3030ce1721f60a31dd4509a4c2d7a925a1d GIT binary patch literal 473 zcmV;~0Ve*5P)+!DEC zqLp3%V1B*B&yw6Gf8R5J%m5s2k(2TLr1=kFepV8}{DQ}i46;kV6v-gb1UAyR4osT<0F-hUX3_UC{&t0^?X3SpA5f zuUvxw0eQ;-pg}^2?@9G;>LElQTu)pN^B%%Bh<86P2@J@t z!4qA`nREXh`mEY;40+#mp@bW`NrGJ3@28Pf-op&0a(ARaWJy4`o6P)Px$l1W5CRCt{2nz2s9Kn#W*#Lko(*^nwR+`!PhK(~0P#A6`!1(Jv0Nf^RQFy6-0 zfiW99k{M8i=z<;f;+*4ecGF*f>^q-x0FL8uKt$5k@E=n&UU36sjM8V%PK+_%iz1@M zXTW{~bl8GOCp!bI;s$67(8dkW7NCtApe^81AR>L;A?*5B(eJLgfguF3s5!~rsMU47 z_(tdffS$k`ArWqXwg7G10B+zojyZLxQE>x_h^ne$$IngIbp!y=G!3+E%hqY81X4H+5)s;Uza~|3AdXFLXFz1cUob4x?staV^U36U+(3x{1Jn5*_BetoB{#-)DC2g8S!*A&l9%hd2bK7%Qi-jpMys%)83Qbj?$+30r z@*~a<6kA>^?@K!rKi4AMNtD?^{qXw!+XmnMeO-Bu=dSGP|YV& z_Sg49H`}*wogB5MDzI0}b}iQ8v3u5%tnkG?z45D8br2Ak8gw|O!l%!AZ`~Ll>-_>*T63nf-pJl|q)cd?rAY}4_ zu)`)-kDhJN(0!g9;dwKR@qo(Li&rvC&vZMT*v1#JUvxso@zo3o(Qjm8=iWC_HC)AD z(f;{QA463^=iE(JDbh?=Bwi#drtm6s{ddwlT~t2rS!Ugv;FW! zhatdF=GW8j3qzC47=nCP@~3eobU|b4408p0waNbw{gyB1fyslx)78&qol`;+0PKnU Awg3PC literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Weapons/Guns/Bow/bow.rsi/inhand-right.png b/Resources/Textures/Objects/Weapons/Guns/Bow/bow.rsi/inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..c281a198704c1e88957ddb99eb35b836dd5187f3 GIT binary patch literal 584 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9F5M?jcysy3fA0|VnP zPZ!6KiaBp*Ip#GR2)NcSxwjzcvT(_L-)auAz3%;&t5Xh&DqWTSHgVT0sjqBPSFj(w zvV*ZFA!_za^-xYu6J!4LHwJecEVLL71u_csaWxc#FtjXYQjig4c(|frDf^Vvo0pP9 zL)qUnxH3hZKKQAoU(8xDs=-^XbF<003`R>8|A0BJfm?hpyByuUgYAjIAI+Z;oZTz| zj5ddc@j74C=K4~$;QP(I`?oDUkQ*!)EL6wI zQNGOhzUuqGm!~YW@H{lR_Fq+JrPm<`haJMT&oggapQ&5racFMu-YuFtS#Qs1iDOWG zz2EcdJg&HPGrZqSIsWmFv5DyS(Sfu@jdzOq)80QD( zMGiZEx1H=|c-Oaa@~*EdKHXfyQN(&mH&K}JPWsC)kvE)v-zYl6vYK_rG|LML?wfYF zw(YVxCNYgkS~Wqd^0T|SPeJXmH4QtB=NJEPx$97#k$R9J=Wlrc`jFcgOWXQyc;1}+eZt&#_jaN!g_1d}CD55&MVvUT79#UQb8 z4hAGz;yfm*HX@}VwX^t>JlfwUKg+0p4ep`P3x_$uwBB~ELr}qu~CT|Arqt_#RoCq(^fTnyq;?SGu zid+)$d`i3+6aTz}<_aO+VJQZbClZN7B5^Ff0c^sUH!(4mdH?_b07*qoM6N<$f_F=n A9RL6T literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Weapons/Guns/Bow/bow.rsi/unwielded.png b/Resources/Textures/Objects/Weapons/Guns/Bow/bow.rsi/unwielded.png new file mode 100644 index 0000000000000000000000000000000000000000..c5dc00243cff878e49e75148d5ef6515bfb6b431 GIT binary patch literal 511 zcmVw9Uhq~?;|uh_-!&^F~=?vvcT_rA9QYt}!26yW?2 zxa|MiNAP+Fpvm9A<-v6@S1?Ne^~vA9x(5mvTaYDym+c6Ws{}63VtD@K{_o(?uJ=RV zds_eklt5@4DM=ED<5&x*u>?g?!0;fF1`8+wA{3s6i?Mm0a~%kyEU3R7oNNJ8mL;TV zYW@ZoV>FoKQz+j6V|{`cG6u(V571NN4G;thI0`R)P!K_!c(Y}>!3VeiuwMeA(1Ez; z+z6s`5Bvqh%1!7BqAfd=vcMMNA&Od4R5=Z8Ai{7~C$cPS#A(%mDm?}R&c|bA2ujhN zju`zyG?{o_5GX^4IuX1w*xz&kU;y#)#H#)wler<$glLnUBXR&?Z^;k>Kb5kBS~#`u zx`%M$30I{kbx&&HvVGvplPx$7fD1xR9J=Wlrc`jFcgOW=NQ@xFf&of14wp@lshf@!9rmT%pBwZ-ON1Dt~CBx=zhNFFu7DHs4X5H61v;1o0i8#+)PCBP{Z3^YUJ zqXV461p_+*yh~;ZOPf%f~YS5K)&r;5YgAfRPc>cj0j=+TtAOlYa%q*hDXDB3{mj vA11`iEdDx40svqw{PLs$K8_xc$&BR_*Nvecl^eK<00000NkvXXu0mjf#TSt_ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Weapons/Guns/Bow/bow.rsi/wielded-inhand-left.png b/Resources/Textures/Objects/Weapons/Guns/Bow/bow.rsi/wielded-inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..75a9329f7044185ddcba35677066c1d2c9c5559f GIT binary patch literal 415 zcmV;Q0bu@#P)Px$SxH1eRCt{2+QDhVFcg5{r_up>(Fg^X9(2eYPmt0vJc5oHp?mbuNpvf8i4IUu zFLAIP*^X2NQusgc!GWju?5FsmCjtNf0001hI%$QfrjoT(HKmj$G4uOY?n(oWg`8bx zf%jgVb459vbK9SJ-(LU#002ov JPDHLkV1hfPw&VZ+ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Weapons/Guns/Bow/bow.rsi/wielded-inhand-right.png b/Resources/Textures/Objects/Weapons/Guns/Bow/bow.rsi/wielded-inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..87451fed6ca2ff5fd2ff58cd605e3353acca5ead GIT binary patch literal 410 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D%zLp)s^Ln`LH zy|p*@uz^6^!}E@89*YH;G&~L-DxSl@DtTCW!xxU5%C2gG;tJj=4Ghzdapg4rTIh3_ z?}J@~)NQ5reM@F9W&xTC1SikboZ9+$wo%XdyLZpHCGYdDm2e8UY;vn-!jr?#!?=n& z-uquR;Zl6Uf92XKKaJ3qouVEu%M;%H(JZc1DQ{5OTc2h8?e2`kuS-j{FT6h>^z2i_ zoRsL()5TIFzM3A5v3C1^@6!Er(Fe~jia1^PUblYx;oa6J<Lm+t!i>jYoL%RAo3 z&qS^WJ#%LJrIVAZk9ptJ`d<$U2?*G(bF5;cHP_<14~uu~J}%MCdb4zH+&nY&@1m<# z?V7tSA~dv4CLntHd+}wz{)FovGWd9J)@jkDQ|?rrJh=Q^V)SYKxivi(%Y|bfc9*R> zn`3ftZpfEA=U+az-u_~>o{)_Hk3UlWdOkp_{)q4A*>onTQLecGWU;5KpUXO@geCwD C^SVd? literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Weapons/Guns/Bow/bow.rsi/wielded.png b/Resources/Textures/Objects/Weapons/Guns/Bow/bow.rsi/wielded.png new file mode 100644 index 0000000000000000000000000000000000000000..41d15ef89a9d61d18de4f11944a3186539b9e6bc GIT binary patch literal 596 zcmV-a0;~OrP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!~g&e!~vBn4jTXf0qIFZK~z{r?Uubu z12Gi9Uy8j+6v4qk3MxWJ3xb_>yj%Pm9Hf)0;OL;MQ~#0PBsy0R>aJC(4sK$hib{=3%IC8IJ?sSei{-T(%_vp@gYWOUR02* zWFnoYgWtanN|n_GQ9-24v?7tluIutztp-PX9^Aa}f_OY+V~GV+#zpQH-LOt=Jl&|w^sqM+=^po~>2l`yDnqtVc=pEMEzCP)#A_q8wCR;!iB01DYn5lw@D znFh7l2jHg|q8nqhcGxL(WR;yA#)5S$S1=A!`qeSf6zI6%yl@K;wC4a$EHYt~0mhhd zhuhe^gc9X0d|)Pu;&CdOWk7O?zMU@g9{^_5HIcSEG8Z6F!olh2p#+cwEz-0tnu`E| z60;})j~H}D5cPUJELCz7AZTGex%xwGB(w;T;XW6St�%3UG88BoQauYFNV zl8b;%)^c3~CVZ;^-JJ1tFjm0k6ih>2;X1SeI4EO|6J#;?IDYXO==T{Ei^B}aJsl76 z^~8+MfRs=~vc~uy;J=+n0$(rFJ4BYKHd-=wEb;V9?`mKRaAT7~mtFYy|ms{la~ iq6)t6=RV$F1K<;81NP6Fy}-Tz0000s)YCO z?%7m%cv|h1GvXzpY-mnFb>kt{h^n0XlNA4%A7ZVU%f4q%{jRH@#iX7HVNEzw)&x*EfGj^JzcV^Nec7}UP%JQby85}Sb4q9e E02Rfnv;Y7A literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Weapons/Guns/Projectiles/arrows.rsi/inhand-right.png b/Resources/Textures/Objects/Weapons/Guns/Projectiles/arrows.rsi/inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..42e1ebc3a65b3c3125399e00957dcf8fd460fa4d GIT binary patch literal 440 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9F5M?jcysy3fA0|R50 zr;B4q#hkad4D*@|L>eC22k}o{8CS)lAA0?n*jcJM1v9iPXW;N>l&cJkoOVv4dFwZa zXSOT_KQ#@OrSY>e?~yAEJ-u+#G+PlC1D^AJvv@Zge^|Sju}ISHi_=|Ji{{_9&y4q+ zpMO<(&(;s;zU*{oY*ws3-E(kf?x=mREc2Ic$*V<-HT4m3eyMA= zFV^UiGy3Xh#C72QsXZO_N83WfwOWocWasn-E9o#r6sOMPN)$YBEBdi-4b!>@MKLq_ zL|GoR&);2kZm9x;{hvGba!-N;9NuYv{(tMu+7D6i0C~@L%s%IF`O**nflFVdQ I&MBb@0IJNlJ^%m! literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Weapons/Guns/Projectiles/arrows.rsi/meta.json b/Resources/Textures/Objects/Weapons/Guns/Projectiles/arrows.rsi/meta.json new file mode 100644 index 0000000000..b8313f7810 --- /dev/null +++ b/Resources/Textures/Objects/Weapons/Guns/Projectiles/arrows.rsi/meta.json @@ -0,0 +1,31 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "tgstation at a373b4cb08298523d40acc14f9c390a0c403fc31, sprites modified and cut into layers by mirrorcult", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "tail" + }, + { + "name": "rod" + }, + { + "name": "tip" + }, + { + "name": "solution" + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Objects/Weapons/Guns/Projectiles/arrows.rsi/rod.png b/Resources/Textures/Objects/Weapons/Guns/Projectiles/arrows.rsi/rod.png new file mode 100644 index 0000000000000000000000000000000000000000..935df1f13d5d8c882aa6f28e15bfbb3847607de4 GIT binary patch literal 157 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;>1s;*b3=DinK$vl=HlH+5(8$xpF(ktM?YV`b3<^BX2kpMi*UoNy$r7Tl x!?^PgtHIQi?|U~@%@3d_5e^fgQu&X%Q~loCID%oD(nCN literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Weapons/Guns/Projectiles/arrows.rsi/solution.png b/Resources/Textures/Objects/Weapons/Guns/Projectiles/arrows.rsi/solution.png new file mode 100644 index 0000000000000000000000000000000000000000..235f318e60aeb77a3ec06c86bb8a2c044a200358 GIT binary patch literal 257 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;>1s;*b3=DinK$vl=HlH+5aGIx!V@QO1vIOhm1d*PmKm#tfgBlVU2RN2` zvQ5{IPh$_7>TqZI>eatFbv)P-nl3$QhG@%Z5fqhJ{-t{JzhqI}3CngQu&X%Q~loCICO}Ov?ZO literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Weapons/Guns/Projectiles/arrows.rsi/tail.png b/Resources/Textures/Objects/Weapons/Guns/Projectiles/arrows.rsi/tail.png new file mode 100644 index 0000000000000000000000000000000000000000..31c4ed7e1f6d6e30c76b2b50f8c5d4bb6ca7828f GIT binary patch literal 153 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;>1s;*b3=DinK$vl=HlH+5P|wrFF(ktM?YV`#3_}IDYpOs literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Weapons/Guns/Projectiles/arrows.rsi/tip.png b/Resources/Textures/Objects/Weapons/Guns/Projectiles/arrows.rsi/tip.png new file mode 100644 index 0000000000000000000000000000000000000000..e4e795295d9bdee965accee03619d8703c080c8b GIT binary patch literal 161 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;>1s;*b3=DinK$vl=HlH+5(9F}tF(ktM?fH$o2Ml*c;) zG>f79>~t1p28R9D?!Ld-nO?qT)v?F(cU1CEP~qOPgS)$0#?lXH0)wZkpUXO@geCxO CX)j#> literal 0 HcmV?d00001 -- 2.51.2