Browse Source

Merge branch 'master' of https://github.com/Civ13/Civ14

Taislin 6 tháng trước cách đây
mục cha
commit
73e2df5643
37 tập tin đã thay đổi với 372 bổ sung424 xóa
  1. 1 1
      Content.Client/Overlays/ShowFactionIconsSystem.cs
  2. 2 2
      Content.Server/Salvage/SalvageSystem.Magnet.cs
  3. 4 0
      Resources/Locale/en-US/headset/headset-component.ftl
  4. 15 0
      Resources/Prototypes/Civ14/Entities/Objects/Radio/radio_channels.yml
  5. 32 1
      Resources/Prototypes/Entities/Clothing/Ears/headsets.yml
  6. 2 7
      Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml
  7. 0 1
      Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml
  8. 64 75
      Resources/Prototypes/Entities/Mobs/Player/ratvar.yml
  9. 30 0
      Resources/Prototypes/Entities/Objects/Devices/encryption_keys.yml
  10. 0 17
      Resources/Prototypes/Entities/Objects/Devices/radio.yml
  11. 2 2
      Resources/Prototypes/Entities/Objects/Fun/pai.yml
  12. 84 86
      Resources/Prototypes/Entities/Objects/Misc/subdermal_implants.yml
  13. 3 3
      Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml
  14. 1 1
      Resources/Prototypes/Entities/Structures/Machines/anomaly_equipment.yml
  15. 43 43
      Resources/Prototypes/Entities/Structures/Machines/salvage.yml
  16. 5 0
      Resources/Prototypes/Roles/Jobs/Civ14/TDM/english.yml
  17. 5 0
      Resources/Prototypes/Roles/Jobs/Civ14/TDM/french.yml
  18. 8 2
      Resources/Prototypes/Roles/Jobs/Civ14/TDM/sovietCW.yml
  19. 7 0
      Resources/Prototypes/Roles/Jobs/Civ14/TDM/usa.yml
  20. 0 8
      Resources/Prototypes/XenoArch/Effects/utility_effects.yml
  21. 39 49
      Resources/Prototypes/borg_types.yml
  22. 2 67
      Resources/Prototypes/radio_channels.yml
  23. 5 5
      Resources/ServerInfo/Guidebook/NewPlayer/Controls/Radio.xml
  24. BIN
      Resources/Textures/Civ14/Objects/headset.rsi/equipped-EARS.png
  25. BIN
      Resources/Textures/Civ14/Objects/headset.rsi/icon.png
  26. 18 0
      Resources/Textures/Civ14/Objects/headset.rsi/meta.json
  27. BIN
      Resources/Textures/Civ14/Weapons/Guns/m60.rsi/mag-0.png
  28. BIN
      Resources/Textures/Civ14/Weapons/Guns/m60_mag.rsi/bolt-open.png
  29. BIN
      Resources/Textures/Civ14/Weapons/Guns/m60_mag.rsi/icon.png
  30. BIN
      Resources/Textures/Civ14/Weapons/Guns/m60_mag.rsi/m60_mag.png
  31. BIN
      Resources/Textures/Civ14/Weapons/Guns/m60_mag.rsi/mag-0.png
  32. 0 27
      Resources/Textures/Civ14/Weapons/Guns/m60_mag.rsi/meta.json
  33. BIN
      Resources/Textures/Civ14/Weapons/Guns/rpd.rsi/mag-0.png
  34. BIN
      Resources/Textures/Civ14/Weapons/Guns/rpd_mag.rsi/bolt-open.png
  35. BIN
      Resources/Textures/Civ14/Weapons/Guns/rpd_mag.rsi/icon.png
  36. 0 27
      Resources/Textures/Civ14/Weapons/Guns/rpd_mag.rsi/meta.json
  37. BIN
      Resources/Textures/Civ14/Weapons/Guns/rpd_mag.rsi/rpd_mag.png

+ 1 - 1
Content.Client/Overlays/ShowFactionIconsSystem.cs

@@ -40,7 +40,7 @@ private void OnGetStatusIconsEvent(EntityUid uid, ShowFactionIconsComponent comp
                 ev.StatusIcons.Add(squadIconPrototype);
         }
         // Otherwise, display the general job icon if no squad icon is present or if not part of a squad
-        if (component.JobIcon != null && component.JobIcon != "JobIconSoldier" && component.JobIcon != "JobIconRifleman" && component.JobIcon != "JobIconMG")
+        if (component.JobIcon != null && component.JobIcon != "JobIconSoldier" && component.JobIcon != "JobIconRifleman" && component.JobIcon != "JobIconMg")
         {
             if (_prototype.TryIndex<JobIconPrototype>(component.JobIcon, out var jobIconPrototype))
                 ev.StatusIcons.Add(jobIconPrototype);

+ 2 - 2
Content.Server/Salvage/SalvageSystem.Magnet.cs

@@ -16,7 +16,7 @@ public sealed partial class SalvageSystem
     [Dependency] private readonly IRuntimeLog _runtimeLog = default!;
 
     [ValidatePrototypeId<RadioChannelPrototype>]
-    private const string MagnetChannel = "Supply";
+    private const string MagnetChannel = "Common";
 
     private EntityQuery<SalvageMobRestrictionsComponent> _salvMobQuery;
     private EntityQuery<MobStateComponent> _mobStateQuery;
@@ -204,7 +204,7 @@ private void CreateMagnetOffers(Entity<SalvageMagnetDataComponent> data)
             var seed = _random.Next();
 
             // Fuck with the seed to mix wrecks and asteroids.
-            seed = (int) (seed / 10f) * 10;
+            seed = (int)(seed / 10f) * 10;
 
 
             if (i >= data.Comp.OfferCount / 2)

+ 4 - 0
Resources/Locale/en-US/headset/headset-component.ftl

@@ -19,3 +19,7 @@ chat-radio-freelance = Freelance
 # not headset but whatever
 chat-radio-handheld = Handheld
 chat-radio-binary = Binary
+
+
+chat-radio-soviet = Soviet
+chat-radio-us = US

+ 15 - 0
Resources/Prototypes/Civ14/Entities/Objects/Radio/radio_channels.yml

@@ -0,0 +1,15 @@
+- type: radioChannel
+  id: Soviet
+  name: chat-radio-soviet
+  keycode: "s"
+  frequency: 1349
+  color: "#539c00"
+  longRange: true
+
+- type: radioChannel
+  id: US
+  name: chat-radio-us
+  keycode: "u"
+  frequency: 1351
+  color: "#539c00"
+  longRange: true

+ 32 - 1
Resources/Prototypes/Entities/Clothing/Ears/headsets.yml

@@ -18,13 +18,14 @@
     - type: Sprite
       state: icon
     - type: STWeight
-      self: 1
+      self: 0.5
     - type: Item
       size: Small
     - type: Clothing
       slots:
         - ears
       sprite: Clothing/Ears/Headsets/base.rsi
+    - type: TelecomExempt
     - type: GuideHelp
       guides:
         - Radio
@@ -51,3 +52,33 @@
       sprite: Clothing/Ears/Headsets/cargo.rsi
     - type: Clothing
       sprite: Clothing/Ears/Headsets/cargo.rsi
+
+- type: entity
+  parent: ClothingHeadset
+  id: ClothingHeadsetSoviet
+  name: Soviet headset
+  description: A headset used by the Soviet Union.
+  components:
+    - type: ContainerFill
+      containers:
+        key_slots:
+          - EncryptionKeySoviet
+    - type: Sprite
+      sprite: Civ14/Objects/headset.rsi
+    - type: Clothing
+      sprite: Civ14/Objects/headset.rsi
+
+- type: entity
+  parent: ClothingHeadset
+  id: ClothingHeadsetUS
+  name: US headset
+  description: A headset used by the United States.
+  components:
+    - type: ContainerFill
+      containers:
+        key_slots:
+          - EncryptionKeyUS
+    - type: Sprite
+      sprite: Civ14/Objects/headset.rsi
+    - type: Clothing
+      sprite: Civ14/Objects/headset.rsi

+ 2 - 7
Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml

@@ -93,14 +93,10 @@
     - type: IntrinsicRadioReceiver
     - type: IntrinsicRadioTransmitter
       channels:
-        - Binary
         - Common
-        - Science
     - type: ActiveRadio
       channels:
-        - Binary
         - Common
-        - Science
     - type: ZombieImmune
     - type: Repairable
       doAfterDelay: 10
@@ -311,11 +307,10 @@
       subverted: true
     - type: IntrinsicRadioTransmitter
       channels:
-        - Binary
-        - Syndicate
+        - Common
     - type: ActiveRadio
       channels:
-        - Syndicate
+        - Common
     - type: ShowSyndicateIcons
     - type: MovementAlwaysTouching
     - type: Speech

+ 0 - 1
Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml

@@ -413,4 +413,3 @@
     - type: ActiveRadio
       channels:
         - Common
-        - Supply

+ 64 - 75
Resources/Prototypes/Entities/Mobs/Player/ratvar.yml

@@ -4,91 +4,80 @@
   name: Ratvar
   description: Your mind aches as it fails to understand the complex mechanics of what is before you.
   components:
-  - type: Sprite
-    sprite: Mobs/Demons/ratvar.rsi
-    drawdepth: Ghosts
-    scale: 1.15,1.15
-    layers:
-    - state: ratvar
-      shader: unshaded
+    - type: Sprite
+      sprite: Mobs/Demons/ratvar.rsi
+      drawdepth: Ghosts
+      scale: 1.15,1.15
+      layers:
+        - state: ratvar
+          shader: unshaded
 
 - type: entity
   parent: MobRatvarBase
   id: MobRatvarSpawn
   suffix: Spawn
   components:
-  - type: Sprite
-    layers:
-    - state: spawn
-      shader: unshaded
-  - type: TimedDespawn
-    lifetime: 3.5
-  - type: SpawnOnDespawn
-    prototype: MobRatvar
+    - type: Sprite
+      layers:
+        - state: spawn
+          shader: unshaded
+    - type: TimedDespawn
+      lifetime: 3.5
+    - type: SpawnOnDespawn
+      prototype: MobRatvar
 
 - type: entity
   parent: [MobRatvarBase, BaseMob]
   id: MobRatvar
   components:
-  - type: AnnounceOnSpawn
-    message: ratvar-has-risen
-    sender: ratvar-has-risen-sender
-    sound:
-      path: /Audio/Misc/ratvar_reveal.ogg
-    color: "#BE8700"
-  - type: CargoSellBlacklist
-  - type: ContentEye
-    maxZoom: 2.0,2.0
-  - type: Fixtures
-    fixtures:
-      EventHorizonCollider:
-        shape:
-          !type:PhysShapeCircle
+    - type: AnnounceOnSpawn
+      message: ratvar-has-risen
+      sender: ratvar-has-risen-sender
+      sound:
+        path: /Audio/Misc/ratvar_reveal.ogg
+      color: "#BE8700"
+    - type: CargoSellBlacklist
+    - type: ContentEye
+      maxZoom: 2.0,2.0
+    - type: Fixtures
+      fixtures:
+        EventHorizonCollider:
+          shape: !type:PhysShapeCircle
             radius: 5
-        hard: false
-        restitution: 0.8
-        density: 1
-        mask:
-        - SingularityLayer
-        layer:
-        - SingularityLayer
-      EventHorizonConsumer:
-        shape:
-          !type:PhysShapeCircle
+          hard: false
+          restitution: 0.8
+          density: 1
+          mask:
+            - SingularityLayer
+          layer:
+            - SingularityLayer
+        EventHorizonConsumer:
+          shape: !type:PhysShapeCircle
             radius: 5
-        hard: false
-        mask:
-        - SingularityLayer
-        layer:
-        - SingularityLayer
-  - type: Input
-    context: "ghost"
-  - type: MovementIgnoreGravity
-  - type: IntrinsicRadioReceiver
-  - type: ActiveRadio
-    channels:
-    - Binary
-    - Common
-    - Command
-    - CentCom
-    - Engineering
-    - Medical
-    - Science
-    - Security
-    - Service
-    - Supply
-    - Syndicate
-    globalReceive: true
-  - type: Physics
-    bodyType: Dynamic
-    bodyStatus: InAir
-  - type: CanMoveInAir
-  - type: EventHorizon
-    radius: 5
-    canBreachContainment: true
-  - type: GravityWell
-    baseRadialAcceleration: 6
-    maxRange: 8
-  - type: WarpPoint
-    follow: true
-    location: Ratvar
+          hard: false
+          mask:
+            - SingularityLayer
+          layer:
+            - SingularityLayer
+    - type: Input
+      context: "ghost"
+    - type: MovementIgnoreGravity
+    - type: IntrinsicRadioReceiver
+    - type: ActiveRadio
+      channels:
+        - Binary
+        - Common
+      globalReceive: true
+    - type: Physics
+      bodyType: Dynamic
+      bodyStatus: InAir
+    - type: CanMoveInAir
+    - type: EventHorizon
+      radius: 5
+      canBreachContainment: true
+    - type: GravityWell
+      baseRadialAcceleration: 6
+      maxRange: 8
+    - type: WarpPoint
+      follow: true
+      location: Ratvar

+ 30 - 0
Resources/Prototypes/Entities/Objects/Devices/encryption_keys.yml

@@ -25,3 +25,33 @@
       layers:
         - state: crypt_gray
         - state: common_label
+
+- type: entity
+  parent: EncryptionKey
+  id: EncryptionKeySoviet
+  name: Soviet encryption key
+  description: An encryption key used by the Soviet Union.
+  components:
+    - type: EncryptionKey
+      channels:
+        - Soviet
+      defaultChannel: Soviet
+    - type: Sprite
+      layers:
+        - state: crypt_gray
+        - state: common_label
+
+- type: entity
+  parent: EncryptionKey
+  id: EncryptionKeyUS
+  name: US encryption key
+  description: An encryption key used by the United States.
+  components:
+    - type: EncryptionKey
+      channels:
+        - US
+      defaultChannel: US
+    - type: Sprite
+      layers:
+        - state: crypt_gray
+        - state: common_label

+ 0 - 17
Resources/Prototypes/Entities/Objects/Devices/radio.yml

@@ -24,20 +24,3 @@
     - type: Tag
       tags:
         - Radio
-
-- type: entity
-  name: security radio
-  description: A handy security radio.
-  parent: [RadioHandheld]
-  id: RadioHandheldSecurity
-  components:
-    - type: RadioMicrophone
-      broadcastChannel: Security
-    - type: RadioSpeaker
-      channels:
-        - Security
-    - type: Sprite
-      sprite: Objects/Devices/securityhandy.rsi
-    - type: Item
-      sprite: Objects/Devices/securityhandy.rsi
-      heldPrefix: walkietalkie

+ 2 - 2
Resources/Prototypes/Entities/Objects/Fun/pai.yml

@@ -97,10 +97,10 @@
         - MindRoleGhostRoleFamiliar
     - type: IntrinsicRadioTransmitter
       channels:
-        - Syndicate
+        - Common
     - type: ActiveRadio
       channels:
-        - Syndicate
+        - Common
     - type: Appearance
     - type: GenericVisualizer
       visuals:

+ 84 - 86
Resources/Prototypes/Entities/Objects/Misc/subdermal_implants.yml

@@ -4,11 +4,11 @@
   description: A microscopic chip that's injected under the skin.
   abstract: true
   components:
-  - type: SubdermalImplant
-  - type: Tag
-    tags:
-    - SubdermalImplant
-    - HideContextMenu
+    - type: SubdermalImplant
+    - type: Tag
+      tags:
+        - SubdermalImplant
+        - HideContextMenu
 
 #Fun implants
 
@@ -17,15 +17,15 @@
   id: SadTromboneImplant
   name: sad trombone implant
   description: This implant plays a sad tune when the user dies.
-  categories: [ HideSpawnMenu ]
+  categories: [HideSpawnMenu]
   components:
     - type: SubdermalImplant
       whitelist:
         components:
-        - MobState # admeme implanting a chair with trombone implant needs to give the chair mobstate so it can die first
+          - MobState # admeme implanting a chair with trombone implant needs to give the chair mobstate so it can die first
     - type: TriggerOnMobstateChange
       mobState:
-      - Dead
+        - Dead
     - type: EmitSoundOnTrigger
       sound:
         collection: SadTrombone
@@ -37,7 +37,7 @@
   id: LightImplant
   name: light implant
   description: This implant emits light from the user's skin on activation.
-  categories: [ HideSpawnMenu ]
+  categories: [HideSpawnMenu]
   components:
     - type: SubdermalImplant
       implantAction: ActionToggleLight
@@ -59,7 +59,7 @@
   id: BikeHornImplant
   name: bike horn implant
   description: This implant lets the user honk anywhere at any time.
-  categories: [ HideSpawnMenu ]
+  categories: [HideSpawnMenu]
   components:
     - type: SubdermalImplant
       implantAction: ActionActivateHonkImplant
@@ -71,7 +71,7 @@
           variation: 0.125
     - type: Tag
       tags:
-      - BikeHorn
+        - BikeHorn
 
 #Security implants
 
@@ -80,12 +80,12 @@
   id: TrackingImplant
   name: tracking implant
   description: This implant has a tracking device attached to the suit sensor network, as well as a condition monitor for the Security radio channel.
-  categories: [ HideSpawnMenu ]
+  categories: [HideSpawnMenu]
   components:
     - type: SubdermalImplant
       whitelist:
         components:
-        - MobState # admeme implanting a chair with tracking implant needs to give the chair mobstate so it can die first
+          - MobState # admeme implanting a chair with tracking implant needs to give the chair mobstate so it can die first
     - type: SuitSensor
       randomMode: false
       controlsLocked: true
@@ -99,9 +99,9 @@
       range: 500
     - type: TriggerOnMobstateChange
       mobState:
-      - Critical
+        - Critical
     - type: Rattle
-      radioChannel: "Security"
+      radioChannel: "Common"
 
 #Traitor implants
 
@@ -110,20 +110,20 @@
   id: StorageImplant
   name: storage implant
   description: This implant grants hidden storage within a person's body using bluespace technology.
-  categories: [ HideSpawnMenu ]
+  categories: [HideSpawnMenu]
   components:
     - type: SubdermalImplant
       implantAction: ActionOpenStorageImplant
       whitelist:
         components:
-        - Hands # no use giving a mouse a storage implant, but a monkey is another story...
+          - Hands # no use giving a mouse a storage implant, but a monkey is another story...
     - type: Storage
       grid:
-      - 0,0,2,2
+        - 0,0,2,2
     - type: ContainerContainer
       containers:
         storagebase: !type:Container
-          ents: [ ]
+          ents: []
     - type: UserInterface
       interfaces:
         enum.StorageUiKey.Key:
@@ -134,52 +134,51 @@
   id: FreedomImplant
   name: freedom implant
   description: This implant lets the user break out of hand restraints up to three times before ceasing to function anymore.
-  categories: [ HideSpawnMenu ]
+  categories: [HideSpawnMenu]
   components:
     - type: SubdermalImplant
       implantAction: ActionActivateFreedomImplant
       whitelist:
         components:
-        - Cuffable # useless if you cant be cuffed
+          - Cuffable # useless if you cant be cuffed
 
 - type: entity
   parent: BaseSubdermalImplant
   id: RadioImplant
   name: radio implant
   description: This implant grants access to the Syndicate channel without a headset.
-  categories: [ HideSpawnMenu ]
+  categories: [HideSpawnMenu]
   components:
-  - type: SubdermalImplant
-  - type: RadioImplant
-    radioChannels:
-    - Syndicate
-
+    - type: SubdermalImplant
+    - type: RadioImplant
+      radioChannels:
+        - Common
 - type: entity
-  parent: [ BaseSubdermalImplant, StorePresetUplink ]
+  parent: [BaseSubdermalImplant, StorePresetUplink]
   id: UplinkImplant
   name: uplink implant
   description: This implant lets the user access a hidden Syndicate uplink at will.
-  categories: [ HideSpawnMenu ]
+  categories: [HideSpawnMenu]
   components:
-  - type: SubdermalImplant
-    implantAction: ActionOpenUplinkImplant
-    whitelist:
-      components:
-      - Hands # prevent mouse buying grenade penguin since its not telepathic
-  - type: Store
-    balance:
-      Telecrystal: 0
-  - type: UserInterface
-    interfaces:
-      enum.StoreUiKey.Key:
-        type: StoreBoundUserInterface
+    - type: SubdermalImplant
+      implantAction: ActionOpenUplinkImplant
+      whitelist:
+        components:
+          - Hands # prevent mouse buying grenade penguin since its not telepathic
+    - type: Store
+      balance:
+        Telecrystal: 0
+    - type: UserInterface
+      interfaces:
+        enum.StoreUiKey.Key:
+          type: StoreBoundUserInterface
 
 - type: entity
   parent: BaseSubdermalImplant
   id: EmpImplant
   name: EMP implant
   description: This implant creates an electromagnetic pulse when activated.
-  categories: [ HideSpawnMenu ]
+  categories: [HideSpawnMenu]
   components:
     - type: SubdermalImplant
       implantAction: ActionActivateEmpImplant
@@ -194,7 +193,7 @@
   id: ScramImplant
   name: scram implant
   description: This implant randomly teleports the user within a large radius when activated.
-  categories: [ HideSpawnMenu ]
+  categories: [HideSpawnMenu]
   components:
     - type: SubdermalImplant
       implantAction: ActionActivateScramImplant
@@ -206,13 +205,13 @@
   id: DnaScramblerImplant
   name: DNA scrambler implant
   description: This implant lets the user randomly change their appearance and name once.
-  categories: [ HideSpawnMenu ]
+  categories: [HideSpawnMenu]
   components:
     - type: SubdermalImplant
       implantAction: ActionActivateDnaScramblerImplant
       whitelist:
         components:
-        - HumanoidAppearance # syndies cant turn hamlet into a human
+          - HumanoidAppearance # syndies cant turn hamlet into a human
 
 #Nuclear Operative/Special Exclusive implants
 
@@ -221,14 +220,14 @@
   id: MicroBombImplant
   name: micro-bomb implant
   description: This implant detonates the user upon activation or upon death.
-  categories: [ HideSpawnMenu ]
+  categories: [HideSpawnMenu]
   components:
     - type: SubdermalImplant
       permanent: true
       implantAction: ActionActivateMicroBomb
     - type: TriggerOnMobstateChange
       mobState:
-      - Dead
+        - Dead
     - type: TriggerImplantAction
     - type: ExplodeOnTrigger
     - type: GibOnTrigger
@@ -245,19 +244,18 @@
         - HideContextMenu
         - MicroBomb
 
-
 - type: entity
   parent: BaseSubdermalImplant
   id: MacroBombImplant
   name: macro-bomb implant
   description: This implant creates a large explosion on death after a preprogrammed countdown.
-  categories: [ HideSpawnMenu ]
+  categories: [HideSpawnMenu]
   components:
     - type: SubdermalImplant
       permanent: true
     - type: TriggerOnMobstateChange #Chains with OnUseTimerTrigger
       mobState:
-      - Dead
+        - Dead
       preventSuicide: true
     - type: OnUseTimerTrigger
       delay: 7
@@ -286,41 +284,41 @@
   id: DeathAcidifierImplant
   name: death-acidifier implant
   description: This implant melts the user and their equipment upon death.
-  categories: [ HideSpawnMenu ]
+  categories: [HideSpawnMenu]
   components:
-  - type: SubdermalImplant
-    permanent: true
-    implantAction: ActionActivateDeathAcidifier
-  - type: TriggerOnMobstateChange
-    mobState:
-    - Dead
-  - type: TriggerImplantAction
-  - type: GibOnTrigger
-    deleteItems: true
-  - type: SpawnOnTrigger
-    proto: Acidifier
-  - type: Tag
-    tags:
-    - SubdermalImplant
-    - HideContextMenu
-    - DeathAcidifier
+    - type: SubdermalImplant
+      permanent: true
+      implantAction: ActionActivateDeathAcidifier
+    - type: TriggerOnMobstateChange
+      mobState:
+        - Dead
+    - type: TriggerImplantAction
+    - type: GibOnTrigger
+      deleteItems: true
+    - type: SpawnOnTrigger
+      proto: Acidifier
+    - type: Tag
+      tags:
+        - SubdermalImplant
+        - HideContextMenu
+        - DeathAcidifier
 
 - type: entity
   parent: BaseSubdermalImplant
   id: DeathRattleImplant
   name: death rattle implant
   description: This implant will inform the Syndicate radio channel should the user fall into critical condition or die.
-  categories: [ HideSpawnMenu ]
+  categories: [HideSpawnMenu]
   components:
     - type: SubdermalImplant
       permanent: true
       whitelist:
         components:
-        - MobState # admeme implanting a chair with rattle implant needs to give the chair mobstate so it can die first
+          - MobState # admeme implanting a chair with rattle implant needs to give the chair mobstate so it can die first
     - type: TriggerOnMobstateChange
       mobState:
-      - Critical
-      - Dead
+        - Critical
+        - Dead
     - type: Rattle
 
 - type: entity
@@ -328,11 +326,11 @@
   id: FakeMindShieldImplant
   name: fake mindshield implant
   description: This implant allows the implanter to produce a fake signal that NT security huds use to identify individuals implanted with a mindshield.
-  categories: [ HideSpawnMenu ]
+  categories: [HideSpawnMenu]
   components:
-      - type: SubdermalImplant
-        implantAction: FakeMindShieldToggleAction
-      - type: FakeMindShieldImplant
+    - type: SubdermalImplant
+      implantAction: FakeMindShieldToggleAction
+    - type: FakeMindShieldImplant
 
 # Sec and Command implants
 
@@ -341,13 +339,13 @@
   id: MindShieldImplant
   name: mindshield implant
   description: This implant will ensure loyalty to Nanotrasen and prevent mind control devices.
-  categories: [ HideSpawnMenu ]
+  categories: [HideSpawnMenu]
   components:
-   - type: SubdermalImplant
-   - type: MindShieldImplant
-   - type: Tag
-     tags:
-       - MindShield
+    - type: SubdermalImplant
+    - type: MindShieldImplant
+    - type: Tag
+      tags:
+        - MindShield
 
 # Centcomm implants
 
@@ -356,9 +354,9 @@
   id: RadioImplantCentcomm
   name: radio implant
   description: This implant grants access to the Centcomm channel without a headset. Only authorized for Centcomm employees.
-  categories: [ HideSpawnMenu ]
+  categories: [HideSpawnMenu]
   components:
-  - type: SubdermalImplant
-  - type: RadioImplant
-    radioChannels:
-    - CentCom
+    - type: SubdermalImplant
+    - type: RadioImplant
+      radioChannels:
+        - Common

+ 3 - 3
Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml

@@ -461,7 +461,7 @@
     - type: ResearchConsole
     - type: ActiveRadio
       channels:
-        - Science
+        - Common
     - type: TechnologyDatabase
     - type: ActivatableUI
       key: enum.ResearchConsoleUiKey.Key
@@ -866,7 +866,7 @@
     - type: BankClient
     - type: ActiveRadio
       channels:
-        - Supply
+        - Common
     - type: ActivatableUI
       key: enum.CargoConsoleUiKey.Orders
     - type: UserInterface
@@ -1113,7 +1113,7 @@
     - type: RoboticsConsole
     - type: ActiveRadio
       channels:
-        - Science
+        - Common
     - type: ActivatableUI
       key: enum.RoboticsConsoleUiKey.Key
     - type: UserInterface

+ 1 - 1
Resources/Prototypes/Entities/Structures/Machines/anomaly_equipment.yml

@@ -294,7 +294,7 @@
     - type: Appearance
     - type: ActiveRadio
       channels:
-        - Science
+        - Common
     - type: GenericVisualizer
       visuals:
         enum.PowerDeviceVisuals.Powered:

+ 43 - 43
Resources/Prototypes/Entities/Structures/Machines/salvage.yml

@@ -1,48 +1,48 @@
 - type: entity
-  parent: [ BaseMachinePowered, ConstructibleMachine ]
+  parent: [BaseMachinePowered, ConstructibleMachine]
   id: SalvageMagnet
   name: salvage magnet
   description: Pulls in salvage.
   components:
-  - type: Sprite
-    sprite: Structures/Machines/salvage.rsi
-    layers:
-    - state: salvage-magnet
-    - state: salvage-magnet-ready
-      visible: false
-      map: [ "ready" ]
-    - state: salvage-magnet-ready-blinking
-      visible: false
-      map: [ "readyBlinking" ]
-    - state: salvage-magnet-unready
-      visible: false
-      map: [ "unready" ]
-    - state: salvage-magnet-unready-blinking
-      visible: false
-      map: [ "unreadyBlinking" ]
-    - state: salvage-magnet-o4
-      map: ["chargeState"]
-      shader: unshaded
-  - type: ActivatableUI
-    key: enum.SalvageMagnetUiKey.Key
-  - type: ActivatableUIRequiresPower
-  - type: UserInterface
-    interfaces:
-      enum.SalvageMagnetUiKey.Key:
-        type: SalvageMagnetBoundUserInterface
-  - type: Transform
-    noRot: false
-  - type: Appearance
-  - type: Rotatable
-  - type: IntrinsicRadioReceiver
-  - type: ActiveRadio
-    channels:
-    - Supply
-  - type: SalvageMagnet
-  - type: ApcPowerReceiver
-    powerLoad: 2500 # TODO change this to a HV power draw that really hits the grid hard WHEN active
-  - type: Machine
-    board: SalvageMagnetMachineCircuitboard
+    - type: Sprite
+      sprite: Structures/Machines/salvage.rsi
+      layers:
+        - state: salvage-magnet
+        - state: salvage-magnet-ready
+          visible: false
+          map: ["ready"]
+        - state: salvage-magnet-ready-blinking
+          visible: false
+          map: ["readyBlinking"]
+        - state: salvage-magnet-unready
+          visible: false
+          map: ["unready"]
+        - state: salvage-magnet-unready-blinking
+          visible: false
+          map: ["unreadyBlinking"]
+        - state: salvage-magnet-o4
+          map: ["chargeState"]
+          shader: unshaded
+    - type: ActivatableUI
+      key: enum.SalvageMagnetUiKey.Key
+    - type: ActivatableUIRequiresPower
+    - type: UserInterface
+      interfaces:
+        enum.SalvageMagnetUiKey.Key:
+          type: SalvageMagnetBoundUserInterface
+    - type: Transform
+      noRot: false
+    - type: Appearance
+    - type: Rotatable
+    - type: IntrinsicRadioReceiver
+    - type: ActiveRadio
+      channels:
+        - Common
+    - type: SalvageMagnet
+    - type: ApcPowerReceiver
+      powerLoad: 2500 # TODO change this to a HV power draw that really hits the grid hard WHEN active
+    - type: Machine
+      board: SalvageMagnetMachineCircuitboard
 
 # For Knightship
 - type: entity
@@ -51,9 +51,9 @@
   name: salvage locator
   description: Locates salvage.
   components:
-  - type: SalvageMagnet
-  - type: ApcPowerReceiver
-    powerLoad: 1000
+    - type: SalvageMagnet
+    - type: ApcPowerReceiver
+      powerLoad: 1000
 
 - type: weightedRandomEntity
   id: RandomAsteroidPool

+ 5 - 0
Resources/Prototypes/Roles/Jobs/Civ14/TDM/english.yml

@@ -51,6 +51,7 @@
   special:
     - !type:AddComponentSpecial
       components:
+        - type: MedievalAccent
         - type: NpcFactionMember
           factions:
             - England
@@ -88,6 +89,7 @@
   special:
     - !type:AddComponentSpecial
       components:
+        - type: MedievalAccent
         - type: NpcFactionMember
           factions:
             - England
@@ -135,6 +137,7 @@
   special:
     - !type:AddComponentSpecial
       components:
+        - type: MedievalAccent
         - type: NpcFactionMember
           factions:
             - England
@@ -182,6 +185,7 @@
   special:
     - !type:AddComponentSpecial
       components:
+        - type: MedievalAccent
         - type: NpcFactionMember
           factions:
             - England
@@ -256,6 +260,7 @@
   special:
     - !type:AddComponentSpecial
       components:
+        - type: MedievalAccent
         - type: NpcFactionMember
           factions:
             - England

+ 5 - 0
Resources/Prototypes/Roles/Jobs/Civ14/TDM/french.yml

@@ -50,6 +50,7 @@
   special:
     - !type:AddComponentSpecial
       components:
+        - type: MedievalAccent
         - type: NpcFactionMember
           factions:
             - France
@@ -87,6 +88,7 @@
   special:
     - !type:AddComponentSpecial
       components:
+        - type: MedievalAccent
         - type: NpcFactionMember
           factions:
             - France
@@ -134,6 +136,7 @@
   special:
     - !type:AddComponentSpecial
       components:
+        - type: MedievalAccent
         - type: NpcFactionMember
           factions:
             - France
@@ -182,6 +185,7 @@
   special:
     - !type:AddComponentSpecial
       components:
+        - type: MedievalAccent
         - type: NpcFactionMember
           factions:
             - France
@@ -256,6 +260,7 @@
   special:
     - !type:AddComponentSpecial
       components:
+        - type: MedievalAccent
         - type: NpcFactionMember
           factions:
             - France

+ 8 - 2
Resources/Prototypes/Roles/Jobs/Civ14/TDM/sovietCW.yml

@@ -22,7 +22,6 @@
           factionIcon: SovietFaction
           jobIcon: JobIconICpt
           assignSquad: false
-
 - type: playTimeTracker
   id: JobSovietCWCaptain
 
@@ -37,6 +36,7 @@
     pocket2: civ13_magazine_PM_Makarov_magazine_(9x18mm)
     head: civ13_head_soviet_officer_cap
     pocket1: Compass
+    ears: ClothingHeadsetSoviet
 
 # Sergeant
 
@@ -78,6 +78,7 @@
     belt: civ13_pistol_Makarov_PM
     pocket1: civ13_magazine_PM_Makarov_magazine_(9x18mm)
     pocket2: Compass
+    ears: ClothingHeadsetSoviet
   inhand:
     - civ13_ar_AK_74
 
@@ -119,6 +120,7 @@
     belt: ClothingWebbingSovietCWRifleman
     pocket1: FlashlightLanternMilitary
     pocket2: Gauze
+    ears: ClothingHeadsetSoviet
   inhand:
     - civ13_ar_AK_74
 
@@ -133,6 +135,7 @@
     head: civ13_head_soviet_helmet
     pocket1: FlashlightLanternMilitary
     pocket2: Gauze
+    ears: ClothingHeadsetSoviet
   inhand:
     - civ13_ar_AK_74
 
@@ -158,7 +161,7 @@
             - SovietCW
         - type: ShowFactionIcons
           factionIcon: SovietFaction
-          jobIcon: JobIconMG
+          jobIcon: JobIconMg
           assignSquad: true
 
 - type: playTimeTracker
@@ -175,6 +178,7 @@
     head: civ13_head_soviet_helmet
     pocket1: CombatKnife
     pocket2: Gauze
+    ears: ClothingHeadsetSoviet
   inhand:
     - civ13_mg_RPD_machine_gun
 
@@ -189,6 +193,7 @@
     head: civ13_head_soviet_ushanka_1
     pocket1: CombatKnife
     pocket2: Gauze
+    ears: ClothingHeadsetSoviet
   inhand:
     - civ13_mg_RPD_machine_gun
 
@@ -230,5 +235,6 @@
     back: ClothingBackpackDuffelFilled
     pocket1: FlashlightLanternMilitary
     pocket2: civ13_magazine_AK_74_magazine_(5.45x39mm)
+    ears: ClothingHeadsetSoviet
   inhand:
     - civ13_ar_AK_74

+ 7 - 0
Resources/Prototypes/Roles/Jobs/Civ14/TDM/usa.yml

@@ -34,6 +34,7 @@
     belt: civ13_pistol_M1911A1
     pocket1: civ13_magazine_M1911_magazine_(.45)
     pocket2: Compass
+    ears: ClothingHeadsetUS
 
 # Sergeant
 
@@ -74,6 +75,7 @@
     belt: civ13_pistol_M1911A1
     pocket1: civ13_magazine_M1911_magazine_(.45)
     pocket2: Compass
+    ears: ClothingHeadsetUS
   inhand:
     - civ13_ar_M16A2
 
@@ -114,6 +116,7 @@
     neck: civ13_accessory_woodland_PASGT_body_armor
     pocket1: Gauze
     pocket2: Gauze
+    ears: ClothingHeadsetUS
   inhand:
     - civ13_ar_M16A2
 
@@ -127,6 +130,7 @@
     neck: civ13_accessory_woodland_PASGT_body_armor
     pocket1: Gauze
     pocket2: Gauze
+    ears: ClothingHeadsetUS
   inhand:
     - civ13_ar_M16A2
 
@@ -167,6 +171,7 @@
     neck: civ13_accessory_woodland_PASGT_body_armor
     pocket1: CombatKnife
     pocket2: Gauze
+    ears: ClothingHeadsetUS
   inhand:
     - civ13_mg_M60
 
@@ -180,6 +185,7 @@
     neck: civ13_accessory_woodland_PASGT_body_armor
     pocket1: CombatKnife
     pocket2: Gauze
+    ears: ClothingHeadsetUS
   inhand:
     - civ13_mg_M60
 
@@ -218,5 +224,6 @@
     back: ClothingBackpackDuffelFilled
     neck: civ13_accessory_woodland_PASGT_body_armor
     pocket1: CombatKnife
+    ears: ClothingHeadsetUS
   inhand:
     - civ13_ar_M16A2

+ 0 - 8
Resources/Prototypes/XenoArch/Effects/utility_effects.yml

@@ -18,14 +18,6 @@
       requiresPower: false
       supportedChannels:
         - Common
-        - CentCom
-        - Command
-        - Engineering
-        - Medical
-        - Science
-        - Security
-        - Service
-        - Supply
 
 - type: artifactEffect
   id: EffectRandomInstrument

+ 39 - 49
Resources/Prototypes/borg_types.yml

@@ -9,14 +9,14 @@
   extraModuleCount: 5
   moduleWhitelist:
     tags:
-    - BorgModuleGeneric
-    - BorgModuleScience #until sciborgs are added
+      - BorgModuleGeneric
+      - BorgModuleScience #until sciborgs are added
 
   defaultModules:
-  - BorgModuleTool
+    - BorgModuleTool
 
   radioChannels:
-  - Science
+    - Common
 
   # Visual
   inventoryTemplateId: borgShort
@@ -29,7 +29,6 @@
   petSuccessString: petting-success-generic-cyborg
   petFailureString: petting-failure-generic-cyborg
 
-
 # Engineering borg
 - type: borgType
   id: engineering
@@ -41,18 +40,17 @@
   extraModuleCount: 3
   moduleWhitelist:
     tags:
-    - BorgModuleGeneric
-    - BorgModuleEngineering
+      - BorgModuleGeneric
+      - BorgModuleEngineering
 
   defaultModules:
-  - BorgModuleTool
-  - BorgModuleConstruction
-  - BorgModuleRCD
-  - BorgModuleCable
+    - BorgModuleTool
+    - BorgModuleConstruction
+    - BorgModuleRCD
+    - BorgModuleCable
 
   radioChannels:
-  - Engineering
-  - Science
+    - Common
 
   # Visual
   inventoryTemplateId: borgShort
@@ -65,7 +63,6 @@
   petSuccessString: petting-success-engineer-cyborg
   petFailureString: petting-failure-engineer-cyborg
 
-
 # Salvage borg
 - type: borgType
   id: mining
@@ -77,17 +74,16 @@
   extraModuleCount: 3
   moduleWhitelist:
     tags:
-    - BorgModuleGeneric
-    - BorgModuleCargo
+      - BorgModuleGeneric
+      - BorgModuleCargo
 
   defaultModules:
-  - BorgModuleGrapplingGun
-  - BorgModuleMining
-  - BorgModuleAppraisal
+    - BorgModuleGrapplingGun
+    - BorgModuleMining
+    - BorgModuleAppraisal
 
   radioChannels:
-  - Supply
-  - Science
+    - Common
 
   # Visual
   inventoryTemplateId: borgTall
@@ -101,7 +97,6 @@
   petSuccessString: petting-success-salvage-cyborg
   petFailureString: petting-failure-salvage-cyborg
 
-
 # Janitor borg
 - type: borgType
   id: janitor
@@ -113,16 +108,15 @@
   extraModuleCount: 3
   moduleWhitelist:
     tags:
-    - BorgModuleGeneric
-    - BorgModuleJanitor
+      - BorgModuleGeneric
+      - BorgModuleJanitor
 
   defaultModules:
-  - BorgModuleLightReplacer
-  - BorgModuleCleaning
+    - BorgModuleLightReplacer
+    - BorgModuleCleaning
 
   radioChannels:
-  - Science
-  - Service
+    - Common
 
   # Visual
   inventoryTemplateId: borgShort
@@ -136,7 +130,6 @@
   petSuccessString: petting-success-janitor-cyborg
   petFailureString: petting-failure-janitor-cyborg
 
-
 # Medical borg
 - type: borgType
   id: medical
@@ -148,24 +141,23 @@
   extraModuleCount: 3
   moduleWhitelist:
     tags:
-    - BorgModuleGeneric
-    - BorgModuleMedical
+      - BorgModuleGeneric
+      - BorgModuleMedical
 
   defaultModules:
-  - BorgModuleTreatment
+    - BorgModuleTreatment
 
   radioChannels:
-  - Science
-  - Medical
+    - Common
 
   addComponents:
-  - type: SolutionScanner
-  - type: ShowHealthBars
-    damageContainers:
-    - Biological
-  - type: ShowHealthIcons
-    damageContainers:
-    - Biological
+    - type: SolutionScanner
+    - type: ShowHealthBars
+      damageContainers:
+        - Biological
+    - type: ShowHealthIcons
+      damageContainers:
+        - Biological
 
   # Visual
   inventoryTemplateId: borgDutch
@@ -183,7 +175,6 @@
   footstepCollection:
     collection: FootstepHoverBorg
 
-
 # Service borg
 - type: borgType
   id: service
@@ -195,17 +186,16 @@
   extraModuleCount: 3
   moduleWhitelist:
     tags:
-    - BorgModuleGeneric
-    - BorgModuleService
+      - BorgModuleGeneric
+      - BorgModuleService
 
   defaultModules:
-  - BorgModuleMusique
-  - BorgModuleService
-  - BorgModuleClowning
+    - BorgModuleMusique
+    - BorgModuleService
+    - BorgModuleClowning
 
   radioChannels:
-  - Science
-  - Service
+    - Common
 
   # Visual
   inventoryTemplateId: borgTall

+ 2 - 67
Resources/Prototypes/radio_channels.yml

@@ -5,71 +5,6 @@
   frequency: 1459
   color: "#2cdb2c"
 
-- type: radioChannel
-  id: CentCom
-  name: chat-radio-centcom
-  keycode: 'y'
-  frequency: 1337
-  color: "#2681a5"
-  longRange: true
-
-- type: radioChannel
-  id: Command
-  name: chat-radio-command
-  keycode: 'c'
-  frequency: 1353
-  color: "#fcdf03"
-
-- type: radioChannel
-  id: Engineering
-  name: chat-radio-engineering
-  keycode: 'e'
-  frequency: 1357
-  color: "#ff733c"
-
-- type: radioChannel
-  id: Medical
-  name: chat-radio-medical
-  keycode: 'm'
-  frequency: 1355
-  color: "#57b8f0"
-
-- type: radioChannel
-  id: Science
-  name: chat-radio-science
-  keycode: 'n'
-  frequency: 1351
-  color: "#cd7ccd"
-
-- type: radioChannel
-  id: Security
-  name: chat-radio-security
-  keycode: 's'
-  frequency: 1359
-  color: "#ff4242"
-
-- type: radioChannel
-  id: Service
-  name: chat-radio-service
-  keycode: 'v'
-  frequency: 1349
-  color: "#539c00"
-
-- type: radioChannel
-  id: Supply
-  name: chat-radio-supply
-  keycode: 'u'
-  frequency: 1347
-  color: "#b48b57"
-
-- type: radioChannel
-  id: Syndicate
-  name: chat-radio-syndicate
-  keycode: 't'
-  frequency: 1213
-  color: "#8f4a4b"
-  longRange: true
-
 - type: radioChannel
   id: Handheld
   name: chat-radio-handheld
@@ -81,7 +16,7 @@
 - type: radioChannel
   id: Binary
   name: chat-radio-binary
-  keycode: 'b'
+  keycode: "b"
   frequency: 1001
   color: "#5ed7aa"
   # long range since otherwise it'd defeat the point of a handheld radio independent of telecomms
@@ -90,7 +25,7 @@
 - type: radioChannel
   id: Freelance
   name: chat-radio-freelance
-  keycode: 'f'
+  keycode: "f"
   frequency: 1984
   color: "#f6ce64"
   # long range since otherwise it'd defeat the point of a handheld radio independent of telecomms

+ 5 - 5
Resources/ServerInfo/Guidebook/NewPlayer/Controls/Radio.xml

@@ -33,7 +33,7 @@ You are able to send messages over your departmental radio channels using [color
 Examine your headset to see the department channels available to you.
 
 <Box>
-  <GuideEntityEmbed Entity="ClothingHeadsetEngineering"/>
+  <GuideEntityEmbed Entity="ClothingHeadsetCargo"/>
 </Box>
 
 Examining an unmodified engineering headset would show you the prefixes for the [color=#32cd32]Common[/color] and [color=#f37746]Engineering[/color] channels.
@@ -43,14 +43,14 @@ For example, if you're a Station Engineer then [color=#a4885c]:h[/color] will de
 
 ## Encryption Keys
 [color=#a4885c]Encryption keys[/color] give you access to their respective channel.
-  
+
 Examining our engineering headset from earlier shows us [color=#32cd32]Common[/color] and [color=#f37746]Engineering[/color] because an engineer's headset starts with those [color=#a4885c]encryption keys[/color].
-  
+
 <Box>
   <GuideEntityEmbed Entity="EncryptionKeyCommon"/>
-  <GuideEntityEmbed Entity="EncryptionKeyEngineering"/>
+  <GuideEntityEmbed Entity="EncryptionKeySoviet"/>
 </Box>
-  
+
 You can take out encryption keys by using a [color=#a4885c]screwdriver[/color] on a headset. New encryption keys are put into headsets by clicking on one with an encryption key in your hand.
 
 All command members have extras of their relevant encryption key, but you can also request one at the HoP's office when you're getting your job changed.

BIN
Resources/Textures/Civ14/Weapons/Guns/rpd_mag.rsi/mag-0.png → Resources/Textures/Civ14/Objects/headset.rsi/equipped-EARS.png


BIN
Resources/Textures/Civ14/Objects/headset.rsi/icon.png


+ 18 - 0
Resources/Textures/Civ14/Objects/headset.rsi/meta.json

@@ -0,0 +1,18 @@
+{
+    "version": 1,
+    "license": "AGPLv3",
+    "copyright": "Taken from Civilization 13 https://github.com/civ13/civ13",
+    "size": {
+        "x": 32,
+        "y": 32
+    },
+    "states": [
+        {
+            "name": "icon"
+        },
+        {
+            "name": "equipped-EARS",
+            "directions": 4
+        }
+    ]
+}

BIN
Resources/Textures/Civ14/Weapons/Guns/m60.rsi/mag-0.png


BIN
Resources/Textures/Civ14/Weapons/Guns/m60_mag.rsi/bolt-open.png


BIN
Resources/Textures/Civ14/Weapons/Guns/m60_mag.rsi/icon.png


BIN
Resources/Textures/Civ14/Weapons/Guns/m60_mag.rsi/m60_mag.png


BIN
Resources/Textures/Civ14/Weapons/Guns/m60_mag.rsi/mag-0.png


+ 0 - 27
Resources/Textures/Civ14/Weapons/Guns/m60_mag.rsi/meta.json

@@ -1,27 +0,0 @@
-{
-  "version": 1,
-  "license": "AGPL-3.0",
-  "copyright": "Exported from https://github.com/civ13/civ13",
-  "size": {
-    "x": 32,
-    "y": 32
-  },
-  "states": [
-    {
-      "name": "mag-0",
-      "directions": 1
-    },
-    {
-      "name": "icon",
-      "directions": 1
-    },
-    {
-      "name": "m60_mag",
-      "directions": 1
-    },
-    {
-      "name": "bolt-open",
-      "directions": 1
-    }
-  ]
-}

BIN
Resources/Textures/Civ14/Weapons/Guns/rpd.rsi/mag-0.png


BIN
Resources/Textures/Civ14/Weapons/Guns/rpd_mag.rsi/bolt-open.png


BIN
Resources/Textures/Civ14/Weapons/Guns/rpd_mag.rsi/icon.png


+ 0 - 27
Resources/Textures/Civ14/Weapons/Guns/rpd_mag.rsi/meta.json

@@ -1,27 +0,0 @@
-{
-  "version": 1,
-  "license": "AGPL-3.0",
-  "copyright": "Exported from https://github.com/civ13/civ13",
-  "size": {
-    "x": 32,
-    "y": 32
-  },
-  "states": [
-    {
-      "name": "mag-0",
-      "directions": 1
-    },
-    {
-      "name": "icon",
-      "directions": 1
-    },
-    {
-      "name": "rpd_mag",
-      "directions": 1
-    },
-    {
-      "name": "bolt-open",
-      "directions": 1
-    }
-  ]
-}

BIN
Resources/Textures/Civ14/Weapons/Guns/rpd_mag.rsi/rpd_mag.png