Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Syringe gun! #1018

Merged
merged 3 commits into from
Jan 25, 2025
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,10 @@ public abstract partial class BaseSolutionInjectOnEventComponent : Component
/// </summary>
[DataField]
public SlotFlags BlockSlots = SlotFlags.NONE;

/// <summary>
/// GoobStation: If this injection transfers EVERYTHING as soon as it is embedded after a gunshot.
/// </summary>
[DataField]
public bool Shot = false;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Content.Server.Body.Components;
using Content.Server.Body.Systems;
using Content.Server.Chemistry.Components;
using Content.Shared.Chemistry.Components; // GoobStation
using Content.Shared.Chemistry.EntitySystems;
using Content.Shared.Chemistry.Events;
using Content.Shared.Inventory;
Expand Down Expand Up @@ -40,6 +41,11 @@ private void HandleProjectileHit(Entity<SolutionInjectOnProjectileHitComponent>

private void HandleEmbed(Entity<SolutionInjectOnEmbedComponent> entity, ref EmbedEvent args)
{
// GoobStation Change Start
if (_tag.HasTag(entity, "Syringe") && !entity.Comp.Shot)
entity.Comp.PierceArmor = false; // This way syringes that are thrown still inject but do not pierce armor.
// GoobStation Change End

DoInjection((entity.Owner, entity.Comp), args.Embedded, args.Shooter);
}

Expand Down Expand Up @@ -95,6 +101,7 @@ private bool TryInjectTargets(Entity<BaseSolutionInjectOnEventComponent> injecto
// TODO blocking injection with a hardsuit should probably done with a cancellable event or something
if (!injector.Comp.PierceArmor && _inventory.TryGetSlotEntity(target, "outerClothing", out var suit) && _tag.HasTag(suit.Value, "Hardsuit"))
{
injector.Comp.Shot = false;
// Only show popup to attacker
if (source != null)
_popup.PopupEntity(Loc.GetString(injector.Comp.BlockedByHardsuitPopupMessage, ("weapon", injector.Owner), ("target", target)), target, source.Value, PopupType.SmallCaution);
Expand Down Expand Up @@ -132,8 +139,16 @@ private bool TryInjectTargets(Entity<BaseSolutionInjectOnEventComponent> injecto
if (targetBloodstreams.Count == 0)
return false;

// Extract total needed solution from the injector
var removedSolution = _solutionContainer.SplitSolution(injectorSolution.Value, injector.Comp.TransferAmount * targetBloodstreams.Count);
// GoobStation Change Start
Solution removedSolution;
if (injector.Comp.Shot)
{
removedSolution = _solutionContainer.SplitSolution(injectorSolution.Value, injectorSolution.Value.Comp.Solution.Volume);
injector.Comp.Shot = false; // Prevent them from abusing this.
}
else
removedSolution = _solutionContainer.SplitSolution(injectorSolution.Value, injector.Comp.TransferAmount * targetBloodstreams.Count);
// GoobStation Change End
// Adjust solution amount based on transfer efficiency
var solutionToInject = removedSolution.SplitSolution(removedSolution.Volume * injector.Comp.TransferEfficiency);
// Calculate how much of the adjusted solution each target will get
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ public sealed class SolutionInjectWhileEmbeddedSystem : EntitySystem
public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<SolutionInjectWhileEmbeddedComponent, MapInitEvent>(OnMapInit);
}

Expand Down
2 changes: 1 addition & 1 deletion Content.Server/Weapons/Ranged/Systems/GunSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public override void Shoot(EntityUid gunUid, GunComponent gun, List<(EntityUid?

RaiseLocalEvent(ent!.Value, new AmmoShotEvent()
{
FiredProjectiles = shotProjectiles,
FiredProjectiles = shotProjectiles
});

SetCartridgeSpent(ent.Value, cartridge, true);
Expand Down
27 changes: 27 additions & 0 deletions Content.Server/_Goobstation/Weapons/Ranged/SyringeGunSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using Content.Server.Chemistry.Components;
using Content.Shared.Weapons.Ranged.Events;
using Content.Shared._Goobstation.Weapons.Ranged;
namespace Content.Server._Goobstation.Weapons.Ranged;

/// <summary>
/// System for handling projectiles and altering their properties when fired from a Syringe Gun.
/// </summary>
public sealed class SyringeGunSystem : EntitySystem
{

public override void Initialize()
{
SubscribeLocalEvent<SyringeGunComponent, AmmoShotEvent>(OnFire);
}

private void OnFire(Entity<SyringeGunComponent> gun, ref AmmoShotEvent args)
{
foreach (var projectile in args.FiredProjectiles)
if (TryComp(projectile, out SolutionInjectOnEmbedComponent? inject))
{
inject.Shot = true;
inject.PierceArmor = gun.Comp.PierceArmor;
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Robust.Shared.GameStates;

namespace Content.Shared._Goobstation.Weapons.Ranged;

/// <summary>
/// Component that allows guns to instantly inject all the contents of any syringe on a target.
/// </summary>
[RegisterComponent]
public sealed partial class SyringeGunComponent : Component
{
[DataField]
public bool PierceArmor;
}
3 changes: 3 additions & 0 deletions Resources/Locale/en-US/store/uplink-catalog.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,9 @@ uplink-decoy-kit-desc = State-of-the-art distraction technology straight from RN
uplink-chemistry-kit-name = Chemical Synthesis Kit
uplink-chemistry-kit-desc = A starter kit for the aspiring chemist, includes toxin and vestine for all your criminal needs!

uplink-dart-syringe-gun-name = Dart Syringe Gun
uplink-dart-syringe-gun-desc = A gun that takes in syringes as ammunition, and injects their contents on its victims. Can pierce through armor.

uplink-knives-kit-name = Throwing Knives Kit
uplink-knives-kit-desc = A set of 4 syndicate branded throwing knives, perfect for embedding into the body of your victims.

Expand Down
6 changes: 6 additions & 0 deletions Resources/Locale/ru-RU/backmen/entities/syringe_gun.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
ent-DartSyringeGun = дротиковый шприцемёт
.desc = Нелегально модифицированная версия шприцемёта которая позволяет пробивать броню.
ent-SyringeGun = шприцемёт
.desc = Девайс, позволяющий выстреливать шприцами и моментально вводить их содержимое в цель.
ent-RapidSyringeGun = улучшенный шприцемёт
.desc = Улучшенная версия шприцемёта с более быстрой скорострельностью и большой вместимостью шприцов.
1 change: 1 addition & 0 deletions Resources/Locale/ru-RU/backmen/research/technologies.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ research-technology-metempsychosis = Метемпсихоз
research-technology-navigation = Навигация
research-technology-psionic-countermeasures = Псионические контрмеры
research-technology-teleportation = Телепортация
research-technology-medical-defense = Экстремальные методы контроля
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,6 @@ ent-SyringeRomerol = { ent-PrefilledSyringe }
ent-SyringeStimulants = { ent-PrefilledSyringe }
.desc = { ent-PrefilledSyringe.desc }
.suffix = Стимулятор
ent-SyringePax = { ent-PrefilledSyringe }
.desc = { ent-PrefilledSyringe.desc }
.suffix = Пакс
2 changes: 2 additions & 0 deletions Resources/Prototypes/Catalog/Fills/Lockers/heads.yml
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,8 @@
- id: FlatpackMetempsychoticMachine # backmen
- id: MedicalBiofabMachineBoard # backmen
- id: MedTekCartridge
- id: RapidSyringeGun # backmen
- id: BoxSyringePax # backmen

# Hardsuit table, used for suit storage as well
- type: entityTable
Expand Down
40 changes: 38 additions & 2 deletions Resources/Prototypes/Entities/Objects/Specific/chemistry.yml
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,40 @@
maxVol: 15
- type: Injector
injectOnly: false
# GoobStation Start - Added embeddable properties for syringe gun
- type: EmbeddableProjectile
offset: "-0.1,0"
minimumSpeed: 3
removalTime: 0.25
embedOnThrow: true
- type: SolutionInjectOnEmbed
transferAmount: 2
solution: injector
- type: Fixtures
fixtures:
fix1:
shape: !type:PhysShapeCircle
radius: 0.2
density: 5
mask:
- ItemMask
restitution: 0.3
friction: 0.2
projectile:
shape:
!type:PhysShapeAabb
bounds: "-0.1,-0.3,0.1,0.3"
hard: false
mask:
- Impassable
- BulletImpassable
- type: Projectile
deleteOnCollide: false
onlyCollideWhenShot: true
damage:
types:
Piercing: 5
# GoobStation End
- type: ExaminableSolution
solution: injector
- type: Spillable
Expand All @@ -374,6 +408,7 @@
- type: Tag
tags:
- Syringe
- SyringeGunAmmo # GoobStation
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Обнаружена проблема с тегом SyringeGunAmmo

Тег SyringeGunAmmo добавлен к сущностям, но отсутствует проверка этого тега в системе шприц-пистолета (SyringeGunSystem). Это может привести к тому, что шприц-пистолет будет принимать неправильные типы боеприпасов.

  • Добавьте проверку тега SyringeGunAmmo в Content.Server/_Goobstation/Weapons/Ranged/SyringeGunSystem.cs
  • Или используйте существующую систему валидации боеприпасов из базового класса GunSystem
🔗 Analysis chain

Проверьте использование тега SyringeGunAmmo

Тег SyringeGunAmmo добавлен к базовым сущностям шприцев. Убедитесь, что система шприц-пистолета корректно фильтрует боеприпасы по этому тегу.

Also applies to: 424-424

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Поиск использования тега SyringeGunAmmo в системах
rg -l "SyringeGunAmmo" --type cs

Length of output: 32


Script:

#!/bin/bash
# Поиск тега во всех файлах
echo "=== Searching for SyringeGunAmmo in all files ==="
rg "SyringeGunAmmo" -l

# Поиск файлов, связанных со шприц-пистолетом
echo -e "\n=== Searching for syringe gun related files ==="
rg -l -i "syringe.*gun|gun.*syringe"

# Поиск систем оружия и боеприпасов
echo -e "\n=== Searching for weapon/ammo systems ==="
fd -e cs -e yml ".*[Gg]un.*System|.*[Aa]mmo.*System|.*[Ww]eapon.*System"

Length of output: 5104


Script:

#!/bin/bash
# Проверка содержимого системы шприц-пистолета
echo "=== SyringeGunSystem implementation ==="
ast-grep --pattern 'class SyringeGunSystem {
  $$$
}'

# Проверка определения тега
echo -e "\n=== Tag definition ==="
rg "SyringeGunAmmo" Resources/Prototypes/tags.yml -C 2

Length of output: 307


Script:

#!/bin/bash
# Проверка реализации системы шприц-пистолета
echo "=== SyringeGunSystem content ==="
rg -A 10 "SyringeGunSystem" Content.Server/_Goobstation/Weapons/Ranged/SyringeGunSystem.cs

# Поиск проверок тегов в файле
echo -e "\n=== Tag checks in system ==="
rg "HasTag|EnsureTag" Content.Server/_Goobstation/Weapons/Ranged/SyringeGunSystem.cs

Length of output: 649


Script:

#!/bin/bash
# Проверка компонента шприц-пистолета
echo "=== SyringeGunComponent content ==="
rg -A 10 "SyringeGunComponent" Content.Shared/_Goobstation/Weapons/Ranged/SyringeGunComponent.cs

# Поиск использования тега в базовой системе оружия
echo -e "\n=== Gun system tag checks ==="
rg "SyringeGunAmmo" Content.Server/Weapons/Ranged/Systems/GunSystem.cs Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs

Length of output: 489


- type: entity
parent: BaseSyringe
Expand All @@ -386,6 +421,7 @@
tags:
- Syringe
- Trash
- SyringeGunAmmo # GoobStation

- type: entity
name: mini syringe
Expand All @@ -409,7 +445,7 @@
offset: "-0.1,0"
minimumSpeed: 3
removalTime: 0.25
embedOnThrow: false
embedOnThrow: true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Исправьте дублирование конфигурации

В сущности MiniSyringe дублируются параметры EmbeddableProjectile из родительской сущности BaseSyringe. Рекомендуется удалить дублирование.

  - type: EmbeddableProjectile
-   offset: "-0.1,0"
-   minimumSpeed: 3
-   removalTime: 0.25
    embedOnThrow: true

Committable suggestion skipped: line range outside the PR's diff.

- type: SolutionInjectWhileEmbedded
transferAmount: 1
solution: injector
Expand Down Expand Up @@ -589,7 +625,7 @@
areaInsertRadius: 1
storageInsertSound: /Audio/Effects/pill_insert.ogg
storageRemoveSound: /Audio/Effects/pill_remove.ogg
whitelist:
whitelist:
tags:
- Pill
- type: Dumpable
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@
containers:
storagebase: !type:Container
ents: []

- type: entity
name: syringe gun
parent: BaseStorageItem
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,7 @@
- WeaponFlareGunSecurity
- WeaponLaserCarbinePractice
- Zipties
- SyringeGun #Goobstation
dynamicRecipes:
- BoxBeanbag
- BoxShotgunIncendiary
Expand Down Expand Up @@ -842,6 +843,7 @@
- ClothingHeadHelmetInsulated
- ShellSoulbreaker
- WeaponXrayCannon
- RapidSyringeGun # Goobstation
- SecurityCyberneticEyes # Shitmed Change
- MedicalCyberneticEyes # Shitmed Change
- type: MaterialStorage
Expand Down Expand Up @@ -963,19 +965,22 @@
- Hemostat
- ClothingEyesGlassesChemical
- WhiteCane
- SyringeGun # backmen
dynamicRecipes:
- ChemicalPayload
- CryostasisBeaker
- BluespaceBeaker
- SyringeBluespace
- SyringeCryostasis
- BluespacePillCanister # backmen
# Shitmed Change
- RapidSyringeGun # backmen
# Shitmed Change start
- EnergyScalpel
- EnergyCautery
- AdvancedRetractor
- OmnimedTool
- MedicalCyberneticEyes
# Shitmed Change end
- type: Machine
board: MedicalTechFabCircuitboard
- type: StealTarget
Expand Down
13 changes: 13 additions & 0 deletions Resources/Prototypes/Research/civilianservices.yml
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,19 @@
recipeUnlocks:
- CargoTelepadMachineCircuitboard

# GoobStation - Why civilian? Because fuck you.
- type: technology
id: MedicalDefense
name: research-technology-medical-defense
icon:
sprite: _Goobstation/Objects/Weapons/Guns/Cannons/syringe_gun.rsi
state: rapid-syringe-gun
discipline: CivilianServices
tier: 2
cost: 10000
recipeUnlocks:
- RapidSyringeGun

# Tier 3

- type: technology
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
equipment:
id: CMOPDA
ears: ClothingHeadsetCMO
belt: ClothingBeltMedicalFilled
belt: ClothingBeltMilitaryWebbingCMOFilled # Goobstation
storage:
back:
- Flash
19 changes: 19 additions & 0 deletions Resources/Prototypes/_Backmen/Catalog/uplink_catalog.yml
Original file line number Diff line number Diff line change
Expand Up @@ -162,3 +162,22 @@
Telecrystal: 10
categories:
- UplinkDeception

- type: listing
id: UplinkDartSyringeGun
name: uplink-dart-syringe-gun-name
description: uplink-dart-syringe-gun-desc
icon: { sprite: /Textures/_Goobstation/Objects/Weapons/Guns/Cannons/syringe_gun.rsi, state: dart-syringe-gun }
productEntity: DartSyringeGun
cost:
Telecrystal: 30 # goob
categories:
- UplinkChemicals
conditions:
- !type:BuyerJobCondition
whitelist:
- MedicalDoctor
- MedicalIntern
- Psychologist
- Chemist
- Paramedic
Loading
Loading