diff --git a/Content.Client/_White/WeaponsModules/WeaponModulesVisuals.cs b/Content.Client/_White/WeaponsModules/WeaponModulesVisuals.cs new file mode 100644 index 0000000000..40f840be23 --- /dev/null +++ b/Content.Client/_White/WeaponsModules/WeaponModulesVisuals.cs @@ -0,0 +1,37 @@ +using Content.Client.Weapons.Ranged.Components; +using Content.Shared._White.WeaponModules; +using Content.Shared.Rounding; +using Content.Shared.Weapons.Ranged.Systems; +using Robust.Client.GameObjects; + +namespace Content.Client._White.WeaponsModules; + +public sealed partial class WeaponModulesVisuals : VisualizerSystem +{ + [Dependency] private readonly PointLightSystem _lightSystem = default!; + protected override void OnAppearanceChange(EntityUid uid, WeaponModulesComponent component, ref AppearanceChangeEvent args) + { + base.OnAppearanceChange(uid, component, ref args); + + if(args.Sprite == null) + return; + + args.Sprite.LayerSetVisible(ModuleVisualState.Module, false); + + if (AppearanceSystem.TryGetData(uid, ModuleVisualState.Module, out var module, args.Component) && module.Length != 0 && module != "none") + { + args.Sprite.LayerSetState(ModuleVisualState.Module, module); + args.Sprite.LayerSetVisible(ModuleVisualState.Module, true); + } + + if (AppearanceSystem.TryGetData(uid, Modules.Light, out var data, args.Component)) + { + if (TryComp(uid, out var pointLightComponent)) + { + if(!pointLightComponent.Enabled) + return; + _lightSystem.SetMask("/Textures/White/Effects/LightMasks/lightModule.png", pointLightComponent!); + } + } + } +} diff --git a/Content.Server/_White/WeaponModules/WeaponModulesSystem.cs b/Content.Server/_White/WeaponModules/WeaponModulesSystem.cs new file mode 100644 index 0000000000..1251efa1d0 --- /dev/null +++ b/Content.Server/_White/WeaponModules/WeaponModulesSystem.cs @@ -0,0 +1,206 @@ +using System.Diagnostics.CodeAnalysis; +using Content.Shared._White.WeaponModules; +using Content.Shared.Weapons.Ranged.Components; +using Content.Shared.Weapons.Ranged.Events; +using Content.Shared.Weapons.Ranged.Systems; +using Linguini.Syntax.Ast; +using Robust.Server.GameObjects; +using Robust.Shared.Containers; + +namespace Content.Server._White.WeaponModules; + +public sealed class WeaponModulesSystem : EntitySystem +{ + protected const string ModulesSlot = "gun_modules"; + [Dependency] private readonly PointLightSystem _lightSystem = default!; + [Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!; + [Dependency] private readonly SharedGunSystem _gunSystem = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(LightModuleOnInsert); + SubscribeLocalEvent(LightModuleOnEject); + + SubscribeLocalEvent(LaserModuleOnInsert); + SubscribeLocalEvent(LaserModuleOnEject); + + SubscribeLocalEvent(FlameHiderModuleOnInsert); + SubscribeLocalEvent(FlameHiderModuleOnEject); + + SubscribeLocalEvent(SilencerModuleOnInsert); + SubscribeLocalEvent(SilencerModuleOnEject); + + SubscribeLocalEvent(AcceleratorModuleOnInsert); + SubscribeLocalEvent(AcceleratorModuleOnEject); + } + + private bool TryInsertModule(EntityUid module, EntityUid weapon, BaseModuleComponent component, + string containerId, [NotNullWhen(true)] out WeaponModulesComponent? weaponModulesComponent) + { + if (!TryComp(weapon, out weaponModulesComponent) || !TryComp(weapon, out var appearanceComponent) || + containerId != ModulesSlot) + { + weaponModulesComponent = null; + appearanceComponent = null; + return false; + } + + if(!weaponModulesComponent.Modules.Contains(module)) + weaponModulesComponent.Modules.Add(module); + _appearanceSystem.SetData(weapon, ModuleVisualState.Module, component.AppearanceValue, appearanceComponent); + + return true; + } + + private bool TryEjectModule(EntityUid module, EntityUid weapon, string containerId, [NotNullWhen(true)] out WeaponModulesComponent? weaponModulesComponent) + { + if (!TryComp(weapon, out weaponModulesComponent) || !TryComp(weapon, out var appearanceComponent) || containerId != ModulesSlot) + { + weaponModulesComponent = null; + appearanceComponent = null; + return false; + } + + if(weaponModulesComponent.Modules.Contains(module)) + weaponModulesComponent.Modules.Remove(module); + _appearanceSystem.SetData(weapon, ModuleVisualState.Module, "none", appearanceComponent); + + return true; + } + + #region InsertModules + private void LightModuleOnInsert(EntityUid module, LightModuleComponent component, EntGotInsertedIntoContainerMessage args) + { + EntityUid weapon = args.Container.Owner; + + if(!TryInsertModule(module, weapon, component, args.Container.ID, out var weaponModulesComponent)) + return; + + TryComp(weapon, out var appearanceComponent); + + SharedPointLightComponent light = _lightSystem.EnsureLight(weapon); + + _appearanceSystem.SetData(weapon, Modules.Light, "none", appearanceComponent); + + _lightSystem.SetRadius(weapon, component.Radius, light); + _lightSystem.SetEnabled(weapon, true, light); + } + + private void LaserModuleOnInsert(EntityUid module, LaserModuleComponent component, EntGotInsertedIntoContainerMessage args) + { + EntityUid weapon = args.Container.Owner; + + if (!TryComp(weapon, out var gunComp)) return; + + if(!TryInsertModule(module, weapon, component, args.Container.ID, out var weaponModulesComponent)) + return; + + component.OldProjectileSpeed = gunComp.ProjectileSpeed; + + _gunSystem.SetProjectileSpeed(weapon, component.OldProjectileSpeed + component.ProjectileSpeedAdd); + } + + private void FlameHiderModuleOnInsert(EntityUid module, FlameHiderModuleComponent component, EntGotInsertedIntoContainerMessage args) + { + EntityUid weapon = args.Container.Owner; + + if(!TryInsertModule(module, weapon, component, args.Container.ID, out var weaponModulesComponent)) + return; + + weaponModulesComponent.WeaponFireEffect = true; + Dirty(module, weaponModulesComponent); + } + + private void SilencerModuleOnInsert(EntityUid module, SilencerModuleComponent component, EntGotInsertedIntoContainerMessage args) + { + EntityUid weapon = args.Container.Owner; + + if (!TryComp(weapon, out var gunComp)) return; + + if(!TryInsertModule(module, weapon, component, args.Container.ID, out var weaponModulesComponent)) + return; + + component.OldSoundGunshot = gunComp.SoundGunshot; + + weaponModulesComponent.WeaponFireEffect = true; + _gunSystem.SetSound(weapon, component.NewSoundGunshot); + + Dirty(module, weaponModulesComponent); + } + + private void AcceleratorModuleOnInsert(EntityUid module, AcceleratorModuleComponent component, EntGotInsertedIntoContainerMessage args) + { + EntityUid weapon = args.Container.Owner; + + if (!TryComp(weapon, out var gunComp)) return; + + if(!TryInsertModule(module, weapon, component, args.Container.ID, out var weaponModulesComponent)) + return; + + component.OldFireRate = gunComp.FireRate; + + _gunSystem.SetFireRate(weapon, component.OldFireRate + component.FireRateAdd); + } + #endregion + + #region EjectModules + private void LightModuleOnEject(EntityUid module, LightModuleComponent component, EntGotRemovedFromContainerMessage args) + { + EntityUid weapon = args.Container.Owner; + + if(!TryEjectModule(module, weapon, args.Container.ID, out var weaponModulesComponent)) + return; + + if(!_lightSystem.TryGetLight(weapon, out var light)) + return; + + _lightSystem.SetRadius(weapon, 0F, light); + _lightSystem.SetEnabled(weapon, false, light); + } + + private void LaserModuleOnEject(EntityUid module, LaserModuleComponent component, EntGotRemovedFromContainerMessage args) + { + EntityUid weapon = args.Container.Owner; + + if(!TryEjectModule(module, weapon, args.Container.ID, out var weaponModulesComponent)) + return; + + _gunSystem.SetProjectileSpeed(weapon, component.OldProjectileSpeed); + } + + private void FlameHiderModuleOnEject(EntityUid module, FlameHiderModuleComponent component, EntGotRemovedFromContainerMessage args) + { + EntityUid weapon = args.Container.Owner; + + if(!TryEjectModule(module, weapon, args.Container.ID, out var weaponModulesComponent)) + return; + + weaponModulesComponent.WeaponFireEffect = false; + Dirty(module, weaponModulesComponent); + } + + private void SilencerModuleOnEject(EntityUid module, SilencerModuleComponent component, EntGotRemovedFromContainerMessage args) + { + EntityUid weapon = args.Container.Owner; + + if(!TryEjectModule(module, weapon, args.Container.ID, out var weaponModulesComponent)) + return; + + weaponModulesComponent.WeaponFireEffect = false; + _gunSystem.SetSound(weapon, component.OldSoundGunshot!); + Dirty(module, weaponModulesComponent); + } + + private void AcceleratorModuleOnEject(EntityUid module, AcceleratorModuleComponent component, EntGotRemovedFromContainerMessage args) + { + EntityUid weapon = args.Container.Owner; + + if(!TryEjectModule(module, weapon, args.Container.ID, out var weaponModulesComponent)) + return; + + _gunSystem.SetFireRate(weapon, component.OldFireRate); + } + #endregion +} diff --git a/Content.Shared/Weapons/Ranged/Components/GunComponent.cs b/Content.Shared/Weapons/Ranged/Components/GunComponent.cs index 919d7f4d06..569b10d75e 100644 --- a/Content.Shared/Weapons/Ranged/Components/GunComponent.cs +++ b/Content.Shared/Weapons/Ranged/Components/GunComponent.cs @@ -231,7 +231,7 @@ public sealed partial class GunComponent : Component // WD START public EntityUid? Target; - + [DataField("forceThrowingAngle")] [ViewVariables(VVAccess.ReadWrite)] public bool ForceThrowingAngle; diff --git a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Interactions.cs b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Interactions.cs index 2e85803d7d..da185c01f0 100644 --- a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Interactions.cs +++ b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Interactions.cs @@ -1,3 +1,4 @@ +using Content.Shared._White.WeaponModules; using Content.Shared.Actions; using Content.Shared.Examine; using Content.Shared.Hands; @@ -21,6 +22,20 @@ public abstract partial class SharedGunSystem args.PushMarkup(Loc.GetString("gun-fire-rate-examine", ("color", FireRateExamineColor), ("fireRate", $"{component.FireRateModified:0.0}"))); + if (TryComp(uid, out var weaponModulesComponent)) + { + if (weaponModulesComponent.Modules.Count == 0) + { + args.PushMarkup(Loc.GetString("gun-modules", ("modules", "Пусто"))); + return; + } + + foreach (var module in weaponModulesComponent.Modules) + { + args.PushMarkup(Loc.GetString("gun-modules", ("modules", Name(module)))); + } + } + if (!TryComp(uid, out var comp)) return; diff --git a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs index 1150392110..37d2c21d6d 100644 --- a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs +++ b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs @@ -1,5 +1,6 @@ using System.Diagnostics.CodeAnalysis; using System.Numerics; +using Content.Shared._White.WeaponModules; using Content.Shared.ActionBlocker; using Content.Shared.Actions; using Content.Shared.Administration.Logs; @@ -476,6 +477,9 @@ public abstract partial class SharedGunSystem : EntitySystem protected void MuzzleFlash(EntityUid gun, AmmoComponent component, EntityUid? user = null) { + bool cancelled = TryComp(gun, out var weaponModulesComponent) && weaponModulesComponent.WeaponFireEffect; // WD EDIT + if(cancelled) return; // WD EDIT END + var attemptEv = new GunMuzzleFlashAttemptEvent(); RaiseLocalEvent(gun, ref attemptEv); if (attemptEv.Cancelled) @@ -534,9 +538,38 @@ public abstract partial class SharedGunSystem : EntitySystem Dirty(gun); } + // WD EDIT + public void SetProjectileSpeed(EntityUid weapon, float projectileSpeed) + { + if(!TryComp(weapon, out var gunComponent)) + return; + gunComponent.ProjectileSpeed = projectileSpeed; + + RefreshModifiers(weapon); + } + + public void SetFireRate(EntityUid weapon, float fireRate) + { + if(!TryComp(weapon, out var gunComponent)) + return; + + gunComponent.FireRate = fireRate; + + RefreshModifiers(weapon); + } + + public void SetSound(EntityUid weapon, SoundSpecifier sound) + { + if(!TryComp(weapon, out var gunComponent)) + return; + + gunComponent.SoundGunshot = sound; + + RefreshModifiers(weapon); + } +// WD EDIT END protected abstract void CreateEffect(EntityUid uid, MuzzleFlashEvent message, EntityUid? user = null); - /// /// Used for animated effects on the client. /// diff --git a/Content.Shared/_White/WeaponModules/AcceleratorModuleComponent.cs b/Content.Shared/_White/WeaponModules/AcceleratorModuleComponent.cs new file mode 100644 index 0000000000..597976a2a4 --- /dev/null +++ b/Content.Shared/_White/WeaponModules/AcceleratorModuleComponent.cs @@ -0,0 +1,12 @@ +namespace Content.Shared._White.WeaponModules; + +/// +/// This is used for... +/// +[RegisterComponent] +public sealed partial class AcceleratorModuleComponent : BaseModuleComponent +{ + public float OldFireRate; + + public float FireRateAdd = 2.4F; +} diff --git a/Content.Shared/_White/WeaponModules/BaseModuleComponent.cs b/Content.Shared/_White/WeaponModules/BaseModuleComponent.cs new file mode 100644 index 0000000000..73a4a4b938 --- /dev/null +++ b/Content.Shared/_White/WeaponModules/BaseModuleComponent.cs @@ -0,0 +1,11 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared._White.WeaponModules; + + +[RegisterComponent, NetworkedComponent] +public partial class BaseModuleComponent : Component +{ + [ViewVariables(VVAccess.ReadWrite), DataField("value")] + public string AppearanceValue; +} diff --git a/Content.Shared/_White/WeaponModules/FlameHiderModuleComponent.cs b/Content.Shared/_White/WeaponModules/FlameHiderModuleComponent.cs new file mode 100644 index 0000000000..94c9a9f02b --- /dev/null +++ b/Content.Shared/_White/WeaponModules/FlameHiderModuleComponent.cs @@ -0,0 +1,9 @@ +namespace Content.Shared._White.WeaponModules; + +/// +/// This is used for... +/// +[RegisterComponent] +public sealed partial class FlameHiderModuleComponent : BaseModuleComponent +{ +} diff --git a/Content.Shared/_White/WeaponModules/LaserModuleComponent.cs b/Content.Shared/_White/WeaponModules/LaserModuleComponent.cs new file mode 100644 index 0000000000..3fd6a91103 --- /dev/null +++ b/Content.Shared/_White/WeaponModules/LaserModuleComponent.cs @@ -0,0 +1,12 @@ +namespace Content.Shared._White.WeaponModules; + +/// +/// This is used for... +/// +[RegisterComponent] +public sealed partial class LaserModuleComponent : BaseModuleComponent +{ + public float OldProjectileSpeed; + + public float ProjectileSpeedAdd = 15F; +} diff --git a/Content.Shared/_White/WeaponModules/LightModuleComponent.cs b/Content.Shared/_White/WeaponModules/LightModuleComponent.cs new file mode 100644 index 0000000000..136663e886 --- /dev/null +++ b/Content.Shared/_White/WeaponModules/LightModuleComponent.cs @@ -0,0 +1,12 @@ +namespace Content.Shared._White.WeaponModules; + +/// +/// LightModuleComponent +/// +[RegisterComponent] +public sealed partial class LightModuleComponent : BaseModuleComponent +{ + public bool Enabled; + + public float Radius = 4F; +} diff --git a/Content.Shared/_White/WeaponModules/SilencerModuleComponent.cs b/Content.Shared/_White/WeaponModules/SilencerModuleComponent.cs new file mode 100644 index 0000000000..d3e72065c8 --- /dev/null +++ b/Content.Shared/_White/WeaponModules/SilencerModuleComponent.cs @@ -0,0 +1,14 @@ +using Robust.Shared.Audio; + +namespace Content.Shared._White.WeaponModules; + +/// +/// This is used for... +/// +[RegisterComponent] +public sealed partial class SilencerModuleComponent : BaseModuleComponent +{ + public SoundSpecifier? OldSoundGunshot; + + public SoundSpecifier NewSoundGunshot = new SoundPathSpecifier("/Audio/White/Weapons/Modules/silence.ogg"); +} diff --git a/Content.Shared/_White/WeaponModules/WeaponModulesComponent.cs b/Content.Shared/_White/WeaponModules/WeaponModulesComponent.cs new file mode 100644 index 0000000000..783648bc3f --- /dev/null +++ b/Content.Shared/_White/WeaponModules/WeaponModulesComponent.cs @@ -0,0 +1,29 @@ +using Robust.Shared.GameStates; +using Robust.Shared.Serialization; + +namespace Content.Shared._White.WeaponModules; + +/// +/// Base Module Component +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public partial class WeaponModulesComponent : Component +{ + [ViewVariables(VVAccess.ReadWrite), DataField] + public List Modules = new(); + + [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + public bool WeaponFireEffect; +} + +[Serializable, NetSerializable] +public enum ModuleVisualState : byte +{ + Module +} + +[Serializable, NetSerializable] +public enum Modules : byte +{ + Light +} diff --git a/Resources/Audio/White/Gun/Modules/ejectmodule.ogg b/Resources/Audio/White/Gun/Modules/ejectmodule.ogg new file mode 100644 index 0000000000..77ef768ab7 Binary files /dev/null and b/Resources/Audio/White/Gun/Modules/ejectmodule.ogg differ diff --git a/Resources/Audio/White/Gun/Modules/insertmodule.ogg b/Resources/Audio/White/Gun/Modules/insertmodule.ogg new file mode 100644 index 0000000000..c7e1884c80 Binary files /dev/null and b/Resources/Audio/White/Gun/Modules/insertmodule.ogg differ diff --git a/Resources/Audio/White/Weapons/Modules/silence.ogg b/Resources/Audio/White/Weapons/Modules/silence.ogg new file mode 100644 index 0000000000..8492f5ad7f Binary files /dev/null and b/Resources/Audio/White/Weapons/Modules/silence.ogg differ diff --git a/Resources/Locale/ru-RU/locales-new/autotranslate-57.ftl b/Resources/Locale/ru-RU/locales-new/autotranslate-57.ftl new file mode 100644 index 0000000000..b280261f02 --- /dev/null +++ b/Resources/Locale/ru-RU/locales-new/autotranslate-57.ftl @@ -0,0 +1,11 @@ +ent-LightModule = модульный фонарик + .desc = Излучает свет. +ent-LaserModule = лазерный модуль + .desc = За счет лазерной обработки пуль, увеличивает их скорость. +ent-FlameHiderModule = пламегаситель + .desc = Скрывает пламя огня во время выстрела. +ent-SilencerModule = глушитель + .desc = Скрывает пламя огня и приглушает звук во время выстрела. +ent-AcceleratorModule = продвинутый модуль + .desc = Разработка NanoTrasen специально для отдела Службы Безопасности. Меняет затворную раму без видимых изменений, за счет этого увеличивает скорострельность оружия. +gun-modules = Установленные модули: [color=cyan]{ $modules }[/color]. \ No newline at end of file diff --git a/Resources/Prototypes/Catalog/Fills/Lockers/security.yml b/Resources/Prototypes/Catalog/Fills/Lockers/security.yml index 0bca462d2a..2c13c0fcc6 100644 --- a/Resources/Prototypes/Catalog/Fills/Lockers/security.yml +++ b/Resources/Prototypes/Catalog/Fills/Lockers/security.yml @@ -18,6 +18,7 @@ - id: BoxMindshield - id: ClothingOuterHardsuitWarden - id: OxygenTankFilled + - id: LightModule - type: entity id: LockerWardenFilled @@ -37,6 +38,7 @@ - id: WeaponPistolMk58Nonlethal - id: MagazinePistol - id: BoxMindshield + - id: LightModule - type: entity id: LockerSecurityFilled @@ -66,6 +68,7 @@ - id: WeaponPistolMk58Nonlethal - id: SurveillanceBodyCamera - id: MagazinePistol + - id: LightModule - type: entity id: LockerBrigmedicFilled @@ -126,6 +129,7 @@ - id: VoiceRecorder - id: ClothingEyesGlassesSecurity - id: BoxZipLocks + - id: LightModule - type: entity id: ClosetBombFilled diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Rifles/rifles.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Rifles/rifles.yml index 82c0770c7f..9f71109abf 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Rifles/rifles.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Rifles/rifles.yml @@ -15,6 +15,7 @@ - Back - suitStorage - type: AmmoCounter + - type: WeaponModules - type: Gun fireRate: 5 selectedMode: FullAuto @@ -32,7 +33,7 @@ startingItem: MagazineLightRifle insertSound: /Audio/Weapons/Guns/MagIn/batrifle_magin.ogg ejectSound: /Audio/Weapons/Guns/MagOut/batrifle_magout.ogg - priority: 2 + priority: 3 whitelist: tags: - MagazineLightRifle @@ -43,10 +44,19 @@ whitelist: tags: - CartridgeLightRifle + gun_modules: + name: Modules + insertSound: /Audio/White/Gun/Modules/insertmodule.ogg + ejectSound: /Audio/White/Gun/Modules/ejectmodule.ogg + priority: 2 + whitelist: + tags: + - BaseModule - type: ContainerContainer containers: gun_magazine: !type:ContainerSlot gun_chamber: !type:ContainerSlot + gun_modules: !type:ContainerSlot - type: StaticPrice price: 500 @@ -63,6 +73,10 @@ map: [ "enum.GunVisualLayers.Base" ] - state: mag-0 map: [ "enum.GunVisualLayers.Mag" ] + - state: laser + visible: false + sprite: White/Objects/Weapons/modulesOnWeapon.rsi + map: [ "enum.ModuleVisualState.Module" ] - type: Gun fireRate: 5 soundGunshot: @@ -88,14 +102,26 @@ whitelist: tags: - CartridgeLightRifle + gun_modules: + name: Modules + insertSound: /Audio/White/Gun/Modules/insertmodule.ogg + ejectSound: /Audio/White/Gun/Modules/ejectmodule.ogg + priority: 2 + whitelist: + tags: + - BaseModule - type: ContainerContainer containers: gun_magazine: !type:ContainerSlot gun_chamber: !type:ContainerSlot + gun_modules: !type:ContainerSlot - type: MagazineVisuals magState: mag steps: 1 zeroVisible: true + - type: PointLight + enabled: false + autoRot: true - type: Appearance - type: entity @@ -154,6 +180,10 @@ map: [ "enum.GunVisualLayers.Base" ] - state: mag-0 map: [ "enum.GunVisualLayers.Mag" ] + - state: laser + visible: false + sprite: White/Objects/Weapons/modulesOnWeapon.rsi + map: [ "enum.ModuleVisualState.Module" ] - type: Clothing sprite: Objects/Weapons/Guns/Rifles/lecter.rsi - type: Gun @@ -177,14 +207,26 @@ whitelist: tags: - CartridgeRifle + gun_modules: + name: Modules + insertSound: /Audio/White/Gun/Modules/insertmodule.ogg + ejectSound: /Audio/White/Gun/Modules/ejectmodule.ogg + priority: 2 + whitelist: + tags: + - BaseModule - type: ContainerContainer containers: gun_magazine: !type:ContainerSlot gun_chamber: !type:ContainerSlot + gun_modules: !type:ContainerSlot - type: MagazineVisuals magState: mag steps: 1 zeroVisible: true + - type: PointLight + enabled: false + autoRot: true - type: Appearance - type: entity @@ -211,3 +253,11 @@ whitelist: tags: - CartridgeRifle + gun_modules: + name: Modules + insertSound: /Audio/White/Gun/Modules/insertmodule.ogg + ejectSound: /Audio/White/Gun/Modules/ejectmodule.ogg + priority: 2 + whitelist: + tags: + - BaseModule diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml index b693bdba37..7e968d088b 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml @@ -117,6 +117,10 @@ map: ["enum.GunVisualLayers.Base"] - state: mag-0 map: ["enum.GunVisualLayers.Mag"] + - state: laser + visible: false + sprite: White/Objects/Weapons/modulesOnWeapon.rsi + map: [ "enum.ModuleVisualState.Module" ] - type: Clothing sprite: Objects/Weapons/Guns/SMGs/drozd.rsi - type: Gun @@ -126,6 +130,7 @@ path: /Audio/Weapons/Guns/Gunshots/atreides.ogg availableModes: - FullAuto + - type: WeaponModules - type: ItemSlots slots: gun_magazine: @@ -144,10 +149,26 @@ whitelist: tags: - CartridgePistol + gun_modules: + name: Modules + insertSound: /Audio/White/Gun/Modules/insertmodule.ogg + ejectSound: /Audio/White/Gun/Modules/ejectmodule.ogg + priority: 2 + whitelist: + tags: + - BaseModule + - type: ContainerContainer + containers: + gun_magazine: !type:ContainerSlot + gun_chamber: !type:ContainerSlot + gun_modules: !type:ContainerSlot - type: MagazineVisuals magState: mag steps: 1 zeroVisible: true + - type: PointLight + enabled: false + autoRot: true - type: Appearance - type: entity @@ -216,6 +237,10 @@ - state: mag-unshaded-0 map: ["enum.GunVisualLayers.MagUnshaded"] shader: unshaded + - state: laser + visible: false + sprite: White/Objects/Weapons/modulesOnWeapon.rsi + map: [ "enum.ModuleVisualState.Module" ] - type: Clothing sprite: Objects/Weapons/Guns/SMGs/wt550.rsi - type: ChamberMagazineAmmoProvider @@ -225,6 +250,7 @@ selectedMode: FullAuto availableModes: - FullAuto + - type: WeaponModules - type: ItemSlots slots: gun_magazine: @@ -243,10 +269,25 @@ whitelist: tags: - CartridgePistol + gun_modules: + name: Modules + insertSound: /Audio/White/Gun/Modules/insertmodule.ogg + ejectSound: /Audio/White/Gun/Modules/ejectmodule.ogg + priority: 2 + whitelist: + tags: + - BaseModule + - type: ContainerContainer + containers: + gun_magazine: !type:ContainerSlot + gun_chamber: !type:ContainerSlot - type: MagazineVisuals magState: mag steps: 6 zeroVisible: true + - type: PointLight + enabled: false + autoRot: true - type: Appearance # Rubber @@ -274,6 +315,14 @@ whitelist: tags: - CartridgePistol + gun_modules: + name: Modules + insertSound: /Audio/White/Gun/Modules/insertmodule.ogg + ejectSound: /Audio/White/Gun/Modules/ejectmodule.ogg + priority: 2 + whitelist: + tags: + - BaseModule - type: entity name: Vector diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index 1ba3cc0b01..00c0b06b35 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -197,6 +197,11 @@ - MagazineBoxRifle - MagazineBoxLightRifle - GrenadeBlast + - LightModuleRecipe + - LaserModuleRecipe + - FlameHiderModuleRecipe + - SilencerModuleRecipe + - AcceleratorModuleRecipe emagDynamicRecipes: - CartridgePistolRubber - CartridgeMagnumRubber @@ -705,6 +710,11 @@ - ShellShotgunPractice - WeaponLaserCarbinePractice - WeaponDisablerPractice + - LightModuleRecipe + - LaserModuleRecipe + - FlameHiderModuleRecipe + - SilencerModuleRecipe + - AcceleratorModuleRecipe dynamicRecipes: - CartridgeLightRifleIncendiary - CartridgeMagnumIncendiary diff --git a/Resources/Prototypes/Recipes/Lathes/security.yml b/Resources/Prototypes/Recipes/Lathes/security.yml index 5e16440cd1..1a33745634 100644 --- a/Resources/Prototypes/Recipes/Lathes/security.yml +++ b/Resources/Prototypes/Recipes/Lathes/security.yml @@ -665,3 +665,47 @@ Steel: 100 Plastic: 50 Silver: 50 + +- type: latheRecipe + id: LightModuleRecipe + result: LightModule + completetime: 5 + materials: + Steel: 700 + Plastic: 700 + Glass: 500 + +- type: latheRecipe + id: LaserModuleRecipe + result: LaserModule + completetime: 10 + materials: + Steel: 1500 + Plastic: 1000 + Glass: 300 + +- type: latheRecipe + id: FlameHiderModuleRecipe + result: FlameHiderModule + completetime: 15 + materials: + Steel: 1000 + Plastic: 1000 + +- type: latheRecipe + id: SilencerModuleRecipe + result: SilencerModule + completetime: 15 + materials: + Steel: 1000 + Plastic: 1000 + +- type: latheRecipe + id: AcceleratorModuleRecipe + result: AcceleratorModule + completetime: 30 + materials: + Steel: 3500 + Plastic: 1000 + Glass: 500 + Gold: 1000 diff --git a/Resources/Prototypes/_White/Entities/Objects/Weapons/Guns/Modules/modules.yml b/Resources/Prototypes/_White/Entities/Objects/Weapons/Guns/Modules/modules.yml new file mode 100644 index 0000000000..dd2ec684aa --- /dev/null +++ b/Resources/Prototypes/_White/Entities/Objects/Weapons/Guns/Modules/modules.yml @@ -0,0 +1,82 @@ +- type: entity + id: BaseModule + parent: BaseItem + abstract: true + components: + - type: Sprite + sprite: White/Objects/Weapons/modules.rsi + - type: Tag + tags: + - BaseModule + - type: Item + sprite: White/Objects/Weapons/modules.rsi + size: Small + shape: + - 0,0,0,0 + layers: + - state: base + map: ["enum.GunVisualLayers.Base"] + - state: mag-1 + map: ["enum.GunVisualLayers.Mag"] + - type: Appearance + +# modules +- type: entity + id: LightModule + description: Light module for rifles (lecter, CV, drozd, WT). + name: "light module" + parent: BaseModule + components: + - type: LightModule + value: "light" + - type: Sprite + state: light + - type: Appearance + +- type: entity + id: LaserModule + description: Laser module for rifles (lecter, CV, drozd, WT). + name: "laser module" + parent: BaseModule + components: + - type: LaserModule + value: "laser" + - type: Sprite + state: laser + - type: Appearance + +- type: entity + id: FlameHiderModule + description: Flame Hider module for rifles (lecter, CV, drozd, WT). + name: "flamehider module" + parent: BaseModule + components: + - type: FlameHiderModule + value: "flamehider" + - type: Sprite + state: flamehider + - type: Appearance + +- type: entity + id: SilencerModule + description: Silencer module for rifles (lecter, CV, drozd, WT). + name: "silencer module" + parent: BaseModule + components: + - type: SilencerModule + value: "silencer" + - type: Sprite + state: silencer + - type: Appearance + +- type: entity + id: AcceleratorModule + description: Accelerator module for rifles (lecter, CV, drozd, WT). + name: "accelerator module" + parent: BaseModule + components: + - type: AcceleratorModule + value: "accelerator" + - type: Sprite + state: accelerator + - type: Appearance \ No newline at end of file diff --git a/Resources/Prototypes/_White/tags.yml b/Resources/Prototypes/_White/tags.yml index 466a1ddb17..73d3311562 100644 --- a/Resources/Prototypes/_White/tags.yml +++ b/Resources/Prototypes/_White/tags.yml @@ -54,3 +54,6 @@ - type: Tag id: MindSlave + +- type: Tag + id: BaseModule diff --git a/Resources/Textures/Effects/LightMasks/cone.png b/Resources/Textures/Effects/LightMasks/cone.png index 2cd329b99c..66d0069768 100644 Binary files a/Resources/Textures/Effects/LightMasks/cone.png and b/Resources/Textures/Effects/LightMasks/cone.png differ diff --git a/Resources/Textures/White/Effects/LightMasks/lightModule.png b/Resources/Textures/White/Effects/LightMasks/lightModule.png new file mode 100644 index 0000000000..66d0069768 Binary files /dev/null and b/Resources/Textures/White/Effects/LightMasks/lightModule.png differ diff --git a/Resources/Textures/White/Objects/Weapons/modules.rsi/accelerator.png b/Resources/Textures/White/Objects/Weapons/modules.rsi/accelerator.png new file mode 100644 index 0000000000..99fffd9ee6 Binary files /dev/null and b/Resources/Textures/White/Objects/Weapons/modules.rsi/accelerator.png differ diff --git a/Resources/Textures/White/Objects/Weapons/modules.rsi/flamehider.png b/Resources/Textures/White/Objects/Weapons/modules.rsi/flamehider.png new file mode 100644 index 0000000000..3a66711c97 Binary files /dev/null and b/Resources/Textures/White/Objects/Weapons/modules.rsi/flamehider.png differ diff --git a/Resources/Textures/White/Objects/Weapons/modules.rsi/laser.png b/Resources/Textures/White/Objects/Weapons/modules.rsi/laser.png new file mode 100644 index 0000000000..457b77dda9 Binary files /dev/null and b/Resources/Textures/White/Objects/Weapons/modules.rsi/laser.png differ diff --git a/Resources/Textures/White/Objects/Weapons/modules.rsi/light.png b/Resources/Textures/White/Objects/Weapons/modules.rsi/light.png new file mode 100644 index 0000000000..347e76a4b2 Binary files /dev/null and b/Resources/Textures/White/Objects/Weapons/modules.rsi/light.png differ diff --git a/Resources/Textures/White/Objects/Weapons/modules.rsi/meta.json b/Resources/Textures/White/Objects/Weapons/modules.rsi/meta.json new file mode 100644 index 0000000000..1560e9b5ea --- /dev/null +++ b/Resources/Textures/White/Objects/Weapons/modules.rsi/meta.json @@ -0,0 +1,26 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Maked by CaypenNow", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "light" + }, + { + "name": "laser" + }, + { + "name": "flamehider" + }, + { + "name": "silencer" + }, + { + "name": "accelerator" + } + ] +} diff --git a/Resources/Textures/White/Objects/Weapons/modules.rsi/silencer.png b/Resources/Textures/White/Objects/Weapons/modules.rsi/silencer.png new file mode 100644 index 0000000000..40cf69b56a Binary files /dev/null and b/Resources/Textures/White/Objects/Weapons/modules.rsi/silencer.png differ diff --git a/Resources/Textures/White/Objects/Weapons/modulesOnWeapon.rsi/accelerator.png b/Resources/Textures/White/Objects/Weapons/modulesOnWeapon.rsi/accelerator.png new file mode 100644 index 0000000000..03a3c0e420 Binary files /dev/null and b/Resources/Textures/White/Objects/Weapons/modulesOnWeapon.rsi/accelerator.png differ diff --git a/Resources/Textures/White/Objects/Weapons/modulesOnWeapon.rsi/flamehider.png b/Resources/Textures/White/Objects/Weapons/modulesOnWeapon.rsi/flamehider.png new file mode 100644 index 0000000000..c3501bed70 Binary files /dev/null and b/Resources/Textures/White/Objects/Weapons/modulesOnWeapon.rsi/flamehider.png differ diff --git a/Resources/Textures/White/Objects/Weapons/modulesOnWeapon.rsi/laser.png b/Resources/Textures/White/Objects/Weapons/modulesOnWeapon.rsi/laser.png new file mode 100644 index 0000000000..efe0ab5bbb Binary files /dev/null and b/Resources/Textures/White/Objects/Weapons/modulesOnWeapon.rsi/laser.png differ diff --git a/Resources/Textures/White/Objects/Weapons/modulesOnWeapon.rsi/light.png b/Resources/Textures/White/Objects/Weapons/modulesOnWeapon.rsi/light.png new file mode 100644 index 0000000000..c4328d7c12 Binary files /dev/null and b/Resources/Textures/White/Objects/Weapons/modulesOnWeapon.rsi/light.png differ diff --git a/Resources/Textures/White/Objects/Weapons/modulesOnWeapon.rsi/meta.json b/Resources/Textures/White/Objects/Weapons/modulesOnWeapon.rsi/meta.json new file mode 100644 index 0000000000..82d692646c --- /dev/null +++ b/Resources/Textures/White/Objects/Weapons/modulesOnWeapon.rsi/meta.json @@ -0,0 +1,26 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "made by CaypenNow", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "laser" + }, + { + "name": "light" + }, + { + "name": "flamehider" + }, + { + "name": "silencer" + }, + { + "name": "accelerator" + } + ] +} diff --git a/Resources/Textures/White/Objects/Weapons/modulesOnWeapon.rsi/silencer.png b/Resources/Textures/White/Objects/Weapons/modulesOnWeapon.rsi/silencer.png new file mode 100644 index 0000000000..c51e1f4c8f Binary files /dev/null and b/Resources/Textures/White/Objects/Weapons/modulesOnWeapon.rsi/silencer.png differ