diff --git a/Content.Server/Explosion/Components/ExplosiveComponent.cs b/Content.Server/Explosion/Components/ExplosiveComponent.cs index 04a08955a35..2b27a89d9db 100644 --- a/Content.Server/Explosion/Components/ExplosiveComponent.cs +++ b/Content.Server/Explosion/Components/ExplosiveComponent.cs @@ -81,6 +81,13 @@ public sealed partial class ExplosiveComponent : Component [DataField("deleteAfterExplosion")] public bool? DeleteAfterExplosion; + /// + /// Whether to not set to true, allowing it to explode multiple times. + /// This should never be used if it is damageable. + /// + [DataField] + public bool Repeatable; + /// /// Avoid somehow double-triggering this explosion (e.g. by damaging this entity from its own explosion. /// diff --git a/Content.Server/Explosion/Components/RepeatingTriggerComponent.cs b/Content.Server/Explosion/Components/RepeatingTriggerComponent.cs new file mode 100644 index 00000000000..cc08de53f90 --- /dev/null +++ b/Content.Server/Explosion/Components/RepeatingTriggerComponent.cs @@ -0,0 +1,25 @@ +using Content.Server.Explosion.EntitySystems; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; + +namespace Content.Server.Explosion.Components; + +/// +/// Constantly triggers after being added to an entity. +/// +[RegisterComponent, Access(typeof(TriggerSystem))] +[AutoGenerateComponentPause] +public sealed partial class RepeatingTriggerComponent : Component +{ + /// + /// How long to wait between triggers. + /// The first trigger starts this long after the component is added. + /// + [DataField] + public TimeSpan Delay = TimeSpan.FromSeconds(1); + + /// + /// When the next trigger will be. + /// + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoPausedField] + public TimeSpan NextTrigger; +} diff --git a/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs b/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs index 1f91b28ec2b..eb2cf9b6548 100644 --- a/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs +++ b/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs @@ -165,7 +165,7 @@ public void TriggerExplosive(EntityUid uid, ExplosiveComponent? explosive = null if (explosive.Exploded) return; - explosive.Exploded = true; + explosive.Exploded = !explosive.Repeatable; // Override the explosion intensity if optional arguments were provided. if (radius != null) diff --git a/Content.Server/Explosion/EntitySystems/TriggerSystem.cs b/Content.Server/Explosion/EntitySystems/TriggerSystem.cs index eb5aeec8158..37c63438152 100644 --- a/Content.Server/Explosion/EntitySystems/TriggerSystem.cs +++ b/Content.Server/Explosion/EntitySystems/TriggerSystem.cs @@ -98,6 +98,7 @@ public override void Initialize() SubscribeLocalEvent(OnStepTriggered); SubscribeLocalEvent(OnSlipTriggered); SubscribeLocalEvent(OnEmptyTriggered); + SubscribeLocalEvent(OnRepeatInit); SubscribeLocalEvent(OnSpawnTrigger); SubscribeLocalEvent(HandleDeleteTrigger); @@ -278,6 +279,11 @@ private void OnEmptyTriggered(EntityUid uid, TriggerWhenEmptyComponent component Trigger(uid, args.EmptyGun); } + private void OnRepeatInit(Entity ent, ref MapInitEvent args) + { + ent.Comp.NextTrigger = _timing.CurTime + ent.Comp.Delay; + } + public bool Trigger(EntityUid trigger, EntityUid? user = null) { var triggerEvent = new TriggerEvent(trigger, user); @@ -360,6 +366,7 @@ public override void Update(float frameTime) UpdateProximity(); UpdateTimer(frameTime); UpdateTimedCollide(frameTime); + UpdateRepeat(); } private void UpdateTimer(float frameTime) @@ -394,5 +401,19 @@ private void UpdateTimer(float frameTime) _appearance.SetData(uid, TriggerVisuals.VisualState, TriggerVisualState.Unprimed, appearance); } } + + private void UpdateRepeat() + { + var now = _timing.CurTime; + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var comp)) + { + if (comp.NextTrigger > now) + continue; + + comp.NextTrigger = now + comp.Delay; + Trigger(uid); + } + } } } diff --git a/Content.Shared/Access/Components/IdCardConsoleComponent.cs b/Content.Shared/Access/Components/IdCardConsoleComponent.cs index 5fe5fe1024b..16aaae9b45b 100644 --- a/Content.Shared/Access/Components/IdCardConsoleComponent.cs +++ b/Content.Shared/Access/Components/IdCardConsoleComponent.cs @@ -72,7 +72,6 @@ public WriteToTargetIdMessage(string fullName, string jobTitle, List public static int CountFreeHands(this HandsComponent component) => component.Hands.Values.Count(hand => hand.IsEmpty); + /// + /// Get the number of hands that are not currently holding anything. This is a LinQ method, not a property, so + /// cache it instead of accessing this multiple times. + /// + public static int CountFreeableHands(this Entity component, SharedHandsSystem system) + { + return system.CountFreeableHands(component); + } + /// /// Get a list of hands that are currently holding nothing. This is a LinQ method, not a property, so cache /// it instead of accessing this multiple times. diff --git a/Content.Shared/Hands/EntitySystems/SharedHandsSystem.cs b/Content.Shared/Hands/EntitySystems/SharedHandsSystem.cs index fd732009e9a..e48aafeab52 100644 --- a/Content.Shared/Hands/EntitySystems/SharedHandsSystem.cs +++ b/Content.Shared/Hands/EntitySystems/SharedHandsSystem.cs @@ -5,7 +5,6 @@ using Content.Shared.Hands.Components; using Content.Shared.Interaction; using Content.Shared.Inventory.VirtualItem; -using Content.Shared.Item; using Content.Shared.Storage.EntitySystems; using Robust.Shared.Containers; using Robust.Shared.Input.Binding; @@ -299,4 +298,16 @@ public bool TryGetHand(EntityUid handsUid, string handId, [NotNullWhen(true)] ou return hands.Hands.TryGetValue(handId, out hand); } + + public int CountFreeableHands(Entity hands) + { + var freeable = 0; + foreach (var hand in hands.Comp.Hands.Values) + { + if (hand.IsEmpty || CanDropHeld(hands, hand)) + freeable++; + } + + return freeable; + } } diff --git a/Content.Shared/Inventory/VirtualItem/SharedVirtualItemSystem.cs b/Content.Shared/Inventory/VirtualItem/SharedVirtualItemSystem.cs index e45530e4582..b31cc755763 100644 --- a/Content.Shared/Inventory/VirtualItem/SharedVirtualItemSystem.cs +++ b/Content.Shared/Inventory/VirtualItem/SharedVirtualItemSystem.cs @@ -4,6 +4,7 @@ using Content.Shared.Interaction; using Content.Shared.Inventory.Events; using Content.Shared.Item; +using Content.Shared.Popups; using Robust.Shared.Containers; using Robust.Shared.Network; using Robust.Shared.Prototypes; @@ -29,6 +30,7 @@ public abstract class SharedVirtualItemSystem : EntitySystem [Dependency] private readonly SharedItemSystem _itemSystem = default!; [Dependency] private readonly InventorySystem _inventorySystem = default!; [Dependency] private readonly SharedHandsSystem _handsSystem = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; [ValidatePrototypeId] private const string VirtualItem = "VirtualItem"; @@ -71,23 +73,53 @@ private void OnBeforeRangedInteract(Entity ent, ref Before } #region Hands + /// /// Spawns a virtual item in a empty hand /// /// The entity we will make a virtual entity copy of /// The entity that we want to insert the virtual entity - public bool TrySpawnVirtualItemInHand(EntityUid blockingEnt, EntityUid user) + /// Whether or not to try and drop other items to make space + public bool TrySpawnVirtualItemInHand(EntityUid blockingEnt, EntityUid user, bool dropOthers = false) { - return TrySpawnVirtualItemInHand(blockingEnt, user, out _); + return TrySpawnVirtualItemInHand(blockingEnt, user, out _, dropOthers); } - /// - public bool TrySpawnVirtualItemInHand(EntityUid blockingEnt, EntityUid user, [NotNullWhen(true)] out EntityUid? virtualItem) + /// + public bool TrySpawnVirtualItemInHand(EntityUid blockingEnt, EntityUid user, [NotNullWhen(true)] out EntityUid? virtualItem, bool dropOthers = false) { - if (!TrySpawnVirtualItem(blockingEnt, user, out virtualItem) || !_handsSystem.TryGetEmptyHand(user, out var hand)) + virtualItem = null; + if (!_handsSystem.TryGetEmptyHand(user, out var empty)) + { + if (!dropOthers) + return false; + + foreach (var hand in _handsSystem.EnumerateHands(user)) + { + if (hand.HeldEntity is not { } held) + continue; + + if (held == blockingEnt || HasComp(held)) + continue; + + if (!_handsSystem.TryDrop(user, hand)) + continue; + + if (!TerminatingOrDeleted(held)) + _popup.PopupClient(Loc.GetString("virtual-item-dropped-other", ("dropped", held)), user, user); + + empty = hand; + break; + } + } + + if (empty == null) + return false; + + if (!TrySpawnVirtualItem(blockingEnt, user, out virtualItem)) return false; - _handsSystem.DoPickup(user, hand, virtualItem.Value); + _handsSystem.DoPickup(user, empty, virtualItem.Value); return true; } @@ -120,6 +152,7 @@ public void DeleteInHandsMatching(EntityUid user, EntityUid matching) /// The entity we will make a virtual entity copy of /// The entity that we want to insert the virtual entity /// The slot to which we will insert the virtual entity (could be the "shoes" slot, for example) + /// Whether or not to force an equip public bool TrySpawnVirtualItemInInventory(EntityUid blockingEnt, EntityUid user, string slot, bool force = false) { return TrySpawnVirtualItemInInventory(blockingEnt, user, slot, force, out _); @@ -140,6 +173,8 @@ public bool TrySpawnVirtualItemInInventory(EntityUid blockingEnt, EntityUid user /// that's done check if the found virtual entity is a copy of our matching entity, /// if it is, delete it /// + /// The entity that we want to delete the virtual entity from + /// The entity that made the virtual entity /// Set this param if you have the name of the slot, it avoids unnecessary queries public void DeleteInSlotMatching(EntityUid user, EntityUid matching, string? slotName = null) { @@ -178,6 +213,7 @@ public void DeleteInSlotMatching(EntityUid user, EntityUid matching, string? slo /// /// The entity we will make a virtual entity copy of /// The entity that we want to insert the virtual entity + /// The virtual item, if spawned public bool TrySpawnVirtualItem(EntityUid blockingEnt, EntityUid user, [NotNullWhen(true)] out EntityUid? virtualItem) { if (_netManager.IsClient) diff --git a/Content.Shared/Preferences/Loadouts/RoleLoadout.cs b/Content.Shared/Preferences/Loadouts/RoleLoadout.cs index e1c6f8395d0..ff3db32fd6f 100644 --- a/Content.Shared/Preferences/Loadouts/RoleLoadout.cs +++ b/Content.Shared/Preferences/Loadouts/RoleLoadout.cs @@ -74,12 +74,20 @@ public void EnsureValid(ICommonSession session, IDependencyCollection collection { var loadout = loadouts[i]; + // Old prototype or otherwise invalid. if (!protoManager.TryIndex(loadout.Prototype, out var loadoutProto)) { loadouts.RemoveAt(i); continue; } + // Malicious client maybe, check the group even has it. + if (!groupProto.Loadouts.Contains(loadout.Prototype)) + { + loadouts.RemoveAt(i); + continue; + } + // Validate the loadout can be applied (e.g. points). if (!IsValid(session, loadout.Prototype, collection, out _)) { diff --git a/Content.Shared/Weapons/Ranged/Components/ActionGunComponent.cs b/Content.Shared/Weapons/Ranged/Components/ActionGunComponent.cs new file mode 100644 index 00000000000..112339efd74 --- /dev/null +++ b/Content.Shared/Weapons/Ranged/Components/ActionGunComponent.cs @@ -0,0 +1,37 @@ +using Content.Shared.Actions; +using Content.Shared.Weapons.Ranged.Systems; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Weapons.Ranged.Components; + +/// +/// Lets you shoot a gun using an action. +/// +[RegisterComponent, NetworkedComponent, Access(typeof(ActionGunSystem))] +public sealed partial class ActionGunComponent : Component +{ + /// + /// Action to create, must use . + /// + [DataField(required: true)] + public EntProtoId Action = string.Empty; + + [DataField] + public EntityUid? ActionEntity; + + /// + /// Prototype of gun entity to spawn. + /// Deleted when this component is removed. + /// + [DataField(required: true)] + public EntProtoId GunProto = string.Empty; + + [DataField] + public EntityUid? Gun; +} + +/// +/// Action event for to shoot at a position. +/// +public sealed partial class ActionGunShootEvent : WorldTargetActionEvent; diff --git a/Content.Shared/Weapons/Ranged/Components/GunRequiresWieldComponent.cs b/Content.Shared/Weapons/Ranged/Components/GunRequiresWieldComponent.cs index 2ae71334b47..fa3732209f5 100644 --- a/Content.Shared/Weapons/Ranged/Components/GunRequiresWieldComponent.cs +++ b/Content.Shared/Weapons/Ranged/Components/GunRequiresWieldComponent.cs @@ -6,8 +6,13 @@ namespace Content.Shared.Weapons.Ranged.Components; /// /// Indicates that this gun requires wielding to be useable. /// -[RegisterComponent, NetworkedComponent, Access(typeof(WieldableSystem))] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +[Access(typeof(WieldableSystem))] public sealed partial class GunRequiresWieldComponent : Component { + [DataField, AutoNetworkedField] + public TimeSpan LastPopup; + [DataField, AutoNetworkedField] + public TimeSpan PopupCooldown = TimeSpan.FromSeconds(1); } diff --git a/Content.Shared/Weapons/Ranged/Components/GunWieldBonusComponent.cs b/Content.Shared/Weapons/Ranged/Components/GunWieldBonusComponent.cs index ce96639e3c4..522319ccbd3 100644 --- a/Content.Shared/Weapons/Ranged/Components/GunWieldBonusComponent.cs +++ b/Content.Shared/Weapons/Ranged/Components/GunWieldBonusComponent.cs @@ -33,4 +33,7 @@ public sealed partial class GunWieldBonusComponent : Component /// [DataField, AutoNetworkedField] public Angle AngleIncrease = Angle.FromDegrees(0); + + [DataField] + public LocId? WieldBonusExamineMessage = "gunwieldbonus-component-examine"; } diff --git a/Content.Shared/Weapons/Ranged/Events/ShotAttemptedEvent.cs b/Content.Shared/Weapons/Ranged/Events/ShotAttemptedEvent.cs index 40925ad614c..d61862bf1a0 100644 --- a/Content.Shared/Weapons/Ranged/Events/ShotAttemptedEvent.cs +++ b/Content.Shared/Weapons/Ranged/Events/ShotAttemptedEvent.cs @@ -1,3 +1,5 @@ +using Content.Shared.Weapons.Ranged.Components; + namespace Content.Shared.Weapons.Ranged.Events; /// @@ -15,7 +17,7 @@ public record struct ShotAttemptedEvent /// /// The gun being shot. /// - public EntityUid Used; + public Entity Used; public bool Cancelled { get; private set; } diff --git a/Content.Shared/Weapons/Ranged/Systems/ActionGunSystem.cs b/Content.Shared/Weapons/Ranged/Systems/ActionGunSystem.cs new file mode 100644 index 00000000000..f3dfe8a2a03 --- /dev/null +++ b/Content.Shared/Weapons/Ranged/Systems/ActionGunSystem.cs @@ -0,0 +1,41 @@ +using Content.Shared.Actions; +using Content.Shared.Weapons.Ranged.Components; + +namespace Content.Shared.Weapons.Ranged.Systems; + +public sealed class ActionGunSystem : EntitySystem +{ + [Dependency] private readonly SharedActionsSystem _actions = default!; + [Dependency] private readonly SharedGunSystem _gun = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnMapInit); + SubscribeLocalEvent(OnShutdown); + SubscribeLocalEvent(OnShoot); + } + + private void OnMapInit(Entity ent, ref MapInitEvent args) + { + if (string.IsNullOrEmpty(ent.Comp.Action)) + return; + + _actions.AddAction(ent, ref ent.Comp.ActionEntity, ent.Comp.Action); + ent.Comp.Gun = Spawn(ent.Comp.GunProto); + } + + private void OnShutdown(Entity ent, ref ComponentShutdown args) + { + if (ent.Comp.Gun is {} gun) + QueueDel(gun); + } + + private void OnShoot(Entity ent, ref ActionGunShootEvent args) + { + if (TryComp(ent.Comp.Gun, out var gun)) + _gun.AttemptShoot(ent, ent.Comp.Gun.Value, gun, args.Target); + } +} + diff --git a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs index c592a241419..eb597467fdc 100644 --- a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs +++ b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs @@ -239,7 +239,7 @@ private void AttemptShoot(EntityUid user, EntityUid gunUid, GunComponent gun) var prevention = new ShotAttemptedEvent { User = user, - Used = gunUid + Used = (gunUid, gun) }; RaiseLocalEvent(gunUid, ref prevention); if (prevention.Cancelled) diff --git a/Content.Shared/Wieldable/WieldableSystem.cs b/Content.Shared/Wieldable/WieldableSystem.cs index ba3f787a4bb..c09044f84b4 100644 --- a/Content.Shared/Wieldable/WieldableSystem.cs +++ b/Content.Shared/Wieldable/WieldableSystem.cs @@ -1,3 +1,4 @@ +using Content.Shared.Examine; using Content.Shared.Hands; using Content.Shared.Hands.Components; using Content.Shared.Hands.EntitySystems; @@ -15,7 +16,7 @@ using Content.Shared.Weapons.Ranged.Systems; using Content.Shared.Wieldable.Components; using Robust.Shared.Audio.Systems; -using Robust.Shared.Player; +using Robust.Shared.Timing; namespace Content.Shared.Wieldable; @@ -29,6 +30,7 @@ public sealed class WieldableSystem : EntitySystem [Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly UseDelaySystem _delay = default!; [Dependency] private readonly SharedGunSystem _gun = default!; + [Dependency] private readonly IGameTiming _timing = default!; public override void Initialize() { @@ -39,12 +41,14 @@ public override void Initialize() SubscribeLocalEvent(OnItemLeaveHand); SubscribeLocalEvent(OnVirtualItemDeleted); SubscribeLocalEvent>(AddToggleWieldVerb); + SubscribeLocalEvent(OnDeselectWieldable); SubscribeLocalEvent(OnMeleeAttempt); - SubscribeLocalEvent(OnShootAttempt); + SubscribeLocalEvent(OnShootAttempt); SubscribeLocalEvent(OnGunWielded); SubscribeLocalEvent(OnGunUnwielded); SubscribeLocalEvent(OnGunRefreshModifiers); + SubscribeLocalEvent(OnExamine); SubscribeLocalEvent(OnGetMeleeDamage); } @@ -59,16 +63,21 @@ private void OnMeleeAttempt(EntityUid uid, MeleeRequiresWieldComponent component } } - private void OnShootAttempt(EntityUid uid, GunRequiresWieldComponent component, ref AttemptShootEvent args) + private void OnShootAttempt(EntityUid uid, GunRequiresWieldComponent component, ref ShotAttemptedEvent args) { if (TryComp(uid, out var wieldable) && !wieldable.Wielded) { - args.Cancelled = true; + args.Cancel(); - if (!HasComp(uid) && !HasComp(uid)) + var time = _timing.CurTime; + if (time > component.LastPopup + component.PopupCooldown && + !HasComp(uid) && + !HasComp(uid)) { - args.Message = Loc.GetString("wieldable-component-requires", ("item", uid)); + component.LastPopup = time; + var message = Loc.GetString("wieldable-component-requires", ("item", uid)); + _popupSystem.PopupClient(message, args.Used, args.User); } } } @@ -83,6 +92,14 @@ private void OnGunWielded(EntityUid uid, GunWieldBonusComponent component, ref I _gun.RefreshModifiers(uid); } + private void OnDeselectWieldable(EntityUid uid, WieldableComponent component, HandDeselectedEvent args) + { + if (!component.Wielded) + return; + + TryUnwield(uid, component, args.User); + } + private void OnGunRefreshModifiers(Entity bonus, ref GunRefreshModifiersEvent args) { if (TryComp(bonus, out WieldableComponent? wield) && @@ -95,6 +112,12 @@ private void OnGunRefreshModifiers(Entity bonus, ref Gun } } + private void OnExamine(EntityUid uid, GunWieldBonusComponent component, ref ExaminedEvent args) + { + if (component.WieldBonusExamineMessage != null) + args.PushText(Loc.GetString(component.WieldBonusExamineMessage)); + } + private void AddToggleWieldVerb(EntityUid uid, WieldableComponent component, GetVerbsEvent args) { if (args.Hands == null || !args.CanAccess || !args.CanInteract) @@ -147,7 +170,7 @@ public bool CanWield(EntityUid uid, WieldableComponent component, EntityUid user return false; } - if (hands.CountFreeHands() < component.FreeHandsRequired) + if (_handsSystem.CountFreeableHands((user, hands)) < component.FreeHandsRequired) { if (!quiet) { @@ -188,9 +211,21 @@ public bool TryWield(EntityUid used, WieldableComponent component, EntityUid use if (component.WieldSound != null) _audioSystem.PlayPredicted(component.WieldSound, used, user); + var virtuals = new List(); for (var i = 0; i < component.FreeHandsRequired; i++) { - _virtualItemSystem.TrySpawnVirtualItemInHand(used, user); + if (_virtualItemSystem.TrySpawnVirtualItemInHand(used, user, out var virtualItem, true)) + { + virtuals.Add(virtualItem.Value); + continue; + } + + foreach (var existingVirtual in virtuals) + { + QueueDel(existingVirtual); + } + + return false; } if (TryComp(used, out UseDelayComponent? useDelay) diff --git a/Resources/Audio/_NF/Jukebox/attributions.yml b/Resources/Audio/_NF/Jukebox/attributions.yml new file mode 100644 index 00000000000..92e453f3ef3 --- /dev/null +++ b/Resources/Audio/_NF/Jukebox/attributions.yml @@ -0,0 +1,4 @@ +- files: ["lateraligator.ogg"] + license: "CC-BY-3.0" + copyright: "Later Alligator By Silverman Sound Studios. Converted to mono ogg" + source: "https://soundcloud.com/silvermansound/later-alligator" diff --git a/Resources/Audio/_NF/Jukebox/lateraligator.ogg b/Resources/Audio/_NF/Jukebox/lateraligator.ogg new file mode 100644 index 00000000000..e4186cccdf9 Binary files /dev/null and b/Resources/Audio/_NF/Jukebox/lateraligator.ogg differ diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index f6548202538..8489a3c74a0 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -4710,3 +4710,44 @@ Entries: Frontier. id: 4997 time: '2024-05-31T11:11:02.0000000+00:00' +- author: dvir01 + changes: + - type: Tweak + message: Added more selections to loadouts options! make sure to pick new items! + id: 4998 + time: '2024-06-01T12:46:43.0000000+00:00' +- author: Katarn1933 + changes: + - type: Add + message: New swampy tune for jukebox + id: 4999 + time: '2024-06-01T13:03:59.0000000+00:00' +- author: erhardsteinhauer + changes: + - type: Add + message: >- + Added new messenger bags: arcadia, chaplain, chief engineer, contractor, + SR, security, black, blue, green, orange, red, purple, brown, light + brown, white. Most of new messenger bags available through loadouts. + - type: Tweak + message: >- + Resprited some messenger bags a bit (engineering, janitor, cultist, both + NFSD). + id: 5000 + time: '2024-06-01T14:44:45.0000000+00:00' +- author: erhardsteinhauer + changes: + - type: Fix + message: >- + Mail RPDS, N2554 Pattern Repeater and BB gun no longer turn invisible if + wielded or put in suit storage slot. + id: 5001 + time: '2024-06-01T15:17:54.0000000+00:00' +- author: Leander + changes: + - type: Tweak + message: >- + Silver Industries has released the argenti 2.0 with improved chamber and + shooting speed. + id: 5002 + time: '2024-06-01T16:30:25.0000000+00:00' diff --git a/Resources/Locale/en-US/_NF/preferences/loadout-groups.ftl b/Resources/Locale/en-US/_NF/preferences/loadout-groups.ftl index b2e2b077145..79a9a45c33a 100644 --- a/Resources/Locale/en-US/_NF/preferences/loadout-groups.ftl +++ b/Resources/Locale/en-US/_NF/preferences/loadout-groups.ftl @@ -14,12 +14,6 @@ loadout-group-contractor-face = mask loadout-group-contractor-utility = tools loadout-group-contractor-fun = fun loadout-group-contractor-trinkets = trinkets -# Security - -loadout-group-security-guard-jumpsuit = head -loadout-group-security-guard-jumpsuit = jumpsuit -loadout-group-security-guard-gloves = gloves -loadout-group-security-guard-head = head -loadout-group-security-guard-outerclothing = outer clothing -loadout-group-security-guard-shoes = shoes -loadout-group-security-guard-id = ID +loadout-group-contractor-survival-box = survival box +loadout-group-contractor-encryption-key = encryption keys +loadout-group-contractor-implanter = implanters \ No newline at end of file diff --git a/Resources/Locale/en-US/virtual/virtual-item.ftl b/Resources/Locale/en-US/virtual/virtual-item.ftl new file mode 100644 index 00000000000..cb91f24cf7c --- /dev/null +++ b/Resources/Locale/en-US/virtual/virtual-item.ftl @@ -0,0 +1 @@ +virtual-item-dropped-other = You dropped {THE($dropped)}! diff --git a/Resources/Locale/en-US/wieldable/wieldable-component.ftl b/Resources/Locale/en-US/wieldable/wieldable-component.ftl index 91eee8c2eaf..84b58224a77 100644 --- a/Resources/Locale/en-US/wieldable/wieldable-component.ftl +++ b/Resources/Locale/en-US/wieldable/wieldable-component.ftl @@ -1,4 +1,4 @@ -### Locale for wielding items; i.e. two-handing them +### Locale for wielding items; i.e. two-handing them wieldable-verb-text-wield = Wield wieldable-verb-text-unwield = Unwield @@ -17,3 +17,4 @@ wieldable-component-not-in-hands = { CAPITALIZE(THE($item)) } isn't in your hand wieldable-component-requires = { CAPITALIZE(THE($item))} must be wielded! +gunwieldbonus-component-examine = This weapon has improved accuracy when wielded. diff --git a/Resources/Prototypes/Access/misc.yml b/Resources/Prototypes/Access/misc.yml index dd47e1f015d..db359351e79 100644 --- a/Resources/Prototypes/Access/misc.yml +++ b/Resources/Prototypes/Access/misc.yml @@ -20,7 +20,6 @@ - Mail # Frontier - Medical - Mercenary # Frontier - - Pilot # Frontier - Quartermaster - Salvage - Cargo diff --git a/Resources/Prototypes/Catalog/Jukebox/Standard.yml b/Resources/Prototypes/Catalog/Jukebox/Standard.yml index 7440428bd49..1cc80ff6e2f 100644 --- a/Resources/Prototypes/Catalog/Jukebox/Standard.yml +++ b/Resources/Prototypes/Catalog/Jukebox/Standard.yml @@ -38,4 +38,4 @@ id: sunset name: PigeonBeans - Sunset path: - path: /Audio/Jukebox/sunset.ogg + path: /Audio/Jukebox/sunset.ogg \ No newline at end of file diff --git a/Resources/Prototypes/Catalog/VendingMachines/Inventories/ammo.yml b/Resources/Prototypes/Catalog/VendingMachines/Inventories/ammo.yml index 447e2037996..26f71911eb7 100644 --- a/Resources/Prototypes/Catalog/VendingMachines/Inventories/ammo.yml +++ b/Resources/Prototypes/Catalog/VendingMachines/Inventories/ammo.yml @@ -7,16 +7,17 @@ WeaponSniperRepeater: 10 MagazineBoxLightRifle: 10 MagazineBoxLightRiflePractice: 10 -# MagazineBoxLightRifleRubber: 15 # Frontier - TODO: Restore Rubber + MagazineBoxLightRifleRubber: 15 WeaponShotgunDoubleBarreled: 10 + WeaponRevolverArgenti: 10 BoxShotgunSlug: 10 BoxLethalshot: 10 BoxBeanbag: 10 BoxShotgunPractice: 10 - WeaponRevolverArgenti: 10 MagazineBoxRifle: 10 -# MagazineBoxRifleRubber: 15 # Frontier - TODO: Restore Rubber - MagazineBoxRiflePractice: 10 + MagazineBoxRifleRubber: 15 MagazineBoxMagnum: 10 + SpeedLoaderRifleHeavy: 10 + SpeedLoaderRifleHeavyRubber: 10 emaggedInventory: WeaponPistolViper: 1 diff --git a/Resources/Prototypes/DeltaV/Entities/Objects/Fun/toy_guns.yml b/Resources/Prototypes/DeltaV/Entities/Objects/Fun/toy_guns.yml index 9acf9740191..cbe7fea8475 100644 --- a/Resources/Prototypes/DeltaV/Entities/Objects/Fun/toy_guns.yml +++ b/Resources/Prototypes/DeltaV/Entities/Objects/Fun/toy_guns.yml @@ -1,6 +1,6 @@ - type: entity name: BB Gun - parent: BaseItem + parent: [BaseItem, BaseGunWieldable] # Frontier id: WeaponRifleBB description: The classic Red Ryder BB gun. Don't shoot your eye out. components: @@ -39,4 +39,4 @@ ents: [] - type: Appearance - type: StaticPrice - price: 2750 + price: 500 diff --git a/Resources/Prototypes/Entities/Mobs/Player/dragon.yml b/Resources/Prototypes/Entities/Mobs/Player/dragon.yml index c58577722c2..76260bb9e83 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/dragon.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/dragon.yml @@ -89,6 +89,12 @@ speedModifierThresholds: 250: 0.7 400: 0.5 + # disable taking damage from fire, since its a fire breathing dragon + - type: Flammable + damage: + types: {} + - type: Temperature + heatDamageThreshold: 800 - type: Metabolizer solutionOnBody: false updateInterval: 0.25 @@ -134,15 +140,37 @@ - type: entity parent: BaseMobDragon id: MobDragon + suffix: No role or objectives components: - type: Dragon spawnRiftAction: ActionSpawnRift - # - type: GenericAntag - # rule: Dragon + - type: ActionGun + action: ActionDragonsBreath + gunProto: DragonsBreathGun - type: GuideHelp guides: - MinorAntagonists +- type: entity + noSpawn: true + id: DragonsBreathGun + name: dragon's lung + description: For dragon's breathing + components: + - type: RechargeBasicEntityAmmo + rechargeCooldown: 5 + rechargeSound: + path: /Audio/Animals/space_dragon_roar.ogg + - type: BasicEntityAmmoProvider + proto: ProjectileDragonsBreath + capacity: 1 + count: 1 + - type: Gun + soundGunshot: + path: /Audio/Animals/space_dragon_roar.ogg + soundEmpty: null + projectileSpeed: 5 + - type: entity parent: BaseMobDragon id: MobDragonDungeon @@ -181,6 +209,7 @@ state: icon event: !type:DragonSpawnRiftActionEvent useDelay: 1 + priority: 3 - type: entity id: ActionDevour @@ -192,3 +221,18 @@ icon: { sprite : Interface/Actions/devour.rsi, state: icon } iconOn: { sprite : Interface/Actions/devour.rsi, state: icon-on } event: !type:DevourActionEvent + priority: 1 + +- type: entity + noSpawn: true + id: ActionDragonsBreath + name: "[color=orange]Dragon's Breath[/color]" + description: Spew out flames at anyone foolish enough to attack you! + components: + - type: WorldTargetAction + # TODO: actual sprite + icon: { sprite : Objects/Weapons/Guns/Projectiles/magic.rsi, state: fireball } + event: !type:ActionGunShootEvent + priority: 2 + checkCanAccess: false + range: 0 diff --git a/Resources/Prototypes/Entities/Objects/Tools/access_configurator.yml b/Resources/Prototypes/Entities/Objects/Tools/access_configurator.yml index 65c958c16af..0c06c4d6e3d 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/access_configurator.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/access_configurator.yml @@ -44,7 +44,6 @@ - Maintenance - Medical - Mercenary # Frontier - - Pilot # Frontier - Quartermaster - Research - ResearchDirector diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/light_rifle.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/light_rifle.yml index d5fb4360a82..3241a892262 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/light_rifle.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Boxes/light_rifle.yml @@ -102,4 +102,4 @@ map: ["enum.GunVisualLayers.Base"] - state: mag-1 map: ["enum.GunVisualLayers.Mag"] - - state: uranium + - state: uranium \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/caseless_rifle.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/caseless_rifle.yml index a35a42d8c2a..73f29189864 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/caseless_rifle.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/caseless_rifle.yml @@ -43,3 +43,4 @@ - state: tip map: [ "enum.AmmoVisualLayers.Tip" ] color: "#dbdbdb" + diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/caseless_rifle.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/caseless_rifle.yml index 741f0a4e1a0..5ce0bf82fe9 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/caseless_rifle.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/caseless_rifle.yml @@ -19,3 +19,14 @@ damage: types: Blunt: 2 + +- type: entity + id: BulletCaselessRifleRubber + name: bullet (.25 caseless rubber) + parent: BaseBulletRubber + noSpawn: true + components: + - type: Projectile + damage: + types: + Blunt: 3 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/light_rifle.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/light_rifle.yml index c6a4808b77b..3a0df2ac6c7 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/light_rifle.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/light_rifle.yml @@ -20,6 +20,17 @@ types: Blunt: 2 +- type: entity + id: BulletLightRifleRubber + name: bullet (.20 rifle rubber) + parent: BaseBulletRubber + noSpawn: true + components: + - type: Projectile + damage: + types: + Blunt: 3 + - type: entity id: BulletLightRifleIncendiary parent: BaseBulletIncendiary diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/magnum.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/magnum.yml index 798de9fa853..1b5cf7890ba 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/magnum.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/magnum.yml @@ -20,6 +20,19 @@ types: Blunt: 1 +- type: entity + id: BulletMagnumRubber + name: bullet (.45 magnum rubber) + parent: BaseBulletRubber + noSpawn: true + components: + - type: Projectile + damage: + types: + Blunt: 3 + - type: StaminaDamageOnCollide + damage: 35 # 3 hits to stun cuz revolver + - type: entity id: BulletMagnumIncendiary parent: BaseBulletIncendiary @@ -31,7 +44,7 @@ types: Blunt: 3 Heat: 32 - + - type: entity id: BulletMagnumAP name: bullet (.45 magnum armor-piercing) diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/pistol.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/pistol.yml index 3cfcc0cf206..086a8dc914f 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/pistol.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/pistol.yml @@ -20,6 +20,17 @@ types: Blunt: 2 +- type: entity + id: BulletPistolRubber + name: bullet (.35 auto rubber) + parent: BaseBulletRubber + noSpawn: true + components: + - type: Projectile + damage: + types: + Blunt: 3 + - type: entity id: BulletPistolIncendiary parent: BaseBulletIncendiary diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/rifle.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/rifle.yml index 6f6fa0f9077..2113916cf52 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/rifle.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/rifle.yml @@ -20,6 +20,17 @@ types: Blunt: 2 +- type: entity + id: BulletRifleRubber + name: bullet (0.20 rifle rubber) + parent: BaseBulletRubber + noSpawn: true + components: + - type: Projectile + damage: + types: + Blunt: 3 + - type: entity id: BulletRifleIncendiary parent: BaseBulletIncendiary @@ -31,7 +42,7 @@ types: Blunt: 2 Heat: 15 - + - type: entity id: BulletRifleUranium parent: BaseBulletUranium @@ -43,4 +54,4 @@ types: Radiation: 7 Piercing: 8 - + diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/base_wieldable.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/base_wieldable.yml new file mode 100644 index 00000000000..cf858e17374 --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Basic/base_wieldable.yml @@ -0,0 +1,12 @@ +# A basic inheritable template for a gun that is wieldable and has the standard inaccuracy. +- type: entity + id: BaseGunWieldable + abstract: true + components: + - type: Wieldable + - type: GunWieldBonus + minAngle: -20 + maxAngle: -30 + - type: Gun + minAngle: 21 + maxAngle: 32 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml index 576545f8e86..642447b49e5 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml @@ -204,7 +204,7 @@ - type: entity name: laser rifle - parent: BaseWeaponBattery + parent: [BaseWeaponBattery, BaseGunWieldable] id: WeaponLaserCarbine description: A simple civilian grade laser carbine, the workhorse of many private security organizations. components: @@ -271,7 +271,7 @@ - type: entity name: pulse carbine - parent: BaseWeaponBattery + parent: [BaseWeaponBattery, BaseGunWieldable] id: WeaponPulseCarbine description: A high tech energy carbine favoured by the NT-ERT operatives. On the handle is a label that says 'for authorized use only.' components: @@ -302,7 +302,7 @@ - type: entity name: pulse rifle - parent: BaseWeaponBattery + parent: [BaseWeaponBattery, BaseGunWieldable] id: WeaponPulseRifle description: A weapon that is almost as infamous as its users. On the handle is a label that says 'for authorized use only.' components: @@ -329,7 +329,7 @@ - type: entity name: laser cannon - parent: BaseWeaponBattery + parent: [BaseWeaponBattery, BaseGunWieldable] id: WeaponLaserCannon description: A heavy duty, high powered laser weapon. On the handle is a label that says 'for authorized use only.' components: @@ -388,7 +388,7 @@ - type: entity name: x-ray cannon - parent: BaseWeaponBattery + parent: [BaseWeaponBattery, BaseGunWieldable] id: WeaponXrayCannon description: An illegal and experimental weapon that uses concentrated x-ray energy against its target. components: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml index 9f94ed2c52b..82a36357455 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml @@ -22,7 +22,7 @@ - type: entity name: china lake - parent: BaseWeaponLauncher + parent: [BaseWeaponLauncher, BaseGunWieldable] id: WeaponLauncherChinaLake description: PLOOP components: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/magic.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/magic.yml index 3556d1c8f8b..d6adcd614e3 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/magic.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/magic.yml @@ -30,6 +30,39 @@ - type: IgniteOnCollide fireStacks: 0.35 +- type: entity + noSpawn: true + parent: BaseBulletTrigger + id: ProjectileDragonsBreath + name: dragon's breath + description: Try not to get toasted. + components: + - type: PointLight + color: "#E25822" + radius: 3.0 + energy: 5.0 + - type: Sprite + sprite: Objects/Weapons/Guns/Projectiles/magic.rsi + layers: + - state: fireball + shader: unshaded + - type: IgnitionSource + temperature: 1000 + ignited: true + - type: RepeatingTrigger + delay: 0.5 # line of fire as well as if it hits something + - type: ExplodeOnTrigger + - type: Explosive + explosionType: FireBomb + totalIntensity: 5 # low intensity, the point is to burn attackers not to break open walls, dragons can just eat them + intensitySlope: 1 + maxIntensity: 3 + canCreateVacuum: false + deleteAfterExplosion: false + repeatable: true + - type: TimedDespawn + lifetime: 5 + - type: entity id: ProjectileAnomalyFireball name: fireball diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml index 60121fde792..7f9ce36f2bd 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml @@ -104,6 +104,25 @@ types: Blunt: 1 +- type: entity + id: BaseBulletRubber + name: base bullet rubber + parent: BaseBullet + noSpawn: true + components: + - type: Sprite + sprite: Objects/Weapons/Guns/Projectiles/projectiles2.rsi + layers: + - state: rubber + - type: Projectile + damage: + types: + Blunt: 3 + soundHit: + path: /Audio/Weapons/Guns/Hits/snap.ogg + - type: StaminaDamageOnCollide + damage: 22 # 5 hits to stun sounds reasonable + - type: entity id: BaseBulletIncendiary name: base bullet incendiary diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Rifles/rifles.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Rifles/rifles.yml index ef83e6c5722..50d8ca7c597 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Rifles/rifles.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Rifles/rifles.yml @@ -1,6 +1,6 @@ - type: entity name: BaseWeaponRifle - parent: BaseItem + parent: [BaseItem, BaseGunWieldable] id: BaseWeaponRifle description: A rooty tooty point and shooty. abstract: true @@ -186,3 +186,4 @@ steps: 1 zeroVisible: true - type: Appearance + diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml index 45be47f79c0..852aaa7c8b8 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml @@ -20,7 +20,7 @@ maxAngle: 16 fireRate: 8 angleIncrease: 3 - angleDecay: 16 + angleDecay: 16 selectedMode: FullAuto availableModes: - SemiAuto @@ -80,7 +80,7 @@ - type: entity name: C-20r sub machine gun - parent: BaseWeaponSubMachineGun + parent: [BaseWeaponSubMachineGun, BaseGunWieldable] id: WeaponSubMachineGunC20r description: An illegal firearm that is often used by the infamous nuclear operatives. Uses .35 auto ammo. components: @@ -94,6 +94,8 @@ - type: Clothing sprite: Objects/Weapons/Guns/SMGs/c20r.rsi - type: Gun + minAngle: 21 + maxAngle: 32 shotsPerBurst: 5 availableModes: - SemiAuto @@ -112,7 +114,7 @@ - type: entity name: Drozd - parent: BaseWeaponSubMachineGun + parent: [BaseWeaponSubMachineGun, BaseGunWieldable] id: WeaponSubMachineGunDrozd description: An excellent fully automatic Heavy SMG. An illegal firearm often used by Syndicate agents. components: @@ -126,6 +128,8 @@ - type: Clothing sprite: Objects/Weapons/Guns/SMGs/drozd.rsi - type: Gun + minAngle: 21 + maxAngle: 32 fireRate: 6 selectedMode: FullAuto soundGunshot: @@ -231,7 +235,7 @@ minAngle: 1 maxAngle: 6 angleIncrease: 1.5 - angleDecay: 6 + angleDecay: 6 selectedMode: FullAuto shotsPerBurst: 5 availableModes: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Shotguns/shotguns.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Shotguns/shotguns.yml index bce85aac322..a8ab8a8e41c 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Shotguns/shotguns.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Shotguns/shotguns.yml @@ -46,7 +46,7 @@ - type: entity name: Bulldog # Don't parent to BaseWeaponShotgun because it differs significantly - parent: BaseItem + parent: [BaseItem, BaseGunWieldable] id: WeaponShotgunBulldog description: It's a magazine-fed shotgun designed for close quarters combat. Uses .50 shotgun shells. An illegal firearm often used by Syndicate agents. components: @@ -66,6 +66,7 @@ - Back - suitStorage - type: AmmoCounter + - type: GunRequiresWield #remove when inaccuracy on spreads is fixed - type: Gun fireRate: 2 selectedMode: FullAuto @@ -102,7 +103,7 @@ - type: entity name: double-barreled shotgun - parent: BaseWeaponShotgun + parent: [BaseWeaponShotgun, BaseGunWieldable] id: WeaponShotgunDoubleBarreled description: An immortal classic. A civilian grade shotgun. Uses .50 shotgun shells. components: @@ -112,8 +113,8 @@ size: Normal shape: - 0,0,4,0 - sprite: Objects/Weapons/Guns/Shotguns/inhands_64x.rsi - heldPrefix: db + sprite: Objects/Weapons/Guns/Shotguns/db_shotgun_inhands_64x.rsi + - type: GunRequiresWield #remove when inaccuracy on spreads is fixed - type: Gun fireRate: 2 - type: BallisticAmmoProvider @@ -137,7 +138,7 @@ - type: entity name: Enforcer - parent: BaseWeaponShotgun + parent: [BaseWeaponShotgun, BaseGunWieldable] id: WeaponShotgunEnforcer description: A premium combat shotgun based on the Kammerer design, featuring an upgraded clip capacity. .50 shotgun shells. On the receiver is a label that says 'for authorized use only.' components: @@ -146,9 +147,9 @@ - type: Clothing sprite: Objects/Weapons/Guns/Shotguns/enforcer.rsi - type: Item - sprite: Objects/Weapons/Guns/Shotguns/inhands_64x.rsi - heldPrefix: enforcer + sprite: Objects/Weapons/Guns/Shotguns/enforcer_inhands_64x.rsi - type: BallisticAmmoProvider + - type: GunRequiresWield #remove when inaccuracy on spreads is fixed - type: entity parent: WeaponShotgunEnforcer @@ -160,7 +161,7 @@ - type: entity name: Kammerer - parent: BaseWeaponShotgun + parent: [BaseWeaponShotgun, BaseGunWieldable] id: WeaponShotgunKammerer description: When an old Remington design meets modern materials, this is the result. A civilian grade shotgun, favored by militia forces throughout many worlds. Uses .50 shotgun shells. components: @@ -168,12 +169,12 @@ size: Normal shape: - 0,0,4,0 - sprite: Objects/Weapons/Guns/Shotguns/inhands_64x.rsi - heldPrefix: pump + sprite: Objects/Weapons/Guns/Shotguns/pump_inhands_64x.rsi - type: Sprite sprite: Objects/Weapons/Guns/Shotguns/pump.rsi - type: Clothing sprite: Objects/Weapons/Guns/Shotguns/pump.rsi + - type: GunRequiresWield #remove when inaccuracy on spreads is fixed - type: BallisticAmmoProvider capacity: 4 - type: Tag @@ -192,8 +193,7 @@ sprite: Objects/Weapons/Guns/Shotguns/sawn.rsi - type: Item size: Small - sprite: Objects/Weapons/Guns/Shotguns/inhands_64x.rsi - heldPrefix: sawn + sprite: Objects/Weapons/Guns/Shotguns/sawn_inhands_64x.rsi - type: Gun fireRate: 4 - type: BallisticAmmoProvider @@ -241,7 +241,7 @@ - type: entity name: blunderbuss - parent: BaseWeaponShotgun + parent: [BaseWeaponShotgun, BaseGunWieldable] id: WeaponShotgunBlunderbuss suffix: Pirate description: Deadly at close range, an illegal shotgun often found at the side of a pirate. @@ -252,6 +252,7 @@ - 0,0,4,0 - type: Sprite sprite: Objects/Weapons/Guns/Shotguns/blunderbuss.rsi + - type: GunRequiresWield #remove when inaccuracy on spreads is fixed - type: Gun fireRate: 2 - type: BallisticAmmoProvider @@ -261,7 +262,7 @@ - type: entity name: improvised shotgun - parent: BaseWeaponShotgun + parent: [BaseWeaponShotgun, BaseGunWieldable] id: WeaponShotgunImprovised description: A shitty, but legal, hand-made shotgun that uses .50 shotgun shells. It can only hold one round in the chamber. components: @@ -273,8 +274,8 @@ size: Normal shape: - 0,0,4,0 - sprite: Objects/Weapons/Guns/Shotguns/inhands_64x.rsi - heldPrefix: improvised + sprite: Objects/Weapons/Guns/Shotguns/improvised_shotgun_inhands_64x.rsi + - type: GunRequiresWield #remove when inaccuracy on spreads is fixed - type: Gun fireRate: 4 #No reason to stifle the firerate since you have to manually reload every time anyways. - type: BallisticAmmoProvider diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Snipers/snipers.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Snipers/snipers.yml index a45924fd4c5..9c9a8c77e57 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Snipers/snipers.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Snipers/snipers.yml @@ -40,7 +40,7 @@ - type: entity name: Kardashev-Mosin - parent: BaseWeaponSniper + parent: [BaseWeaponSniper, BaseGunWieldable] id: WeaponSniperMosin description: A civilian grade weapon for hunting, or endless trench warfare. Uses .30 rifle ammo. components: @@ -51,7 +51,7 @@ - type: entity name: Hristov - parent: BaseWeaponSniper + parent: [BaseWeaponSniper, BaseGunWieldable] id: WeaponSniperHristov description: A portable anti-materiel rifle. Fires armor piercing 14.5mm shells. Uses .60 anti-materiel ammo. On the receiver is a label that says 'for authorized use only.' components: diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index cd0ba89b3b5..ad0fa9702d1 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -191,6 +191,8 @@ - ShellTranquilizer - SpeedLoaderMagnum - SpeedLoaderMagnumEmpty + - SpeedLoaderRifleHeavy # Frontier + - SpeedLoaderRifleHeavyEmpty # Frontier emagDynamicRecipes: - BoxBeanbag - BoxShotgunIncendiary @@ -221,6 +223,8 @@ - PowerCageSmall - SpeedLoaderMagnumIncendiary - SpeedLoaderMagnumUranium + - SpeedLoaderRifleHeavyIncendiary # Frontier + - SpeedLoaderRifleHeavyUranium # Frontier - type: entity id: AutolatheHyperConvection @@ -764,6 +768,8 @@ - RiotShield - SpeedLoaderMagnum - SpeedLoaderMagnumEmpty + - SpeedLoaderRifleHeavy # Frontier + - SpeedLoaderRifleHeavyEmpty # Frontier - Stunbaton - TargetClown - TargetHuman @@ -822,6 +828,8 @@ - SignalTrigger - SpeedLoaderMagnumIncendiary - SpeedLoaderMagnumUranium + - SpeedLoaderRifleHeavyIncendiary # Frontier + - SpeedLoaderRifleHeavyUranium # Frontier - TelescopicShield - TimerTrigger - Truncheon @@ -883,6 +891,8 @@ - ShellTranquilizer - SpeedLoaderMagnum - SpeedLoaderMagnumEmpty + - SpeedLoaderRifleHeavy # Frontier + - SpeedLoaderRifleHeavyEmpty # Frontier - type: MaterialStorage whitelist: tags: diff --git a/Resources/Prototypes/Loadouts/role_loadouts.yml b/Resources/Prototypes/Loadouts/role_loadouts.yml index 316082562ba..7d9aedee1fd 100644 --- a/Resources/Prototypes/Loadouts/role_loadouts.yml +++ b/Resources/Prototypes/Loadouts/role_loadouts.yml @@ -75,8 +75,12 @@ groups: - LawyerNeck - LawyerJumpsuit - - LawyerBackpack + - ContractorBackpack - ContractorGlasses + - ContractorFace + - ContractorBoxSurvival + - ContractorEncryptionKey + - ContractorImplanter - ContractorFun - ContractorTrinkets @@ -87,9 +91,12 @@ - ChaplainMask - ChaplainNeck - ChaplainJumpsuit - - ChaplainBackpack + - ContractorBackpack - ChaplainOuterClothing - ContractorGlasses + - ContractorBoxSurvival + - ContractorEncryptionKey + - ContractorImplanter - ContractorFun - ContractorTrinkets @@ -99,9 +106,13 @@ - JanitorHead - JanitorJumpsuit - JanitorGloves - - CommonBackpack + - ContractorBackpack - JanitorOuterClothing + - ContractorFace - ContractorGlasses + - ContractorBoxSurvival + - ContractorEncryptionKey + - ContractorImplanter - ContractorFun - ContractorTrinkets diff --git a/Resources/Prototypes/Nyanotrasen/Roles/Jobs/Wildcards/prisoner.yml b/Resources/Prototypes/Nyanotrasen/Roles/Jobs/Wildcards/prisoner.yml index 34a0a75ee5d..b0d447b4d0c 100644 --- a/Resources/Prototypes/Nyanotrasen/Roles/Jobs/Wildcards/prisoner.yml +++ b/Resources/Prototypes/Nyanotrasen/Roles/Jobs/Wildcards/prisoner.yml @@ -18,7 +18,5 @@ - type: startingGear id: PrisonerGear equipment: - jumpsuit: ClothingUniformJumpsuitPrisoner shoes: ClothingShoesColorBlack - id: PrisonerPDA ears: ClothingHeadsetGrey diff --git a/Resources/Prototypes/Research/arsenal.yml b/Resources/Prototypes/Research/arsenal.yml index c8cee57de2b..5aed3aa6aaa 100644 --- a/Resources/Prototypes/Research/arsenal.yml +++ b/Resources/Prototypes/Research/arsenal.yml @@ -33,6 +33,7 @@ - MagazinePistolIncendiary - MagazineLightRifleIncendiary - SpeedLoaderMagnumIncendiary + - SpeedLoaderRifleHeavyIncendiary # Frontier - MagazineShotgunIncendiary - MagazineBoxPistolIncendiary - MagazineBoxMagnumIncendiary @@ -80,6 +81,7 @@ - MagazinePistolUranium - MagazineLightRifleUranium - SpeedLoaderMagnumUranium + - SpeedLoaderRifleHeavyUranium # Frontier - MagazineBoxPistolUranium - MagazineBoxMagnumUranium - MagazineBoxLightRifleUranium diff --git a/Resources/Prototypes/Roles/Jobs/Civilian/chaplain.yml b/Resources/Prototypes/Roles/Jobs/Civilian/chaplain.yml index 677449cfac8..5395e9ed861 100644 --- a/Resources/Prototypes/Roles/Jobs/Civilian/chaplain.yml +++ b/Resources/Prototypes/Roles/Jobs/Civilian/chaplain.yml @@ -22,3 +22,5 @@ shoes: ClothingShoesColorBlack id: ChaplainPDA ears: ClothingHeadsetService + pocket1: Bible # Frontier + pocket2: RubberStampChaplain # Frontier diff --git a/Resources/Prototypes/Roles/Jobs/Civilian/lawyer.yml b/Resources/Prototypes/Roles/Jobs/Civilian/lawyer.yml index 347f4185df1..b2bf348ebde 100644 --- a/Resources/Prototypes/Roles/Jobs/Civilian/lawyer.yml +++ b/Resources/Prototypes/Roles/Jobs/Civilian/lawyer.yml @@ -16,10 +16,10 @@ - type: startingGear id: LawyerGear equipment: - jumpsuit: ClothingUniformJumpsuitLawyerBlack # TODO change jumpsuit to randomiser of the 4 variants - back: ClothingBackpackLawyerFilled # Frontier shoes: ClothingShoesBootsLaceup id: LawyerPDA - ears: ClothingHeadsetSecurity + ears: ClothingHeadsetNfsdGreen # Frontier ClothingHeadsetSecurity