Skip to content

Shotguns reheated #3278

Open
Raizlen wants to merge 4 commits into
BlueMoon-Labs:masterfrom
Raizlen:Shotguns-Reheated-
Open

Shotguns reheated #3278
Raizlen wants to merge 4 commits into
BlueMoon-Labs:masterfrom
Raizlen:Shotguns-Reheated-

Conversation

@Raizlen

@Raizlen Raizlen commented May 28, 2026

Copy link
Copy Markdown

Описание

Небольшое контентное и техническое обновление, связанное с переписыванием легасикода.
Улучшение базовых дробовиков, предметов связанных с ними. Механика осечек, новое оружие
Открытый тред для обсуждения: https://discord.com/channels/875735187449847830/1496434065589534792.

  • [+] Изменения были проверены на локальном сервере
  • [-] Этот пулл-реквест готов к тест-мерджу.
  • [-] Изменения были портированы с другого сервера

Причина изменений

Улучшение импакта от класса оружия, его пересмотр в нынешней мете и улучшения. Полная замена спрайтов и звуков.

Демонстрация изменений

Changelog

🆑
add: Новое оружие:
CS-9 "Bastion" (карго) - Дробовик 12 калибра с двумя трубками-магазинами. Alt+Click чтобы сменить трубку.
Aegis-12 "Teta" (Набор запчастей, достаётся из рнд) - Двуствольный помповый дробовик.
HCA-00 "Invictus" (Нюка) - Улучшенная версия Aegis-12, оснащённая альтернативным режимом: Залп из двух стволов одновременно.
Model 156-C - Старое, но быстро стреляющее и капризное ружьё. Alt+Click - режим ускоренной стрельбы.
M156 "Hell-Stitch" (Нюка) - Кастомная версия 156-C с встроенным штык-ножом.
CS-11 "JackHammer" (Нюка) - Крепящийся на пояс инструмент для быстрого вскрытия дверей. Идёт в комплекте с бричер-патронами.
HC-X "Aspis" (Трейтор) - Полуавтоматический обрез, идущий в комплекте с глушителем. Быстро стреляющий, дешёвый вариант для заказных убийц. Помещается в сумку.
add: Новые эмоции и мудл, связанные с M156 "Hell-Stitch".
add: Механика осечек для трубчатых дробовиков.
add: Новые звуки выстрелов, взаимодействия с оружием, гильз.
add: Новые наборы связанные с оружием в карго.
add: Переписано поведение обоих типов дробовиков. Добавлено покачивание экрана при взаимодействии с оружием.
qol: Теперь можно посмотреть, поддерживается ли глушитель или штык-нож прямо в описании предмета.
qol: Описания дробовиков, патронов 12 калибра теперь на русском.
balance: Полный ребаланс боеприпасов, баллистики и всё что связанно с 12 калибром.
balance: Частичный пересмотр цен в аплинке и карго.
fix: Теперь патроны 12 калибра звучат по-другому, но на них всё ещё влияет поверхность
fix: Дробовики теперь имеют отдельные звуки взвода, зарядки патрона внутрь.
fix: Поведение глушителей и штык-ножей приведено к рабочему состоянию. Теперь оружие может поддерживать оба варианта одновременно, не конфликтуя друг с другом.
fix: Переписано поведение гильз. Теперь есть возможность задать собственный звук гильзы, включая звуковой банк.
balance: Полный ребаланс дробовиков.
sound: Добавлены звуковые пакеты для эмоций.
sound: Добавлены звуковые пакеты для дробовиков всех типов, исключая полуавтоматические.
image: Переделаны спрайты помповых дробовиков, включая скины.
map: Новый контент доступен в гейтах, заместо классических пушек.
code: Часть легасикода, связанный с механиками глушителей и гильз был освежён. Детальные описания выше^
/:cl:

Summary by CodeRabbit

Изменения в выпуске

  • Новые функции

    • Добавлены новые варианты дробовиков: DP12, сламфаер с модификациями
    • Введена система заклинивания и стресса для дробовиков
    • Добавлен лазерный штык-нож с механикой парирования
    • Новые наборы снабжения для арсенала и безопасности
    • Добавлены новые звуковые эмоуты для людей
  • Балансировка

    • Перебалансированы уроны боеприпасов для дробовиков
    • Обновлены характеристики различных типов дробовых патронов
  • Исправления

    • Улучшена система звуков отскока снарядов
    • Оптимизирована работа глушителей на оружии

Review Change Stack

Raizlen added 4 commits May 13, 2026 19:26
Добавление кода, предметов и реворков на стабильную ветку билда
Добавлены эмоции, связанные с трейторовским дробовиком. Добавлен новый патрон, улучшена структура предметов overall. Система осечек работает теперь корректно
СУЩЕСТВУЮЩИЕ БАГИ:
Спрайты оружия пропадают при установке глушителя.
@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown

Walkthrough

PR перерабатывает систему дробовиков и звуков отскока снарядов: заменяет bullet_bounce_sound на override_shell_bounce_sound во всех турфах, добавляет jam/stress механику для дробовиков, вводит новые варианты оружия (dp12, slamfire/traitor с frenzy системой), расширяет систему аксессуаров оружия, добавляет новый контент (supply packs, uplink items) и обновляет карты.

Changes

Shotgun Overhaul: Jam System, Variants, and Audio Feedback

Layer / File(s) Summary
Turf shell bounce sound refactoring
code/game/turfs/turf.dm, code/game/turfs/*/*.dm, code/modules/holodeck/turfs.dm, code/modules/mapping/preloader.dm, modular_*/code/game/turfs/*
25+ типов турфов получают новое поле override_shell_bounce_sound вместо bullet_bounce_sound для единообразного управления звуком рикошета снарядов.
Ammunition system: shell bounce sound delegation
code/modules/projectiles/ammunition/_ammunition.dm, code/modules/projectiles/ammunition/ballistic/shotgun.dm
Гильзы получают shell_bounce_sound и shell_bounce_sounds с методом get_shell_bounce_sound(), bounce_away() переписана для использования override_shell_bounce_sound из турфа с приоритетом над внутренними звуками. Дробовые гильзы получают калибр и список звуков отскока. Добавлен новый тип shotgun_breacher для специальной механики пробития.
Gun base system: suppressor and bayonet attachment
code/modules/projectiles/gun.dm
Введены default_fire_sound, suppressed_fire_sound, флаги ignore_twohand_requirement и can_mount_both, методы can_attach_suppressor() и can_attach_bayonet() для проверки совместимости аксессуаров, обновлена логика двухрукости и переписана система установки штыка с разными сообщениями об ошибках.
Ballistic gun initialization and suppressor hooks
code/modules/projectiles/guns/ballistic.dm
base_w_class кэшируется в Initialize() вместе с загрузкой магазина и патрона, attackby() использует can_attach_suppressor() перед установкой, введены хуки on_suppressor_installed() и on_suppressor_removed() для управления звуком и весом глушителя, обновлены сообщения пользователю на русском.
Shotgun jam/stress system foundation
code/modules/projectiles/guns/ballistic/shotgun.dm (lines 14–293)
Добавлены переменные jam/stress (jammed, jam_stress, jam_multiplier и другие), методы update_jam_stress(), update_stress_effects(), get_stressed_shot_spread(), apply_stressed_shot_stamina(), can_fire_check(), try_jam(), clear_jam(), переработана process_fire() для применения стресс-логики и проверок джема, обновлены attack_self() и pump() для взаимодействия с механикой заклинивания.
Shotgun variants: dp12, dual_tube, slamfire, and traitor models
code/modules/projectiles/guns/ballistic/shotgun.dm (lines 310–1385)
Новые варианты riot, syndicate, traitor с обновленными параметрами, dual_tube с переключением стволов, dp12 двуствольный помповый, slamfire с авто-помпой и стресс-зависимыми модификаторами, slamfire/traitor с крупной системой frenzy/overload включая оверлеи, сигнальные привязки к пользователю, питание frenzy при событиях и диагностический examine.
Shotgun automatic and combat mechanics
code/modules/projectiles/guns/ballistic/shotgun.dm (lines 1497–1614)
process_fire() для automatic вручную выбрасывает гильзы и загружает следующий патрон, combat версия получает toggle_stock() для раскладывания приклада с изменением w_class/recoil/spread и afterattack() блокирующий стрельбу со сложенным прикладом.
Projectile balance and breach_slug
code/modules/projectiles/projectile/bullets/shotgun.dm
Урон incendiary/shotgun повышен до 30, dragonsbreath до 10, pellet урон повышен до 8, rubber stamina до 20, improvised урон до 8. Добавлен новый breach_slug с отрицательным пробитием и специальной логикой on_hit() для airlock/window/grille.
UI and audio feedback: fullscreen overlay and emotes
code/_rendering/fullscreen/fullscreen.dm, code/modules/mob/living/emote.dm
Новый fullscreen overlay slamfire_frenzy с динамической альфа-анимацией в зависимости от severity, три новых audio emote (overload, psychotic, psychoticshort) с гендер-зависимыми звуками и ограничением SOFT_CRIT для feedback frenzy состояния.
Content addition: supply packs, uplink items, and designs
code/modules/cargo/packs/armory.dm, code/modules/cargo/packs/security.dm, code/modules/research/designs/weapon_designs.dm, code/modules/uplink/uplink_items/uplink_bundles.dm, code/modules/uplink/uplink_items/uplink_dangerous.dm, code/game/objects/items/storage/briefcase.dm
Новые supply pack bastion и randomshells, design dp12 с lockbox, uplink items aspisbundle/hellstitch/invictus/jackhammer/aspis с разными ограничениями, новый briefcase aspisbundle со специальным содержимым (traitor shotgun, suppressor, боеприпасы).
Mood events and loot tables
code/datums/mood_events/generic_positive_events.dm, code/game/objects/effects/spawners/lootdrop.dm
Новое настроение slamfire_overload с mood_change = 50 для позитивного события, расширенные лут-таблицы armory с dp12 и полные наборы дробовых боеприпасов (improvised/slug/stunslug/pulseslug/laserslug/ion).
New melee weapon: laser_bayonet
code/game/objects/items/kitchen.dm
Новый laser_bayonet как подкласс боевого ножа с параметрами остроты, пробития брони, блока, парирования, урона и встраивания.
Map updates: weapon replacements
_maps/RandomZLevels/VR/murderdome.dmm, _maps/RandomZLevels/away_mission/TheBeach.dmm, _maps/RandomZLevels/away_mission/ihategordon.dmm, _maps/RandomZLevels/away_mission/wildwest.dmm, _maps/map_files/generic/CentCom.dmm
Замены спавнов оружия: boltactiondp12 (murderdome), lethalslamfire/lethal (TheBeach/ihategordon), базовый shotgun → slamfire (wildwest), aa12dp12/traitor (CentCom).
Modular extension: KS23 updates
modular_bluemoon/code/modules/projectiles/guns/ballistic/shotgun.dm
KS23 получает новые звуки (fire/pump/load), поле force и fire_delay 6, удален звук при выбросе гильзы.

Sequence Diagram(s)

sequenceDiagram
  participant Player
  participant SlamfireTraitor as Slamfire/Traitor
  participant JamSystem as Jam/Stress System
  participant Frenzy as Frenzy State
  participant Overlay as UI Overlay
  
  Player->>SlamfireTraitor: Fire shot
  SlamfireTraitor->>JamSystem: process_fire() with stress check
  JamSystem->>JamSystem: update_jam_stress()
  JamSystem->>Frenzy: Can trigger jam?
  alt Jam occurs
    Frenzy->>SlamfireTraitor: try_jam()
    SlamfireTraitor->>Player: Try jam emote + sound
  else No jam
    SlamfireTraitor->>Frenzy: Feed frenzy meter
  end
  Frenzy->>Overlay: SetSeverity(current_stress)
  Overlay->>Player: Animate alpha based on severity
  Player->>SlamfireTraitor: Pump (Alt-click)
  SlamfireTraitor->>JamSystem: clear_jam() + reduce jam_stress
  JamSystem->>Overlay: Update severity
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

  • BlueMoon-Labs/BlueMoon-Station#2976: Добавляет аудио-эмоты bubble и blubbr в тот же модуль code/modules/mob/living/emote.dm, где данный PR добавляет overload/psychotic/psychoticshort, возможны конфликты слияния в одной ветке.
  • BlueMoon-Labs/BlueMoon-Station#2896: Изменяет сигнатуру process_fire() для дробовиков (добавляет параметр stam_cost), что напрямую пересекается с переработкой process_fire() в данном PR для jam/stress системы.

Suggested labels

Code, Sound, Sprites, Map Edit

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Название 'Shotguns reheated' связано с основным изменением — масштабным обновлением системы дробовиков, но формулировка очень краткая и образная, не раскрывая суть изменений.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 16

🧹 Nitpick comments (1)
code/modules/projectiles/guns/ballistic/shotgun.dm (1)

85-102: ⚡ Quick win

Рекомендуется использовать именованные константы для порогов стресса.

Магические числа (40, 60, 80) снижают читаемость и усложняют настройку баланса. Определите константы в начале файла:

`#define` JAM_STRESS_TIER_LOW 40
`#define` JAM_STRESS_TIER_MED 60
`#define` JAM_STRESS_TIER_HIGH 80
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@code/modules/projectiles/guns/ballistic/shotgun.dm` around lines 85 - 102,
Replace the magic thresholds in update_stress_effects with named constants:
define JAM_STRESS_TIER_LOW, JAM_STRESS_TIER_MED, JAM_STRESS_TIER_HIGH near the
top of the file and use them instead of 40, 60, 80 in the jam_stress
comparisons; update the conditions in proc update_stress_effects (references:
jam_stress, stress_spread_mult, stress_stam_cost, stress_pump_delay) to compare
against these constants so the thresholds are readable and configurable.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@_maps/RandomZLevels/away_mission/wildwest.dmm`:
- Line 2064: Замените использование базового дробовика
`/obj/item/gun/ballistic/shotgun/lethal` в этом блоке на вариант с slamfire —
`/obj/item/gun/ballistic/shotgun/slamfire/lethal` чтобы соответствовать AI
summary и целям PR; используйте паттерн, показанный в блоке `JW`
(`/obj/item/gun/ballistic/shotgun/slamfire/lethal`) как образец при правке и
убедитесь, что запятые и синтаксис списка остаются корректными после замены.

In `@code/game/objects/items/kitchen.dm`:
- Around line 240-243: Лазерный штык-нож имеет завышенные боевые параметры: поля
force = 23 и wound_bonus = 11 в сочетании с armour_penetration = 35 и
block_chance = 50 делают его сильнее родительских предметов; откорректируй
баланс либо снизив force до значения ближе к combat knife (≈16) и wound_bonus до
≈8, либо явно задокументируй в комментарии над определением (упомянуть поля
force, wound_bonus, armour_penetration и block_chance) что такие значения
являются намеренным баланс-решением (например, редкий/трейторский/нюк-артефакт).
- Around line 229-230: В коде предмета в kitchen.dm установлено icon_state =
"survivalknife" и item_state = "knife" — уточни, намеренно ли переиспользуется
спрайт обычного survival knife для лазерного штык-ножа; если да, оставь как
есть; если нет — поменяй icon_state на уникальное имя (например "laserknife" или
другое согласованное имя спрайта), добавь/обнови соответствующую
спрайт-переменную в ресурсах и при необходимости скорректируй
item_state/описание в той же сущности (функции/классе предмета, где определены
icon_state и item_state) чтобы они соответствовали новому спрайту.

In `@code/game/objects/items/storage/briefcase.dm`:
- Around line 92-101: The new type /obj/item/storage/briefcase/aspisbundle and
its PopulateContents() block use spaces for indentation; replace all leading
spaces with tabs for every line in that block (the type declaration and all
lines inside PopulateContents()), preserving the existing token order and
content so /obj/item/storage/briefcase/aspisbundle and the PopulateContents()
method keep the same code but use tabs for indentation to comply with the "Tabs
for indentation, never spaces" guideline.

In `@code/modules/projectiles/ammunition/ballistic/shotgun.dm`:
- Line 21: В поле desc (string) исправьте оборванную фразу и удалите лишний
пробел перед точкой: замените "A 12 gauge copper slug meant for destroying ." на
завершённое описание (например "A 12 gauge copper slug meant for destroying
targets.") — отредактируйте значение переменной desc в том модуле.
- Around line 19-27: /obj/item/ammo_casing/shotgun_breacher is currently
declared directly from /obj/item/ammo_casing which causes it to miss
shell_bounce_sounds and duplicate caliber; change its parent to
/obj/item/ammo_casing/shotgun/breacher (i.e. make it a subtype of
/obj/item/ammo_casing/shotgun) so it inherits shell_bounce_sounds and caliber,
then remove the redundant caliber = "shotgun" line and keep only unique fields
(name, desc, icon_state, projectile_type, custom_materials, pellets, variance)
in the /obj/item/ammo_casing/shotgun/breacher definition.

In `@code/modules/projectiles/gun.dm`:
- Around line 625-641: The if-block checking can_attach_bayonet(K, user) inside
the istype(I, /obj/item/kitchen/knife) branch uses brace characters on their own
lines; reformat that block to the project's idiomatic style by moving the
opening brace to the end of the if line (if(!can_attach_bayonet(K, user)) {) and
the closing brace to align with the if (}), keeping the inner logic (the to_chat
calls, bayonet check, suppressed/can_mount_both check and return) unchanged;
locate the block by the surrounding symbols K, can_attach_bayonet, bayonet,
suppressed, can_mount_both, to_chat, user.transferItemToLoc and update_icon.

In `@code/modules/projectiles/guns/ballistic.dm`:
- Around line 24-36: Several procedure blocks use leading spaces instead of
tabs; update their indentation to use tabs only. Edit the procedures
Initialize(), on_suppressor_installed, on_suppressor_removed,
install_suppressor(), and on_attack_hand() in ballistic.dm and replace any
leading space characters at the start of lines with a single tab per indent
level so all lines within those methods use tab indentation consistently; ensure
nested blocks keep correct tab depth and no trailing mixed whitespace remains.

In `@code/modules/projectiles/guns/ballistic/shotgun.dm`:
- Line 598: The direct assignment recoil = 7 breaks suppressor multipliers in
on_suppressor_installed(); instead either (A) treat this as a temporary recoil
spike by saving the current recoil, compute recoil from base_recoil (so
suppressor multipliers still apply) for the shot and then restore the saved
recoil after firing, or (B) if it is intended to be a permanent change (e.g.,
after doubleshot), set base_recoil = 7 and call refresh_stress_effects() so
suppressor multipliers are reapplied; update the code around the existing recoil
= 7 occurrence and reference on_suppressor_installed(), base_recoil, and
refresh_stress_effects() when making the change.
- Line 591: Вместо блокирующего sleep(1.2) замените синхронную паузу на
addtimer: вызывайте сразу chambered.fire_casing(...), playsound(...) и
shake_camera(...), затем запланируйте addtimer(CALLBACK(src,
PROC_REF(fire_second_barrel), target, user, params, suppressed, zone_override,
shot_spread), 1.2) для выполнения второго выстрела; добавьте метод/процедуру
fire_second_barrel в соответствующий класс (напр.
/obj/item/gun/ballistic/shotgun/dp12/traitor/proc/fire_second_barrel) который
проверяет QDELETED(src) и QDELETED(user) и наличие secondary_chambered, вызывает
secondary_chambered.fire_casing(...), playsound(...),
user.do_attack_animation(src), shake_camera(user,5,5) и
user.adjustStaminaLoss(5); используйте addtimer с CALLBACK/PROC_REF и ни в коем
случае не spawn().

In `@code/modules/projectiles/projectile/bullets/shotgun.dm`:
- Line 129: Комментарий рядом с переменной tile_dropoff в shotgun.dm устарел —
он содержит фразу "it does 6 damage", тогда как урон теперь 8; обновите текст
комментария, чтобы он корректно отражал новое значение (например заменить "6" на
"8" или переформулировать комментарий, упоминая 8 урона) рядом с tile_dropoff.
- Around line 162-171: В on_hit методе (функция on_hit) родительский метод ..()
вызывается сначала (в строке с ..() после . = ..()) и затем повторно в ветках
проверки istype для /obj/machinery/door/airlock, /obj/structure/window и
/obj/structure/grille, что приводит к двойной обработке; исправьте это, убрав
повторные вызовы ..() в этих istype-ветках (или, альтернативно, переместив
единственный вызов ..() так, чтобы он выполнялся единоразово после необходимых
istype-проверок), при этом сохранив добавление искр do_sparks для не-мобов
(do_sparks(1, TRUE, src)) и любую специальную обработку для структур, если она
требуется.

In `@code/modules/research/designs/weapon_designs.dm`:
- Line 334: The dp12 design (/datum/design/dp12) currently duplicates the
material list from /datum/design/nuclear_gun (materials =
list(/datum/material/iron = 10000, /datum/material/glass = 2000,
/datum/material/uranium = 3000, /datum/material/titanium = 1000)); change the
dp12 materials to ones appropriate for a ballistic shotgun (e.g. remove or
drastically reduce uranium, lower titanium and iron requirements, or swap in a
more plausible material), or alternatively add a clear in-code comment
justifying why dp12 matches nuclear_gun if that was intentional; update the
materials assignment on the dp12 datum to reflect the corrected values or the
justification comment.

In `@code/modules/uplink/uplink_items/uplink_bundles.dm`:
- Around line 55-61: The type /datum/uplink_item/dangerous/aspisbundle is
declared in the wrong module; move the entire type declaration for aspisbundle
out of the uplink_bundles file and into the file that holds other
/datum/uplink_item/dangerous/ types, placing it alphabetically among the other
dangerous items (e.g., near aspis or its proper alphabetical slot) so the
dangerous bundle types stay together; ensure you remove the original declaration
so there are no duplicate definitions.

In `@code/modules/uplink/uplink_items/uplink_dangerous.dm`:
- Around line 117-148: Replace leading spaces with tabs for the new uplink items
so they follow the project's "tabs for indentation" rule: update the indentation
on the entries for /datum/uplink_item/dangerous/hellstitch,
/datum/uplink_item/dangerous/invictus, /datum/uplink_item/dangerous/jackhammer,
and /datum/uplink_item/dangerous/aspis by converting the leading spaces at the
start of each line to a single tab (e.g. replace groups of four leading spaces
with \t), ensure your editor is set to use tabs for .dm files, and verify the
file now uses tabs for all indented lines before committing.

In `@modular_splurt/code/game/turfs/simulated/floor/plating/asteroid.dm`:
- Line 16: Вместо присваивания override_shell_bounce_sound = null (в тиле
simulated floor plating asteroid и других похожих) явно поставить
override_shell_bounce_sound = FALSE, потому что функция
ammo_casing/bounce_away() подавляет звук только при точном значении FALSE;
проверьте все упомянутые места (≈22) и замените null на FALSE там, где требуется
тишина, сохранив любые случаи, где нужен текстовый путь к звуку.

---

Nitpick comments:
In `@code/modules/projectiles/guns/ballistic/shotgun.dm`:
- Around line 85-102: Replace the magic thresholds in update_stress_effects with
named constants: define JAM_STRESS_TIER_LOW, JAM_STRESS_TIER_MED,
JAM_STRESS_TIER_HIGH near the top of the file and use them instead of 40, 60, 80
in the jam_stress comparisons; update the conditions in proc
update_stress_effects (references: jam_stress, stress_spread_mult,
stress_stam_cost, stress_pump_delay) to compare against these constants so the
thresholds are readable and configurable.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7c017048-a928-41b6-bcf8-8799cfad848a

📥 Commits

Reviewing files that changed from the base of the PR and between 8d24b54 and 61129c4.

⛔ Files ignored due to path filters (50)
  • sound/voice/frenzy/overload/female1.ogg is excluded by !**/*.ogg, !sound/**
  • sound/voice/frenzy/overload/female2.ogg is excluded by !**/*.ogg, !sound/**
  • sound/voice/frenzy/overload/female3.ogg is excluded by !**/*.ogg, !sound/**
  • sound/voice/frenzy/overload/female4.ogg is excluded by !**/*.ogg, !sound/**
  • sound/voice/frenzy/overload/male1.ogg is excluded by !**/*.ogg, !sound/**
  • sound/voice/frenzy/overload/male2.ogg is excluded by !**/*.ogg, !sound/**
  • sound/voice/frenzy/overload/male3.ogg is excluded by !**/*.ogg, !sound/**
  • sound/voice/frenzy/overload/male4.ogg is excluded by !**/*.ogg, !sound/**
  • sound/voice/frenzy/psychotic/femalepsychotic.ogg is excluded by !**/*.ogg, !sound/**
  • sound/voice/frenzy/psychotic/femalepsychotic2.ogg is excluded by !**/*.ogg, !sound/**
  • sound/voice/frenzy/psychotic/femalepsychoticcrying.ogg is excluded by !**/*.ogg, !sound/**
  • sound/voice/frenzy/psychotic/femalepsychoticshort.ogg is excluded by !**/*.ogg, !sound/**
  • sound/voice/frenzy/psychotic/femalepsychoticshort2.ogg is excluded by !**/*.ogg, !sound/**
  • sound/voice/frenzy/psychotic/malepsychotic.ogg is excluded by !**/*.ogg, !sound/**
  • sound/voice/frenzy/psychotic/malepsychotic2.ogg is excluded by !**/*.ogg, !sound/**
  • sound/voice/frenzy/psychotic/malepsychoticcrying.ogg is excluded by !**/*.ogg, !sound/**
  • sound/voice/frenzy/psychotic/malepsychoticshort.ogg is excluded by !**/*.ogg, !sound/**
  • sound/voice/frenzy/psychotic/malepsychoticshort2.ogg is excluded by !**/*.ogg, !sound/**
  • sound/weapons/Shotguns_reheated/Devastator/devastatorchamber.ogg is excluded by !**/*.ogg, !sound/**
  • sound/weapons/Shotguns_reheated/Devastator/devastatorsuppressed.ogg is excluded by !**/*.ogg, !sound/**
  • sound/weapons/Shotguns_reheated/KS-23/Ks-23Pumpaction.ogg is excluded by !**/*.ogg, !sound/**
  • sound/weapons/Shotguns_reheated/KS-23/Ks-23shot.ogg is excluded by !**/*.ogg, !sound/**
  • sound/weapons/Shotguns_reheated/Pumpaction/Pumpchamber.ogg is excluded by !**/*.ogg, !sound/**
  • sound/weapons/Shotguns_reheated/Pumpaction/Pumpfire.ogg is excluded by !**/*.ogg, !sound/**
  • sound/weapons/Shotguns_reheated/Riot/Riotchamber.ogg is excluded by !**/*.ogg, !sound/**
  • sound/weapons/Shotguns_reheated/Riot/Riotfire.ogg is excluded by !**/*.ogg, !sound/**
  • sound/weapons/Shotguns_reheated/Semi-auto/Semichamber.ogg is excluded by !**/*.ogg, !sound/**
  • sound/weapons/Shotguns_reheated/Semi-auto/Semifire.ogg is excluded by !**/*.ogg, !sound/**
  • sound/weapons/Shotguns_reheated/Semi-auto/Stockunfold.ogg is excluded by !**/*.ogg, !sound/**
  • sound/weapons/Shotguns_reheated/Slamfire/SlamfirePump.ogg is excluded by !**/*.ogg, !sound/**
  • sound/weapons/Shotguns_reheated/Slamfire/VO/fade1.ogg is excluded by !**/*.ogg, !sound/**
  • sound/weapons/Shotguns_reheated/Slamfire/VO/fade2.ogg is excluded by !**/*.ogg, !sound/**
  • sound/weapons/Shotguns_reheated/Slamfire/VO/fade3.ogg is excluded by !**/*.ogg, !sound/**
  • sound/weapons/Shotguns_reheated/Slamfire/VO/initialization.ogg is excluded by !**/*.ogg, !sound/**
  • sound/weapons/Shotguns_reheated/Slamfire/VO/overload.ogg is excluded by !**/*.ogg, !sound/**
  • sound/weapons/Shotguns_reheated/Slamfire/VO/whisper1.ogg is excluded by !**/*.ogg, !sound/**
  • sound/weapons/Shotguns_reheated/shared/Cyclerswap.ogg is excluded by !**/*.ogg, !sound/**
  • sound/weapons/Shotguns_reheated/shared/Shellinsert1.ogg is excluded by !**/*.ogg, !sound/**
  • sound/weapons/Shotguns_reheated/shared/Shellinsert2.ogg is excluded by !**/*.ogg, !sound/**
  • sound/weapons/Shotguns_reheated/shared/Shellinsertlight.wav is excluded by !**/*.wav, !sound/**
  • sound/weapons/Shotguns_reheated/shared/Shellinstertplastic.wav is excluded by !**/*.wav, !sound/**
  • sound/weapons/Shotguns_reheated/shared/casings/12g_fall1.wav is excluded by !**/*.wav, !sound/**
  • sound/weapons/Shotguns_reheated/shared/casings/12g_fall2.wav is excluded by !**/*.wav, !sound/**
  • sound/weapons/Shotguns_reheated/shared/casings/12g_fall3.ogg is excluded by !**/*.ogg, !sound/**
  • sound/weapons/Shotguns_reheated/shared/casings/12g_fall4.ogg is excluded by !**/*.ogg, !sound/**
  • sound/weapons/Shotguns_reheated/shared/draw.ogg is excluded by !**/*.ogg, !sound/**
  • sound/weapons/Shotguns_reheated/shared/jam_warning.ogg is excluded by !**/*.ogg, !sound/**
  • sound/weapons/Shotguns_reheated/shared/misfire.ogg is excluded by !**/*.ogg, !sound/**
  • sound/weapons/Shotguns_reheated/shared/shotgunsuppressed.ogg is excluded by !**/*.ogg, !sound/**
  • sound/weapons/Shotguns_reheated/shared/weapon_rattle.ogg is excluded by !**/*.ogg, !sound/**
📒 Files selected for processing (41)
  • _maps/RandomZLevels/VR/murderdome.dmm
  • _maps/RandomZLevels/VR/snowdin_VR.dmm
  • _maps/RandomZLevels/away_mission/TheBeach.dmm
  • _maps/RandomZLevels/away_mission/ihategordon.dmm
  • _maps/RandomZLevels/away_mission/wildwest.dmm
  • _maps/map_files/generic/CentCom.dmm
  • code/_rendering/fullscreen/fullscreen.dm
  • code/datums/mood_events/generic_positive_events.dm
  • code/game/objects/effects/spawners/lootdrop.dm
  • code/game/objects/items/kitchen.dm
  • code/game/objects/items/storage/briefcase.dm
  • code/game/turfs/closed.dm
  • code/game/turfs/open/floor/grass.dm
  • code/game/turfs/simulated/chasm.dm
  • code/game/turfs/simulated/floor/fancy_floor.dm
  • code/game/turfs/simulated/floor/plating/asteroid.dm
  • code/game/turfs/simulated/floor/plating/misc_plating.dm
  • code/game/turfs/simulated/lava.dm
  • code/game/turfs/simulated/reebe_void.dm
  • code/game/turfs/simulated/wall/mineral_walls.dm
  • code/game/turfs/simulated/water.dm
  • code/game/turfs/space/space.dm
  • code/game/turfs/turf.dm
  • code/modules/cargo/packs/armory.dm
  • code/modules/cargo/packs/security.dm
  • code/modules/holodeck/turfs.dm
  • code/modules/mapping/preloader.dm
  • code/modules/mob/living/emote.dm
  • code/modules/projectiles/ammunition/_ammunition.dm
  • code/modules/projectiles/ammunition/ballistic/shotgun.dm
  • code/modules/projectiles/gun.dm
  • code/modules/projectiles/guns/ballistic.dm
  • code/modules/projectiles/guns/ballistic/shotgun.dm
  • code/modules/projectiles/projectile/bullets/shotgun.dm
  • code/modules/research/designs/weapon_designs.dm
  • code/modules/uplink/uplink_items/uplink_bundles.dm
  • code/modules/uplink/uplink_items/uplink_dangerous.dm
  • modular_bluemoon/code/modules/projectiles/guns/ballistic/shotgun.dm
  • modular_citadel/code/modules/eventmaps/Spookystation/JTGSZwork.dm
  • modular_splurt/code/game/turfs/open/floor/plating/lavaland_jungle.dm
  • modular_splurt/code/game/turfs/simulated/floor/plating/asteroid.dm

Comment thread _maps/RandomZLevels/away_mission/wildwest.dmm
Comment on lines +229 to +230
icon_state = "survivalknife"
item_state = "knife"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Уточните использование спрайта survivalknife.

Лазерный штык-нож использует icon_state = "survivalknife", переиспользуя спрайт обычного survival knife. Учитывая, что это лазерное оружие с уникальными характеристиками (описание упоминает "лезвие всегда идеально острое", "ядерная батарейка"), возможно, предполагался уникальный спрайт?

Если переиспользование намеренное - можно проигнорировать.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@code/game/objects/items/kitchen.dm` around lines 229 - 230, В коде предмета в
kitchen.dm установлено icon_state = "survivalknife" и item_state = "knife" —
уточни, намеренно ли переиспользуется спрайт обычного survival knife для
лазерного штык-ножа; если да, оставь как есть; если нет — поменяй icon_state на
уникальное имя (например "laserknife" или другое согласованное имя спрайта),
добавь/обнови соответствующую спрайт-переменную в ресурсах и при необходимости
скорректируй item_state/описание в той же сущности (функции/классе предмета, где
определены icon_state и item_state) чтобы они соответствовали новому спрайту.

Comment thread code/game/objects/items/kitchen.dm
Comment thread code/game/objects/items/storage/briefcase.dm
Comment on lines +19 to +27
/obj/item/ammo_casing/shotgun_breacher
name = "breacher slug"
desc = "A 12 gauge copper slug meant for destroying ."
icon_state = "blshell"
caliber = "shotgun"
projectile_type = /obj/item/projectile/bullet/breach_slug
custom_materials = list(/datum/material/iron=4000)
pellets = 2
variance = 1

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -nP --type-add 'dm:*.dm' -t dm '\bshotgun_breacher\b'

Repository: BlueMoon-Labs/BlueMoon-Station

Length of output: 173


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="code/modules/projectiles/ammunition/ballistic/shotgun.dm"

# show the relevant parts around the reported lines + nearby parent definitions
nl -ba "$FILE" | sed -n '1,120p'

# also find any definition of the intended parent path if present
rg -nP --type-add 'dm:*.dm' -t dm '\b/obj/item/ammo_casing/shotgun\b' "$FILE"

# locate where shell_bounce_sounds and caliber are defined in this file (if at all)
rg -nP --type-add 'dm:*.dm' -t dm '(shell_bounce_sounds|caliber)\b' "$FILE"

Repository: BlueMoon-Labs/BlueMoon-Station

Length of output: 117


🏁 Script executed:

#!/bin/bash
set -euo pipefail
FILE="code/modules/projectiles/ammunition/ballistic/shotgun.dm"

python3 - <<'PY'
path = "code/modules/projectiles/ammunition/ballistic/shotgun.dm"
with open(path, "r", encoding="utf-8") as f:
    lines = f.readlines()
start, end = 1, 140
for i in range(start-1, min(end, len(lines))):
    print(f"{i+1:4d}: {lines[i].rstrip()}")
PY

echo "---- find parent definitions in this file ----"
rg -nP --type-add 'dm:*.dm' -t dm '\b/obj/item/ammo_casing/shotgun\b' "$FILE" || true

echo "---- find shell_bounce_sounds / caliber in this file ----"
rg -nP --type-add 'dm:*.dm' -t dm '\b(shell_bounce_sounds|caliber)\b' "$FILE" || true

Repository: BlueMoon-Labs/BlueMoon-Station

Length of output: 6357


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Search for exact path usages
rg -nP --type-add 'dm:*.dm' -t dm '\b/obj/item/ammo_casing/shotgun_breacher\b' || true

# Search for token usages (broader)
rg -nP --type-add 'dm:*.dm' -t dm '\bshotgun_breacher\b' || true

Repository: BlueMoon-Labs/BlueMoon-Station

Length of output: 173


🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -nP '\bshotgun_breacher\b' . || true
rg -nP '/obj/item/ammo_casing/shotgun_breacher' . || true

Repository: BlueMoon-Labs/BlueMoon-Station

Length of output: 276


🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -nP --type-add 'dm:*.dm' -t dm '\bshell_bounce_sounds\b' code || true
rg -nP --type-add 'dm:*.dm' -t dm '\bcaliber\b' code/modules/projectiles/ammunition code || true

Repository: BlueMoon-Labs/BlueMoon-Station

Length of output: 11440


🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -nP --type-add 'dm:*.dm' -t dm '\b/obj/item/ammo_casing/shotgun/breacher\b' . || true

Repository: BlueMoon-Labs/BlueMoon-Station

Length of output: 56


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# show the ammo casing base + how shell_bounce_sounds is used
FILE="code/modules/projectiles/ammunition/_ammunition.dm"
python3 - <<'PY'
path = "code/modules/projectiles/ammunition/_ammunition.dm"
with open(path, "r", encoding="utf-8") as f:
    lines = f.readlines()
for i in range(1, 220):
    if i-1 < len(lines):
        print(f"{i:4d}: {lines[i-1].rstrip()}")
PY

Repository: BlueMoon-Labs/BlueMoon-Station

Length of output: 4528


Перепривязать /obj/item/ammo_casing/shotgun_breacher к /obj/item/ammo_casing/shotgun/breacher, чтобы он наследовал shell_bounce_sounds и не дублировал caliber.

Сейчас /obj/item/ammo_casing/shotgun задаёт shell_bounce_sounds и caliber = "shotgun", но /obj/item/ammo_casing/shotgun_breacher объявлен напрямую от /obj/item/ammo_casing, поэтому звуки гильзы не наследуются и приходится вручную указывать caliber. Поиск по репо по старому пути находит только это определение.

♻️ Предлагаемый реворк через подтип
-/obj/item/ammo_casing/shotgun_breacher
+/obj/item/ammo_casing/shotgun/breacher
 	name = "breacher slug"
 	desc = "A 12 gauge copper slug meant for destroying ."
 	icon_state = "blshell"
-	caliber = "shotgun"
 	projectile_type = /obj/item/projectile/bullet/breach_slug
 	custom_materials = list(/datum/material/iron=4000)
 	pellets = 2
 	variance = 1
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@code/modules/projectiles/ammunition/ballistic/shotgun.dm` around lines 19 -
27, /obj/item/ammo_casing/shotgun_breacher is currently declared directly from
/obj/item/ammo_casing which causes it to miss shell_bounce_sounds and duplicate
caliber; change its parent to /obj/item/ammo_casing/shotgun/breacher (i.e. make
it a subtype of /obj/item/ammo_casing/shotgun) so it inherits
shell_bounce_sounds and caliber, then remove the redundant caliber = "shotgun"
line and keep only unique fields (name, desc, icon_state, projectile_type,
custom_materials, pellets, variance) in the
/obj/item/ammo_casing/shotgun/breacher definition.

Comment on lines +162 to +171
/obj/item/projectile/bullet/breach_slug/on_hit(atom/target, blocked = FALSE)
. = ..()
if(!ismob(target))
do_sparks(1, TRUE, src)
if(istype(target, /obj/machinery/door/airlock))
return ..()
if(istype(target, /obj/structure/window))
return ..()
if(istype(target, /obj/structure/grille))
return ..()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚖️ Poor tradeoff

Двойной вызов родительского метода для дверей/окон/решеток.

Метод on_hit() вызывает ..() в строке 163, а затем ПОВТОРНО вызывает ..() в строках 167, 169 и 171 для объектов типа airlock/window/grille. Это приведет к двойной обработке логики попадания (возможно, двойное применение урона, двойные эффекты и т.д.), что почти наверняка является багом.

Текущий флоу:

  • Для дверей/окон/решеток: родительский метод вызывается ДВАЖДЫ (строка 163 + одна из 167/169/171)
  • Для других целей: родительский метод вызывается один раз (строка 163)

Если цель — просто добавить искры для не-мобов, уберите повторные вызовы ..():

🔧 Предлагаемое исправление
 /obj/item/projectile/bullet/breach_slug/on_hit(atom/target, blocked = FALSE)
 	. = ..()
 	if(!ismob(target))
 		do_sparks(1, TRUE, src)
-	if(istype(target, /obj/machinery/door/airlock))
-		return ..()
-	if(istype(target, /obj/structure/window))
-		return ..()
-	if(istype(target, /obj/structure/grille))
-		return ..()
+	return .

Если же требуется специальная обработка для структур (двери/окна/решетки), явно опишите желаемое поведение без повторного вызова родительского метода.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/obj/item/projectile/bullet/breach_slug/on_hit(atom/target, blocked = FALSE)
. = ..()
if(!ismob(target))
do_sparks(1, TRUE, src)
if(istype(target, /obj/machinery/door/airlock))
return ..()
if(istype(target, /obj/structure/window))
return ..()
if(istype(target, /obj/structure/grille))
return ..()
/obj/item/projectile/bullet/breach_slug/on_hit(atom/target, blocked = FALSE)
. = ..()
if(!ismob(target))
do_sparks(1, TRUE, src)
return .
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@code/modules/projectiles/projectile/bullets/shotgun.dm` around lines 162 -
171, В on_hit методе (функция on_hit) родительский метод ..() вызывается сначала
(в строке с ..() после . = ..()) и затем повторно в ветках проверки istype для
/obj/machinery/door/airlock, /obj/structure/window и /obj/structure/grille, что
приводит к двойной обработке; исправьте это, убрав повторные вызовы ..() в этих
istype-ветках (или, альтернативно, переместив единственный вызов ..() так, чтобы
он выполнялся единоразово после необходимых istype-проверок), при этом сохранив
добавление искр do_sparks для не-мобов (do_sparks(1, TRUE, src)) и любую
специальную обработку для структур, если она требуется.

Comment thread code/modules/research/designs/weapon_designs.dm
Comment thread code/modules/uplink/uplink_items/uplink_bundles.dm
Comment thread code/modules/uplink/uplink_items/uplink_dangerous.dm
Comment thread modular_splurt/code/game/turfs/simulated/floor/plating/asteroid.dm
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant