Shotguns reheated #3278
Conversation
Добавление кода, предметов и реворков на стабильную ветку билда
Добавлены эмоции, связанные с трейторовским дробовиком. Добавлен новый патрон, улучшена структура предметов overall. Система осечек работает теперь корректно
СУЩЕСТВУЮЩИЕ БАГИ: Спрайты оружия пропадают при установке глушителя.
WalkthroughPR перерабатывает систему дробовиков и звуков отскока снарядов: заменяет ChangesShotgun Overhaul: Jam System, Variants, and Audio Feedback
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
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Possibly related PRs
Suggested labels
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ 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. Comment |
There was a problem hiding this comment.
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
⛔ Files ignored due to path filters (50)
sound/voice/frenzy/overload/female1.oggis excluded by!**/*.ogg,!sound/**sound/voice/frenzy/overload/female2.oggis excluded by!**/*.ogg,!sound/**sound/voice/frenzy/overload/female3.oggis excluded by!**/*.ogg,!sound/**sound/voice/frenzy/overload/female4.oggis excluded by!**/*.ogg,!sound/**sound/voice/frenzy/overload/male1.oggis excluded by!**/*.ogg,!sound/**sound/voice/frenzy/overload/male2.oggis excluded by!**/*.ogg,!sound/**sound/voice/frenzy/overload/male3.oggis excluded by!**/*.ogg,!sound/**sound/voice/frenzy/overload/male4.oggis excluded by!**/*.ogg,!sound/**sound/voice/frenzy/psychotic/femalepsychotic.oggis excluded by!**/*.ogg,!sound/**sound/voice/frenzy/psychotic/femalepsychotic2.oggis excluded by!**/*.ogg,!sound/**sound/voice/frenzy/psychotic/femalepsychoticcrying.oggis excluded by!**/*.ogg,!sound/**sound/voice/frenzy/psychotic/femalepsychoticshort.oggis excluded by!**/*.ogg,!sound/**sound/voice/frenzy/psychotic/femalepsychoticshort2.oggis excluded by!**/*.ogg,!sound/**sound/voice/frenzy/psychotic/malepsychotic.oggis excluded by!**/*.ogg,!sound/**sound/voice/frenzy/psychotic/malepsychotic2.oggis excluded by!**/*.ogg,!sound/**sound/voice/frenzy/psychotic/malepsychoticcrying.oggis excluded by!**/*.ogg,!sound/**sound/voice/frenzy/psychotic/malepsychoticshort.oggis excluded by!**/*.ogg,!sound/**sound/voice/frenzy/psychotic/malepsychoticshort2.oggis excluded by!**/*.ogg,!sound/**sound/weapons/Shotguns_reheated/Devastator/devastatorchamber.oggis excluded by!**/*.ogg,!sound/**sound/weapons/Shotguns_reheated/Devastator/devastatorsuppressed.oggis excluded by!**/*.ogg,!sound/**sound/weapons/Shotguns_reheated/KS-23/Ks-23Pumpaction.oggis excluded by!**/*.ogg,!sound/**sound/weapons/Shotguns_reheated/KS-23/Ks-23shot.oggis excluded by!**/*.ogg,!sound/**sound/weapons/Shotguns_reheated/Pumpaction/Pumpchamber.oggis excluded by!**/*.ogg,!sound/**sound/weapons/Shotguns_reheated/Pumpaction/Pumpfire.oggis excluded by!**/*.ogg,!sound/**sound/weapons/Shotguns_reheated/Riot/Riotchamber.oggis excluded by!**/*.ogg,!sound/**sound/weapons/Shotguns_reheated/Riot/Riotfire.oggis excluded by!**/*.ogg,!sound/**sound/weapons/Shotguns_reheated/Semi-auto/Semichamber.oggis excluded by!**/*.ogg,!sound/**sound/weapons/Shotguns_reheated/Semi-auto/Semifire.oggis excluded by!**/*.ogg,!sound/**sound/weapons/Shotguns_reheated/Semi-auto/Stockunfold.oggis excluded by!**/*.ogg,!sound/**sound/weapons/Shotguns_reheated/Slamfire/SlamfirePump.oggis excluded by!**/*.ogg,!sound/**sound/weapons/Shotguns_reheated/Slamfire/VO/fade1.oggis excluded by!**/*.ogg,!sound/**sound/weapons/Shotguns_reheated/Slamfire/VO/fade2.oggis excluded by!**/*.ogg,!sound/**sound/weapons/Shotguns_reheated/Slamfire/VO/fade3.oggis excluded by!**/*.ogg,!sound/**sound/weapons/Shotguns_reheated/Slamfire/VO/initialization.oggis excluded by!**/*.ogg,!sound/**sound/weapons/Shotguns_reheated/Slamfire/VO/overload.oggis excluded by!**/*.ogg,!sound/**sound/weapons/Shotguns_reheated/Slamfire/VO/whisper1.oggis excluded by!**/*.ogg,!sound/**sound/weapons/Shotguns_reheated/shared/Cyclerswap.oggis excluded by!**/*.ogg,!sound/**sound/weapons/Shotguns_reheated/shared/Shellinsert1.oggis excluded by!**/*.ogg,!sound/**sound/weapons/Shotguns_reheated/shared/Shellinsert2.oggis excluded by!**/*.ogg,!sound/**sound/weapons/Shotguns_reheated/shared/Shellinsertlight.wavis excluded by!**/*.wav,!sound/**sound/weapons/Shotguns_reheated/shared/Shellinstertplastic.wavis excluded by!**/*.wav,!sound/**sound/weapons/Shotguns_reheated/shared/casings/12g_fall1.wavis excluded by!**/*.wav,!sound/**sound/weapons/Shotguns_reheated/shared/casings/12g_fall2.wavis excluded by!**/*.wav,!sound/**sound/weapons/Shotguns_reheated/shared/casings/12g_fall3.oggis excluded by!**/*.ogg,!sound/**sound/weapons/Shotguns_reheated/shared/casings/12g_fall4.oggis excluded by!**/*.ogg,!sound/**sound/weapons/Shotguns_reheated/shared/draw.oggis excluded by!**/*.ogg,!sound/**sound/weapons/Shotguns_reheated/shared/jam_warning.oggis excluded by!**/*.ogg,!sound/**sound/weapons/Shotguns_reheated/shared/misfire.oggis excluded by!**/*.ogg,!sound/**sound/weapons/Shotguns_reheated/shared/shotgunsuppressed.oggis excluded by!**/*.ogg,!sound/**sound/weapons/Shotguns_reheated/shared/weapon_rattle.oggis 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.dmmcode/_rendering/fullscreen/fullscreen.dmcode/datums/mood_events/generic_positive_events.dmcode/game/objects/effects/spawners/lootdrop.dmcode/game/objects/items/kitchen.dmcode/game/objects/items/storage/briefcase.dmcode/game/turfs/closed.dmcode/game/turfs/open/floor/grass.dmcode/game/turfs/simulated/chasm.dmcode/game/turfs/simulated/floor/fancy_floor.dmcode/game/turfs/simulated/floor/plating/asteroid.dmcode/game/turfs/simulated/floor/plating/misc_plating.dmcode/game/turfs/simulated/lava.dmcode/game/turfs/simulated/reebe_void.dmcode/game/turfs/simulated/wall/mineral_walls.dmcode/game/turfs/simulated/water.dmcode/game/turfs/space/space.dmcode/game/turfs/turf.dmcode/modules/cargo/packs/armory.dmcode/modules/cargo/packs/security.dmcode/modules/holodeck/turfs.dmcode/modules/mapping/preloader.dmcode/modules/mob/living/emote.dmcode/modules/projectiles/ammunition/_ammunition.dmcode/modules/projectiles/ammunition/ballistic/shotgun.dmcode/modules/projectiles/gun.dmcode/modules/projectiles/guns/ballistic.dmcode/modules/projectiles/guns/ballistic/shotgun.dmcode/modules/projectiles/projectile/bullets/shotgun.dmcode/modules/research/designs/weapon_designs.dmcode/modules/uplink/uplink_items/uplink_bundles.dmcode/modules/uplink/uplink_items/uplink_dangerous.dmmodular_bluemoon/code/modules/projectiles/guns/ballistic/shotgun.dmmodular_citadel/code/modules/eventmaps/Spookystation/JTGSZwork.dmmodular_splurt/code/game/turfs/open/floor/plating/lavaland_jungle.dmmodular_splurt/code/game/turfs/simulated/floor/plating/asteroid.dm
| icon_state = "survivalknife" | ||
| item_state = "knife" |
There was a problem hiding this comment.
Уточните использование спрайта 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) чтобы они соответствовали новому спрайту.
| /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 |
There was a problem hiding this comment.
🧩 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" || trueRepository: 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' || trueRepository: 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' . || trueRepository: 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 || trueRepository: 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' . || trueRepository: 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()}")
PYRepository: 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.
| /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 ..() |
There was a problem hiding this comment.
Двойной вызов родительского метода для дверей/окон/решеток.
Метод 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.
| /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)) и любую
специальную обработку для структур, если она требуется.
Описание
Небольшое контентное и техническое обновление, связанное с переписыванием легасикода.
Улучшение базовых дробовиков, предметов связанных с ними. Механика осечек, новое оружие
Открытый тред для обсуждения: 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
Изменения в выпуске
Новые функции
Балансировка
Исправления