Skip to content

Ебануто огромный апдейт вещей лапки#3285

Open
Lev1932 wants to merge 27 commits into
BlueMoon-Labs:masterfrom
Lev1932:big-lapkee-update
Open

Ебануто огромный апдейт вещей лапки#3285
Lev1932 wants to merge 27 commits into
BlueMoon-Labs:masterfrom
Lev1932:big-lapkee-update

Conversation

@Lev1932
Copy link
Copy Markdown

@Lev1932 Lev1932 commented May 30, 2026

Описание

Лапки ебанулась и захотела себе примерно 15 рескинов в лодаут. Я делаю. Закинуть в ТМ на недельку или две, а то тут миллиарды вещей будут

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

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

Попросили...

Summary by CodeRabbit

  • Новые возможности

    • Добавлены оружие и модкиты: Quasar, Comet, Neutron, Spectral; новый модкит для Pulsar-ножа; нож переименован в «Kasari ritual knife». Новые модкиты добавлены в комплектные наборы.
  • Улучшения

    • Обновлён визуальный статус у Nebular‑T, Supernova, Pulsar и новых стволов — более явные индикаторы заряда, режима и заполнения патронника (иконы и оверлеи).

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 30, 2026

Review Change Stack

Caution

Review failed

Failed to post review comments

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

В guns.dm переработаны icon_state/update_overlays для Nebular‑T и Supernova, добавлены новые модкиты и оружие (Quasar, Comet, Neutron, Spectral, riot Pulsar) и переименован Pulsar-нож; в storage.dm эти модкиты добавлены в содержимое lapkee_kit.

Changes

Обновления оружия и контента

Layer / File(s) Summary
Katana kit и Stun‑Katana
modular_bluemoon/fluffs/code/guns.dm
Ограничен fromitem у katana_kit (только /obj/item/melee/baton/stunsword) и добавлен /obj/item/melee/baton/stunkatana с логикой состояния и подсветки.
Nebular‑T: иконка и оверлеи
modular_bluemoon/fluffs/code/guns.dm
Переименован icon_state (nebular_tnebular-t), update_icon_state() теперь ставит nebular-t-e при отсутствии/нулевом/низком заряде; добавлен update_overlays() с nebular-t-base и уровнями nebular-t-0/1/2.
Supernova: состояние по боезапасу и оверлеи
modular_bluemoon/fluffs/code/guns.dm
Изменены icon_state/item_state; update_icon_state() зависит от наличия патронов (0 → supernova-e, иначе supernova, учитывает сложенный приклад). Добавлен update_overlays() (supernova-loaded/not-loaded, supernova-base, supernova-[ammo] при ammo < 6).
Переименование Pulsar → Kasari ritual knife
modular_bluemoon/fluffs/code/guns.dm
Добавлен modkit/pulsar_knife_kit и обновлён name ножа (/obj/item/kitchen/knife/combat/pulsarKasari ritual knife).
Добавление Quasar, Comet, Neutron, Spectral и riot Pulsar
modular_bluemoon/fluffs/code/guns.dm
Новые модкиты и оружие: quasar_kit + e_gun/nuclear/quasar (overlays с дискретизацией заряда и базой по режиму), comet_kit + wt550/comet (icon/overlays по заполнению магазина), neutron_kit + xray/neutron (icon/overlays по порогам заряда), spectral_kit + temperature/spectral (оверлеи heat/freeze и уровни), и gun/ballistic/shotgun/riot/pulsar (sprite/overlays по sawn_off и заполнению).
PopulateContents: добавить модкиты в lapkee_kit
modular_bluemoon/fluffs/code/storage.dm
В PopulateContents() для lapkee_kit добавлены pulsar_knife_kit, quasar_kit, comet_kit, neutron_kit и spectral_kit; изменён порядок строк в блоке.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

Sprites, Code

🚥 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 Заголовок PR на русском языке в разговорном стиле относится к большому обновлению предметов Lapkee, что соответствует содержанию PR (множество рескинов оружия и модификаций).
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.

@Lev1932
Copy link
Copy Markdown
Author

Lev1932 commented May 30, 2026

@coderabbitai Мне надо сделать overlays на квазар, меняющиеся в зависимости от заряда и при полном от режима(quasar-lethal-mode-base, quasar-non-lethal-mode-base, quasar-7 и до 0 по той же схеме(то есть при 8/8 заряда спрайт base, иначе [колво частей заряда]/8

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 30, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find quasar-related files
fd -i quasar
echo "---"
# Search for quasar in dm files
rg -rn -i "quasar" --type=dm -A5 -B5

Length of output: 406


🏁 Script executed:

#!/bin/bash
# Find quasar-related files
fd -i quasar
echo "=== rg search ==="
rg -rn -i "quasar" -g "*.dm" -A5 -B5
echo "=== dmi files ==="
fd -i quasar -e dmi
echo "=== all files ==="
fd -i quasar

Length of output: 2222


🏁 Script executed:

#!/bin/bash
# Check the PR diff for quasar
gh pr diff 3285 --repo BlueMoon-Labs/BlueMoon-Station | grep -i quasar | head -80
echo "==="
# Also check if there's a fluffs/lapka related folder
fd -i lapka
fd -i "quasar" --no-ignore

Length of output: 494


🏁 Script executed:

#!/bin/bash
# Get full quasar section from PR diff
gh pr diff 3285 --repo BlueMoon-Labs/BlueMoon-Station | grep -i quasar -A30 -B5
echo "=== nuclear e_gun parent ==="
rg -n "e_gun/nuclear" -g "*.dm" -A30 | head -120
echo "=== update_icon in nuclear ==="
rg -n "update_icon\|overlay\|charge" -g "*.dm" modular_bluemoon/fluffs/code/guns.dm | head -60

Length of output: 12725


🏁 Script executed:

#!/bin/bash
echo "=== e_gun/nuclear definition ==="
rg -n "e_gun/nuclear" -g "*.dm" -A40 | grep -v "\.dm-" | head -80

echo "=== update_icon in e_gun ==="
rg -n "update_icon\|overlay\|charge_overlay\|cell\b" -g "*.dm" code/modules/projectiles/guns/energy/e_gun.dm | head -60

echo "=== full e_gun nuclear definition ==="
rg -n "/obj/item/gun/energy/e_gun/nuclear" -g "*.dm" -A40 | head -80

echo "=== Nebular-T full code for reference ==="
rg -n "e_gun/nuclear/n\b\|nuclear/n\b" -g "*.dm" -B2 -A50 | head -100

Length of output: 10890


🏁 Script executed:

#!/bin/bash
echo "=== energy_gun.dm nuclear section ==="
sed -n '100,230p' code/modules/projectiles/guns/energy/energy_gun.dm

echo "=== also look at how mode/cell/charge_parts are used ==="
rg -n "charge_parts\|lethal_mode\|mode\b\|cell\b\|update_overlays\|update_icon" -g "*.dm" code/modules/projectiles/guns/energy/energy_gun.dm | head -60

echo "=== Nebular with overlays (existing modular) ==="
rg -n "update_overlays\|charge\|mode\|overlay" -g "*.dm" modular_bluemoon/fluffs/code/guns.dm | head -60

Length of output: 4766


🏁 Script executed:

#!/bin/bash
echo "=== get_charge_ratio and charge-related procs ==="
rg -n "get_charge_ratio\|charge_ratio\|automatic_charge_overlays\|modifystate\|shaded_charge\|select_name" -g "*.dm" code/modules/projectiles/guns/energy/ | head -80

echo "=== e_gun base update_overlays ==="
rg -n "update_overlays\|proc/update_overlays" -g "*.dm" code/modules/projectiles/guns/energy/ -A20 | head -100

echo "=== ammo_type and firemode for e_gun ==="
rg -n "ammo_type\|firemode\|current_firemode\|select_name" -g "*.dm" code/modules/projectiles/guns/energy/e_gun.dm | head -40

echo "=== e_gun.dm base file ==="
fd e_gun.dm

Length of output: 944


🏁 Script executed:

#!/bin/bash
echo "=== find e_gun definition file ==="
rg -rn "^/obj/item/gun/energy/e_gun\b" -g "*.dm" -l

echo "=== get_charge_ratio proc ==="
rg -rn "proc/get_charge_ratio\|get_charge_ratio" -g "*.dm" -A10 | head -60

echo "=== automatic_charge_overlays shaded_charge modifystate vars ==="
rg -rn "automatic_charge_overlays\|shaded_charge\|modifystate" -g "*.dm" -A3 | head -80

echo "=== current_firemode_index and ammo select_name ==="
rg -rn "current_firemode_index\|select_name" -g "*.dm" -A2 | head -60

echo "=== energy_gun.dm full nuclear ert update_overlays continued ==="
sed -n '195,260p' code/modules/projectiles/guns/energy/energy_gun.dm

Length of output: 2646


🏁 Script executed:

#!/bin/bash
echo "=== base e_gun definition with all vars ==="
rg -n "get_charge_ratio\|automatic_charge_overlays\|shaded_charge\|modifystate\|current_firemode\|select_name\|lethal\|non.lethal\|disabler\|laser" -g "*.dm" code/modules/projectiles/guns/energy/energy_gun.dm | head -80

echo "=== full base e_gun ==="
sed -n '1,100p' code/modules/projectiles/guns/energy/energy_gun.dm

echo "=== gun energy base update_overlays and get_charge_ratio ==="
rg -rn "proc/get_charge_ratio\|automatic_charge_overlays\|modifystate\|shaded_charge\|select_name" -g "*.dm" code/modules/projectiles/guns/ -A5 | head -100

echo "=== select_name in ammo ==="
rg -rn "select_name" -g "*.dm" code/modules/projectiles/ -A2 | head -60

Length of output: 8817


🏁 Script executed:

#!/bin/bash
echo "=== energy.dm base update_overlays and get_charge_ratio ==="
rg -n "update_overlays\|get_charge_ratio\|charge_sections\|automatic_charge\|modifystate\|shaded_charge\|current_firemode_index\|proc/n\b" -g "*.dm" code/modules/projectiles/guns/energy.dm -A5 | head -120

echo "=== full energy.dm sections ==="
sed -n '1,150p' code/modules/projectiles/guns/energy.dm

echo "=== ammo disabler and laser n values ==="
rg -n "^\s*n\s*=" -g "*.dm" code/modules/projectiles/ammunition/energy/ | head -30

Length of output: 6334


🏁 Script executed:

#!/bin/bash
echo "=== energy.dm update_overlays and get_charge_ratio ==="
sed -n '150,280p' code/modules/projectiles/guns/energy.dm

echo "=== n variable in ammo casings ==="
rg -n "^\s*n\s*=" -g "*.dm" code/modules/projectiles/ammunition/energy/ | head -30

Length of output: 5832


🏁 Script executed:

#!/bin/bash
echo "=== energy.dm update_overlays continued + get_charge_ratio ==="
sed -n '280,360p' code/modules/projectiles/guns/energy.dm

echo "=== select_name vs n in ammo_casing ==="
rg -n "select_name\b\|var/n\b\|^\s*n\b" -g "*.dm" code/modules/projectiles/ammunition/energy/laser.dm code/modules/projectiles/ammunition/energy/stun.dm | head -30

Length of output: 3862



@Lev1932 Вот код для overlays квазара. Добавь это в modular_bluemoon/fluffs/code/guns.dm прямо под определением /obj/item/gun/energy/e_gun/nuclear/quasar:

/obj/item/gun/energy/e_gun/nuclear/quasar
	DONATE_ITEM_TOOLTIP_PARENT
	name = "\improper Quasar"
	desc = "Продвинутая лазерная установка с микрореакторной батареей внутри. Удивительно надёжна в роли лазерной указки, и куда менее применима в бою из за низкого урона. Тем не менее, пользуется спросом ввиду простоты применения и буквально бесплатной эксплуатации, не требующей каких либо вложений."
	icon = 'modular_bluemoon/fluffs/icons/obj/guns.dmi'
	lefthand_file = 'modular_bluemoon/fluffs/icons/mob/guns_left.dmi'
	righthand_file = 'modular_bluemoon/fluffs/icons/mob/guns_right.dmi'
	icon_state = "quasar"
	item_state = "Nebular-9"
	can_flashlight = FALSE
	charge_sections = 8               // 8 делений заряда
	automatic_charge_overlays = FALSE // Отключаем стандартную систему оверлеев заряда

/obj/item/gun/energy/e_gun/nuclear/quasar/update_overlays()
	. = ..() // вызываем родительский (в т.ч. fail-оверлеи из e_gun/nuclear)
	if(QDELETED(src) || !ammo_type || !length(ammo_type) || current_firemode_index < 1 || current_firemode_index > length(ammo_type))
		return
	var/ratio = get_charge_ratio()
	var/obj/item/ammo_casing/energy/shot = ammo_type[current_firemode_index]
	if(ratio >= charge_sections) // полный заряд (8/8)
		if(istype(shot, /obj/item/ammo_casing/energy/laser))
			. += "quasar-lethal-mode-base"
		else
			. += "quasar-non-lethal-mode-base"
	else // частичный заряд: 0, 1, 2 ... 7
		. += "quasar-[ratio]"

Что нужно добавить в guns.dmi (10 оверлей-спрайтов):

Состояние Условие
quasar-lethal-mode-base Полный заряд + летальный режим (laser)
quasar-non-lethal-mode-base Полный заряд + нелетальный режим (disabler)
quasar-7 7/8 заряда
quasar-6 6/8
quasar-5 5/8
quasar-4 4/8
quasar-3 3/8
quasar-2 2/8
quasar-1 1/8
quasar-0 Пустой (не может выстрелить)

Как работает логика:

  • get_charge_ratio() возвращает 0 если не может выстрелить, и 1–8 в зависимости от заряда относительно charge_sections = 8
  • При полном заряде (ratio == 8) — показывается base-спрайт в зависимости от режима
  • При частичном — quasar-[число от 0 до 7]

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
modular_bluemoon/fluffs/code/guns.dm (1)

1076-1102: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Привяжите отображение Nebular-T к cell, иначе спрайт залипает и оверлеи расходятся с зарядом.

После перехода в nebular-t-e иконка уже не возвращается в базовое состояние: при charge_percent > 0.1 здесь ничего не выставляется. Плюс update_overlays() делает ранний выход по magazine, хотя дальше читает заряд из cell, так что состояние легко разойдётся с фактическим зарядом оружия.

💡 Вариант правки
+#define NEBULAR_T_EMPTY_THRESHOLD 0.1
+#define NEBULAR_T_LOW_THRESHOLD 0.3
+#define NEBULAR_T_MEDIUM_THRESHOLD 0.6
+
 /obj/item/gun/energy/e_gun/advtaser/nebular_t/update_icon_state()
-	var/charge_percent = cell.charge / cell.maxcharge
-	if(charge_percent <= 0.1)
-		icon_state = "nebular-t-e"
+	if(!cell || !cell.maxcharge)
+		icon_state = "nebular-t-e"
+		return
+	var/charge_percent = cell.charge / cell.maxcharge
+	icon_state = charge_percent <= NEBULAR_T_EMPTY_THRESHOLD ? "nebular-t-e" : initial(icon_state)
 
 /obj/item/gun/energy/e_gun/advtaser/nebular_t/update_overlays()
 	. = ..()
 	. += "nebular-t-base"
 
-	if(!magazine || !magazine.max_ammo)
+	if(!cell || !cell.maxcharge)
 		. += "nebular-t-0"
 		return
 
 	var/charge_percent = cell.charge / cell.maxcharge
-	if(charge_percent>=0.3 && charge_percent<=0.6)
+	if(charge_percent >= NEBULAR_T_LOW_THRESHOLD && charge_percent <= NEBULAR_T_MEDIUM_THRESHOLD)
 		. += "nebular-t-2"
-	else if(charge_percent>=0.1 && charge_percent<=0.3)
+	else if(charge_percent >= NEBULAR_T_EMPTY_THRESHOLD && charge_percent <= NEBULAR_T_LOW_THRESHOLD)
 		. += "nebular-t-1"
-	else if(charge_percent<=0.1)
+	else if(charge_percent <= NEBULAR_T_EMPTY_THRESHOLD)
 		. += "nebular-t-0"
+
+#undef NEBULAR_T_EMPTY_THRESHOLD
+#undef NEBULAR_T_LOW_THRESHOLD
+#undef NEBULAR_T_MEDIUM_THRESHOLD

As per coding guidelines, "No magic numbers — use #define constants".

🤖 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 `@modular_bluemoon/fluffs/code/guns.dm` around lines 1076 - 1102, The sprite
sticks because update_icon_state and update_overlays don't reliably use the
weapon's cell and early-return on magazine causes charge-based overlays to be
skipped; in update_icon_state(), first check that cell exists, compute
charge_percent from cell, and set icon_state back to "nebular-t" when
charge_percent > LOW_CHARGE_THRESHOLD instead of only setting the low state, and
in update_overlays() ensure you read cell.charge only after confirming cell
exists and move/adjust the magazine existence check so it doesn't early-return
before applying charge-based overlay logic; replace magic numbers (0.1, 0.3,
0.6) with `#define` constants like NEBULAR_T_CHARGE_LOW, NEBULAR_T_CHARGE_MED_LOW,
NEBULAR_T_CHARGE_MED_HIGH and use those in both update_icon_state and
update_overlays (referencing
/obj/item/gun/energy/e_gun/advtaser/nebular_t:update_icon_state and
:update_overlays).
🤖 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 `@modular_bluemoon/fluffs/code/guns.dm`:
- Around line 1447-1451: Вы переопределяете существующий тип
/obj/item/modkit/nebular_t_kit для Quasar; вместо этого создайте новый
уникальный путь для кита (например /obj/item/modkit/quasar_kit) и поместите в
нём поля product и fromitem, оставив /obj/item/modkit/nebular_t_kit нетронутым,
чтобы исходный Nebular-T kit сохранился; обновите все места, где должен
использоваться новый Quasar-kit, чтобы ссылались на новый путь и проверьте, что
product = /obj/item/gun/energy/e_gun/nuclear/quasar и fromitem =
list(/obj/item/gun/energy/e_gun/nuclear) у нового типа.

---

Outside diff comments:
In `@modular_bluemoon/fluffs/code/guns.dm`:
- Around line 1076-1102: The sprite sticks because update_icon_state and
update_overlays don't reliably use the weapon's cell and early-return on
magazine causes charge-based overlays to be skipped; in update_icon_state(),
first check that cell exists, compute charge_percent from cell, and set
icon_state back to "nebular-t" when charge_percent > LOW_CHARGE_THRESHOLD
instead of only setting the low state, and in update_overlays() ensure you read
cell.charge only after confirming cell exists and move/adjust the magazine
existence check so it doesn't early-return before applying charge-based overlay
logic; replace magic numbers (0.1, 0.3, 0.6) with `#define` constants like
NEBULAR_T_CHARGE_LOW, NEBULAR_T_CHARGE_MED_LOW, NEBULAR_T_CHARGE_MED_HIGH and
use those in both update_icon_state and update_overlays (referencing
/obj/item/gun/energy/e_gun/advtaser/nebular_t:update_icon_state and
:update_overlays).
🪄 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: 693cf4d4-bf7e-4b44-a319-cfab8186b3c1

📥 Commits

Reviewing files that changed from the base of the PR and between 1333958 and fecdb23.

📒 Files selected for processing (2)
  • modular_bluemoon/fluffs/code/guns.dm
  • modular_bluemoon/fluffs/icons/obj/guns.dmi

Comment thread modular_bluemoon/fluffs/code/guns.dm Outdated
@Lev1932
Copy link
Copy Markdown
Author

Lev1932 commented May 30, 2026

@coderabbitai Во первых, нам не нужны fail оверлеи, во вторых как ты можешь быть что ратио максимум 8? Почему свою переменную не напишешь. А и почему тесты падают и после обновы апстрима, хоть их должны были починить

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 30, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
echo "=== get_charge_ratio implementation ==="
rg -n "proc/get_charge_ratio\|/get_charge_ratio" -g "*.dm" -A20 | head -80

echo "=== how nebular_t does update_overlays (reference) ==="
rg -n "update_overlays\|charge\|cell\b" -g "*.dm" modular_bluemoon/fluffs/code/guns.dm | head -40

echo "=== cell.charge usage in guns ==="
rg -n "cell\.charge\b\|cell\.maxcharge\b" -g "*.dm" code/modules/projectiles/guns/ -A2 | head -60

echo "=== charge_sections var ==="
rg -n "charge_sections" -g "*.dm" -A3 | head -60

echo "=== PR test failures ==="
gh pr checks 3285 --repo BlueMoon-Labs/BlueMoon-Station 2>&1 | head -60

echo "=== PR status ==="
gh pr view 3285 --repo BlueMoon-Labs/BlueMoon-Station --json statusCheckRollup | jq '.statusCheckRollup[]? | {name, conclusion, status}' 2>&1 | head -80

Length of output: 10973


🏁 Script executed:

#!/bin/bash
echo "=== Compile Maps log ==="
gh run view 26679190686 --repo BlueMoon-Labs/BlueMoon-Station --job 78636441122 --log 2>&1 | grep -i "error\|warning\|failed\|cannot\|undefined\|missing" | head -60

echo "=== Run Linters log ==="
gh run view 26679190686 --repo BlueMoon-Labs/BlueMoon-Station --job 78636441126 --log 2>&1 | grep -i "error\|warning\|failed\|cannot\|undefined\|missing" | head -60

echo "=== Integration test runtimestation log (smallest, most likely to show root cause) ==="
gh run view 26679190686 --repo BlueMoon-Labs/BlueMoon-Station --job 78636441122 --log 2>&1 | tail -80

Length of output: 17324


🏁 Script executed:

#!/bin/bash
echo "=== guns.dm around line 1092 ==="
sed -n '1080,1110p' modular_bluemoon/fluffs/code/guns.dm

Length of output: 1072



( ་་་ ་་་ )

@Lev1932 Отвечаю по всем трём пунктам:


1 & 2 — Overlays квазара (без ..(), своя переменная)

/obj/item/gun/energy/e_gun/nuclear/quasar/update_overlays()
	// НЕ вызываем ..() — нам не нужны родительские/fail-оверлеи
	. = list()
	if(!cell || cell.charge <= 0 || !cell.maxcharge)
		. += "quasar-0"
		return
	var/max_sections = 8
	var/ratio = CEILING((cell.charge / cell.maxcharge) * max_sections, 1)
	// ratio гарантированно от 1 до 8 (своя переменная, не get_charge_ratio)
	if(ratio >= max_sections) // 8/8 — полный заряд
		if(istype(ammo_type[current_firemode_index], /obj/item/ammo_casing/energy/laser))
			. += "quasar-lethal-mode-base"
		else
			. += "quasar-non-lethal-mode-base"
	else
		. += "quasar-[ratio]"

3 — Почему падают тесты

Это не проблема апстрима. Ошибка компиляции в твоём PR, строка 1092 modular_bluemoon/fluffs/code/guns.dm:

error: magazine: undefined var
error: magazine.max_ammo: undefined var

Это в nebular_t/update_overlays() — у энергетических пушек (e_gun) нет переменной magazine, только cell. Правим:

/obj/item/gun/energy/e_gun/advtaser/nebular_t/update_overlays()
	. = ..()
	. += "nebular-t-base"

	if(!cell || cell.charge <= 0)  // ← было: !magazine || !magazine.max_ammo
		. += "nebular-t-0"
		return

	var/charge_percent = cell.charge / cell.maxcharge
	if(charge_percent >= 0.3 && charge_percent <= 0.6)
		. += "nebular-t-2"
	else if(charge_percent >= 0.1 && charge_percent < 0.3)
		. += "nebular-t-1"
	else if(charge_percent < 0.1)
		. += "nebular-t-0"

Вот почему все Integration Tests и Compile Maps падают — компилятор не может собрать проект из-за этих двух ошибок.

@Lev1932
Copy link
Copy Markdown
Author

Lev1932 commented May 30, 2026

@coderabbitai ЭТО ПИЗДЕЦ, МНЕ ЕЩЁ И ДРОБАШ supernova ПЕРЕДЕЛЫВАТЬ ПОМОГАЙ
supernova - обычный вариант
supernova-e - пустая
с supernova-folded и supernova-e-folded аналогично, только сложенная
дальше оверлеи
supernova-loaded это если патрон в патроннике
supernova-not-loaded без него
supernova-base это индикатор боезопаса, поверх него в обратном порядке накладывать supernova-5, supernova-4, supernova-3 и тд

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 30, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
echo "=== supernova definition ==="
rg -n "supernova" -g "*.dm" -A20 -B3 | head -120

echo "=== supernova in guns.dm ==="
rg -n "supernova" modular_bluemoon/fluffs/code/guns.dm -A20 -B3

echo "=== find shotgun/bolt parent types ==="
rg -n "bolt\|pump\|shotgun" -g "*.dm" code/modules/projectiles/guns/ -l | head -10

Length of output: 14129



(╥﹏╥) Держи, всё что нужно:

/obj/item/gun/ballistic/shotgun/automatic/combat/supernova/update_icon_state()
	var/ammo = magazine ? magazine.ammo_count() : 0
	var/folded = stock ? "" : "-folded"
	if(ammo <= 0)
		icon_state = "supernova-e[folded]"
	else
		icon_state = "supernova[folded]"

/obj/item/gun/ballistic/shotgun/automatic/combat/supernova/update_overlays()
	. = list()
	// Патрон в патроннике
	if(chambered && chambered.BB)
		. += "supernova-loaded"
	else
		. += "supernova-not-loaded"
	// Индикатор боезапаса: подложка + уровень (0..5)
	var/ammo = magazine ? magazine.ammo_count() : 0
	. += "supernova-base"
	. += "supernova-[ammo]"

Что нужно в guns.dm:

  • Убрать старый update_icon_state() (который строил supernova-[ammo]-[chamber][folded])
  • Добавить оба новых проца выше

Спрайты в 48x32.dmi:

Спрайт Назначение
supernova Обычный (сложенный)
supernova-e Пустой
supernova-folded Сложен
supernova-e-folded Пустой + сложен
supernova-loaded Оверлей: патрон в патроннике
supernova-not-loaded Оверлей: патронник пуст
supernova-base Оверлей: подложка индикатора
supernova-0supernova-5 Оверлей: уровень боезапаса

Итого 14 спрайтов.

@Lev1932
Copy link
Copy Markdown
Author

Lev1932 commented May 30, 2026

@coderabbitai Почему линтеры упали? И не будет проблемы как с небуларом, что патрон в патроннике не считался и был вечно разряженным на одно деление

@Lev1932 Lev1932 marked this pull request as draft May 30, 2026 08:51
@Lev1932
Copy link
Copy Markdown
Author

Lev1932 commented May 30, 2026

@coderabbitai Почему линтеры упали? И не будет проблемы как с небуларом, что патрон в патроннике не считался и был вечно разряженным на одно деление

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 30, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
echo "=== PR checks ==="
gh pr checks 3285 --repo BlueMoon-Labs/BlueMoon-Station 2>&1 | head -40

echo "=== Run IDs ==="
gh run list --repo BlueMoon-Labs/BlueMoon-Station --branch big-lapkee-update --limit 5 2>&1

echo "=== ammo_count definition ==="
rg -n "proc/ammo_count\|/ammo_count" -g "*.dm" -A15 | head -60

echo "=== chambered in ballistic guns ==="
rg -n "chambered\b" -g "*.dm" code/modules/projectiles/guns/ballistic.dm | head -30

echo "=== supernova current definition in PR ==="
rg -n "supernova" -g "*.dm" modular_bluemoon/fluffs/code/guns.dm -B2 -A30

echo "=== linter log ==="
gh run list --repo BlueMoon-Labs/BlueMoon-Station --branch big-lapkee-update --limit 3 --json databaseId,status,conclusion,name 2>&1

Length of output: 9561


🏁 Script executed:

#!/bin/bash
echo "=== Linter job log ==="
gh run view 26679542339 --repo BlueMoon-Labs/BlueMoon-Station --job 78636441126 --log 2>&1 | grep -i "error\|warning\|fail\|lint\|undefined\|missing\|cannot" | head -60

echo "=== Linter log (latest run) ==="
gh run view 26679547501 --repo BlueMoon-Labs/BlueMoon-Station --job 78637367708 --log 2>&1 | grep -i "error\|warning\|fail\|lint\|undefined\|missing\|cannot" | head -60

echo "=== ammo_count in magazine ==="
rg -n "proc/ammo_count\|/ammo_count" -g "*.dm" -A10

echo "=== get_ammo proc full ==="
rg -n "proc/get_ammo" -g "*.dm" -A15 | head -40

Length of output: 7194


🏁 Script executed:

#!/bin/bash
echo "=== Full linter log tail ==="
gh run view 26679547501 --repo BlueMoon-Labs/BlueMoon-Station --job 78637367708 --log 2>&1 | tail -80

echo "=== Linter log - DreamAnnotate step ==="
gh run view 26679547501 --repo BlueMoon-Labs/BlueMoon-Station --job 78637367708 --log 2>&1 | grep -A3 -i "DreamAnnotate\|annotate\|dm_annotate\|lint\|check\|Run "

echo "=== Supernova magazine capacity ==="
rg -n "supernova" -g "*.dm" code/ -A10 | head -40

echo "=== automatic combat shotgun magazine capacity ==="
rg -n "shotgun/automatic/combat\b" -g "*.dm" code/ -A20 | head -60

echo "=== ammo_count in magazine types ==="
rg -n "proc/ammo_count\|/ammo_count" -g "*.dm" | head -20
rg -n "ammo_count" -g "*.dm" code/modules/projectiles/ | head -30

Length of output: 12226


🏁 Script executed:

#!/bin/bash
echo "=== Linter errors from failed run ==="
gh run view 26679542339 --repo BlueMoon-Labs/BlueMoon-Station --job 78636441126 --log 2>&1 | tail -100

echo "=== internal/shot/com magazine capacity ==="
rg -n "internal/shot/com\b" -g "*.dm" -A15 | head -60

echo "=== internal shotgun ammo_count override ==="
sed -n '1,40p' code/modules/projectiles/boxes_magazines/internal/shotgun.dm

echo "=== base ammo_count ==="
sed -n '135,160p' code/modules/projectiles/boxes_magazines/_box_magazine.dm

Length of output: 19421



@Lev1932


1 — Почему линтеры упали

Это та же ошибка, которую я уже называл — в nebular_t/update_overlays() на строке 1092 используется переменная magazine, которой не существует у energy-пушек:

guns.dm:1092 — error: undefined var: "magazine"
guns.dm:1092 — error: undefined var: "magazine"  
guns.dm:1092 — warning: field access requires static type: "max_ammo"

DreamChecker (линтер) поймал это, даже если BYOND-компилятор иногда пропускает. Исправь nebular_t/update_overlays() — замени magazine и magazine.max_ammo на cell и cell.maxcharge (код я давал в прошлом ответе).


2 — Проблема с патроном в патроннике

Не будет — в предложенном мной коде дизайн специально разделён на две части:

  • supernova-loaded / supernova-not-loaded — отдельный оверлей, который показывает наличие патрона в патроннике
  • supernova-0supernova-N — показывает только то, что в магазине, через magazine.ammo_count()

Когда патрон досылается в патронник: магазин уменьшается на 1 → индикатор показывает N-1 уровней, но supernova-loaded загорается. Суммарная информация полная и корректная, без недосчёта.


⚠️ Но есть другая проблема: max_ammo = 6, а не 5

/obj/item/ammo_box/magazine/internal/shot/com имеет max_ammo = 6. Значит спрайты нужны от supernova-0 до supernova-6 (7 штук), а не до 5. Либо добавь в supernova:

/obj/item/gun/ballistic/shotgun/automatic/combat/supernova
    ...
    mag_type = /obj/item/ammo_box/magazine/internal/shot/com/supernova // кастомный
/obj/item/ammo_box/magazine/internal/shot/com/supernova
    max_ammo = 5

И тогда max будет 5 → supernova-0 до supernova-5.

(ó﹏ò。)

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 30, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
echo "=== PR checks ==="
gh pr checks 3285 --repo BlueMoon-Labs/BlueMoon-Station 2>&1 | head -60

echo "=== Run Linters job log ==="
gh run list --repo BlueMoon-Labs/BlueMoon-Station --branch big-lapkee-update --json databaseId,name,status,conclusion --limit 5

echo "=== latest run ID ==="
LATEST=$(gh run list --repo BlueMoon-Labs/BlueMoon-Station --branch big-lapkee-update --json databaseId --limit 1 | jq -r '.[0].databaseId')
echo "Latest run: $LATEST"
gh run view $LATEST --repo BlueMoon-Labs/BlueMoon-Station --json jobs | jq '.jobs[] | {name, conclusion, databaseId}' 2>&1

Length of output: 6516


🏁 Script executed:

#!/bin/bash
echo "=== ammo_count() implementation ==="
rg -n "proc/ammo_count\|/ammo_count" -g "*.dm" -A15 | head -60

echo "=== chambered var in ballistic gun ==="
rg -n "var/chambered\|chambered\b" -g "*.dm" code/modules/projectiles/guns/ballistic.dm | head -30

echo "=== ammo_count usage ==="
rg -n "ammo_count\(\)" -g "*.dm" code/modules/projectiles/ -A2 | head -40

echo "=== magazine ammo_count in context of update_overlays/icon ==="
rg -n "ammo_count\|chambered\|ammo_count" -g "*.dm" code/modules/projectiles/guns/ -A3 | head -60

Length of output: 3504


🏁 Script executed:

#!/bin/bash
echo "=== current guns.dm supernova section ==="
rg -n "supernova" modular_bluemoon/fluffs/code/guns.dm -B3 -A30

echo "=== linter errors from PR ==="
LATEST=$(gh run list --repo BlueMoon-Labs/BlueMoon-Station --branch big-lapkee-update --json databaseId --limit 1 | jq -r '.[0].databaseId')
LINT_JOB=$(gh run view $LATEST --repo BlueMoon-Labs/BlueMoon-Station --json jobs | jq -r '.jobs[] | select(.name | test("[Ll]int")) | .databaseId' 2>/dev/null | head -1)
echo "Lint job: $LINT_JOB"
gh run view $LATEST --repo BlueMoon-Labs/BlueMoon-Station --job $LINT_JOB --log 2>&1 | grep -i "error\|warning\|fail\|lint\|undefined\|cannot" | head -60

Length of output: 4619


🏁 Script executed:

#!/bin/bash
echo "=== Full linter log ==="
gh run view 26679547501 --repo BlueMoon-Labs/BlueMoon-Station --job 78637367708 --log 2>&1 | head -120

echo "=== ammo_count proc definition ==="
rg -n "proc/ammo_count" -g "*.dm" -A20 | head -60

echo "=== ballistic.dm ammo_count_in_chamber / total_ammo ==="
sed -n '165,185p' code/modules/projectiles/guns/ballistic.dm

echo "=== magazine get_round and stored_ammo var ==="
rg -n "stored_ammo\|get_round\|ammo_count\|/proc/ammo_count" -g "*.dm" code/modules/projectiles/magazines/ -A5 | head -60

Length of output: 2947


🏁 Script executed:

#!/bin/bash
echo "=== Previous failed run linter job ==="
PREV_LINT=$(gh run view 26679542339 --repo BlueMoon-Labs/BlueMoon-Station --json jobs | jq -r '.jobs[] | select(.name | test("[Ll]int")) | .databaseId' 2>/dev/null | head -1)
echo "Prev lint job: $PREV_LINT"
gh run view 26679542339 --repo BlueMoon-Labs/BlueMoon-Station --job $PREV_LINT --log 2>&1 | grep -i "error\|warning\|fail\|lint\|undefined\|cannot\|supernova\|quasar\|nebular\|guns" | head -80

echo "=== Full prev linter log (last 100 lines) ==="
gh run view 26679542339 --repo BlueMoon-Labs/BlueMoon-Station --job $PREV_LINT --log 2>&1 | tail -100

Length of output: 19503



@Lev1932 Нашёл конкретную причину и отвечаю на оба вопроса.


1. Почему упали линтеры

guns.dm, строка 1470update_overlays() не вызывает ..():

error: proc never calls parent, required by /atom/proc/update_overlays
- code/game/atoms.dm:725: required by this must_call_parent annotation

/atom/proc/update_overlays помечен как must_call_parent — это жёсткое требование движка, обойти нельзя. ..() обязан быть вызван, но его результат можно просто выбросить:

/obj/item/gun/energy/e_gun/advtaser/nebular_t/update_overlays()
    ..()          // ← обязательно, иначе линтер падает; результат нам не нужен
    . = list()    // заменяем своим списком, без fail-оверлеев
    . += "nebular-t-base"
    if(!cell || cell.charge <= 0)
        . += "nebular-t-0"
        return
    var/charge_percent = cell.charge / cell.maxcharge
    if(charge_percent > 0.6)
        . += "nebular-t-2"
    else if(charge_percent > 0.3)
        . += "nebular-t-1"
    else
        . += "nebular-t-0"

Аналогично для quasar и любого другого update_overlays() — везде ..() в самом начале обязателен.


2. Проблема «вечно разряженного деления» — для суперновы её НЕТ

В небуларе баг был потому, что код пытался использовать magazine на энергетической пушке, у которой его нет.

Для суперновы всё чисто:

  • magazine.ammo_count() → считает только патроны в магазине (stored_ammo.len)
  • Патрон в патроннике (chambered) → показывается отдельным оверлеем supernova-loaded/not-loaded

Они не смешиваются, оба показываются корректно. Если магазин на 5 патронов и один уже в патроннике — индикатор покажет supernova-5 + supernova-loaded. Никакого смещения.

( ་་་ ་་་ )

@Lev1932
Copy link
Copy Markdown
Author

Lev1932 commented May 30, 2026

@coderabbitai теперь помогай нейтрон доделать спрайты: neutron; neutron-e; оверлеи: neutron-base; neutron-2; neutron-1; neutron-0

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 30, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
echo "=== neutron in guns.dm ==="
rg -n -i "neutron" modular_bluemoon/fluffs/code/guns.dm -B3 -A30

echo "=== neutron anywhere ==="
rg -rn -i "neutron" -g "*.dm" -B2 -A10 | head -80

Length of output: 8209



@Lev1932 Вижу — текущий код нейтрона полностью сломан: использует magazine (энергопушка!), спрайты от comet и supernova-e. Вот исправление:

/obj/item/gun/energy/xray/neutron
	DONATE_ITEM_TOOLTIP_PARENT
	name = "\improper Neutron"
	desc = "Ученый внутри вас не может нарадоваться, это оружие - настоящее изнасилование идеи о мирном применении рентгеновского излучения. Концентрированные пучки испускаемые этой бандурой способны выжигать даже металл, единственное что омрачает - ограничение конструкции, не дающее возможности использовать этого кастрата что бы аннигилировать надоедливого клоуна за один выстрел до состояния бесформенной массы."
	unique_reskin = list()
	icon = 'modular_bluemoon/fluffs/icons/obj/48x32.dmi'
	icon_state = "neutron"           // ← было "comet"
	lefthand_file = 'modular_bluemoon/fluffs/icons/mob/guns_left.dmi'
	righthand_file = 'modular_bluemoon/fluffs/icons/mob/guns_right.dmi'
	item_state = "neutron"           // ← было "comet"

/obj/item/gun/energy/xray/neutron/update_icon_state()
	if(!cell || cell.charge <= 0)
		icon_state = "neutron-e"
	else
		icon_state = "neutron"

/obj/item/gun/energy/xray/neutron/update_overlays()
	. = ..()                         // обязательно — must_call_parent
	. += "neutron-base"
	if(!cell || cell.charge <= 0)
		. += "neutron-0"
		return
	var/charge_percent = cell.charge / cell.maxcharge
	if(charge_percent > 0.6)
		. += "neutron-2"
	else
		. += "neutron-1"

Логика порогов:

Состояние Условие
neutron-2 > 60% заряда
neutron-1 1–60% заряда
neutron-0 Пустой

Спрайты для 48x32.dmi — итого 6:

Спрайт Назначение
neutron Основной icon_state
neutron-e Пустой icon_state
neutron-base Оверлей-подложка индикатора
neutron-2 Оверлей: высокий заряд
neutron-1 Оверлей: низкий заряд
neutron-0 Оверлей: пусто

ʕ •ᴥ•ʔ

@Lev1932
Copy link
Copy Markdown
Author

Lev1932 commented May 30, 2026

@coderabbitai почини комету. У неё максимум 32 патрона, а лапки наспрайтила только 9 спрайтов. Сделай через проценты, как nebular-9

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 30, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
echo "=== comet in guns.dm ==="
rg -n -i "comet" modular_bluemoon/fluffs/code/guns.dm -B3 -A30

echo "=== comet anywhere else ==="
rg -rn -i "comet" -g "*.dm" -B2 -A15 | head -80

echo "=== nebular-9 update_overlays for reference (if already in file) ==="
rg -n -i "nebular.9" modular_bluemoon/fluffs/code/guns.dm -B2 -A25

Length of output: 15257



@Lev1932 Вот исправленный код по той же схеме, что Небулар-9:

/obj/item/gun/ballistic/automatic/wt550/comet/update_icon_state()
	if(!magazine || magazine.ammo_count() <= 0)
		icon_state = "comet-e"
	else
		icon_state = "comet"

/obj/item/gun/ballistic/automatic/wt550/comet/update_overlays()
	. = ..()
	. += "comet-base"
	if(!magazine || !magazine.max_ammo)
		. += "comet-0"
		return
	var/fill_level = round(magazine.stored_ammo.len / magazine.max_ammo * 8)
	if(fill_level < 8)  // при полном (8/8) — только base, без доп. оверлея
		. += "comet-[fill_level]"

Логика:

  • stored_ammo.len / max_ammo * 8 → число от 0 до 8
  • Полный магазин (32/32) → fill_level = 8 → показывается только comet-base
  • Частично/пусто → comet-0comet-7

Итого 9 спрайтов (ровно столько, сколько нарисовано):

Спрайт Условие
comet-base Всегда (подложка индикатора)
comet-7 ~88–99% заряда
comet-6 ~75–87%
comet-5 ~63–74%
comet-4 ~50–62%
comet-3 ~38–49%
comet-2 ~25–37%
comet-1 ~13–24%
comet-0 Пустой / ~0–12%

Также исправил update_icon_state() — в текущем коде при перезарядке icon_state не сбрасывался обратно на comet.

ʕ •ᴥ•ʔ

@Lev1932 Lev1932 marked this pull request as ready for review May 30, 2026 10:13
@Lev1932
Copy link
Copy Markdown
Author

Lev1932 commented May 30, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 30, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 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 `@modular_bluemoon/fluffs/code/guns.dm`:
- Around line 1484-1498: The check inside update_overlays() uses
istype(ammo_type[current_firemode_index], /obj/item/ammo_casing/energy/laser)
but ammo_type[current_firemode_index] is a typepath, so replace istype(...) with
ispath(...) to correctly compare typepaths; update the conditional in
update_overlays() to use ispath(ammo_type[current_firemode_index],
/obj/item/ammo_casing/energy/laser) so the lethal/non-lethal overlay branch
works as intended.
- Around line 1585-1600: In update_overlays() replace the invalid istype call on
a typepath with ispath by checking ispath(ammo_type[current_firemode_index],
/obj/item/ammo_casing/energy/temp/hot); and prevent division-by-zero when
computing charge_percent from cell.charge / cell.maxcharge by first ensuring
cell.maxcharge > 0 (e.g. treat charge_percent as 0 or return early if
cell.maxcharge == 0) so the computation of charge_percent is safe; update
references to ammo_type, current_firemode_index, and cell accordingly.
- Around line 1556-1566: In update_overlays() for
/obj/item/gun/energy/xray/neutron, guard against division-by-zero by checking
cell.maxcharge before computing charge_percent: ensure cell and cell.maxcharge
are valid (e.g., if !cell || cell.charge <= 0 || cell.maxcharge <= 0) return or
treat as zero charge, then compute charge_percent = cell.charge / cell.maxcharge
and proceed to choose "neutron-2"/"neutron-1"; update the conditional logic
around cell, cell.charge and cell.maxcharge to avoid dividing when
cell.maxcharge == 0.
- Around line 1613-1631: The file defines a second set of
update_icon_state/update_overlays for
/obj/item/gun/ballistic/automatic/wt550/comet that overwrites the Comet visuals
with Pulsar overlays; remove or merge the duplicate methods so comet keeps its
original comet-* icon_state and overlays (modify or delete the later definitions
named update_icon_state() and update_overlays() under
/obj/item/gun/ballistic/automatic/wt550/comet), and while merging/fixing
update_overlays(), correct the overlay name typo "pulsars-0" to the intended
"pulsar-0" or to the appropriate comet-* name and ensure the fill_level overlay
string matches the comet scheme rather than using pulsar-* values.
🪄 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: 1f5ba2dc-93e2-4528-9455-b6a37ea32002

📥 Commits

Reviewing files that changed from the base of the PR and between fecdb23 and 31a4ae7.

📒 Files selected for processing (6)
  • modular_bluemoon/fluffs/code/guns.dm
  • modular_bluemoon/fluffs/code/storage.dm
  • modular_bluemoon/fluffs/icons/mob/guns_left.dmi
  • modular_bluemoon/fluffs/icons/mob/guns_right.dmi
  • modular_bluemoon/fluffs/icons/obj/48x32.dmi
  • modular_bluemoon/fluffs/icons/obj/guns.dmi

Comment thread modular_bluemoon/fluffs/code/guns.dm
Comment thread modular_bluemoon/fluffs/code/guns.dm
Comment thread modular_bluemoon/fluffs/code/guns.dm
Comment thread modular_bluemoon/fluffs/code/guns.dm Outdated
@Lev1932
Copy link
Copy Markdown
Author

Lev1932 commented May 30, 2026

@coderabbitai istype() на типпасе всегда вернёт FALSE — используйте ispath(). Ты уверен? В чём у них отличие вообще.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 30, 2026

Tip

For best results, initiate chat on the files or code changes.

@Lev1932 Да, ты прав — я ошибся. Вот ключевое различие:

istype(A, B) — проверяет, является ли инстанс объекта A типом B или его подтипом.

var/obj/item/ammo_casing/energy/laser/shot = new()
istype(shot, /obj/item/ammo_casing/energy/laser) // TRUE — это объект

ispath(A, B) — проверяет, является ли тайп-путь A типом B или его подтипом.

var/path = /obj/item/ammo_casing/energy/laser
ispath(path, /obj/item/ammo_casing/energy/laser) // TRUE — это путь

ammo_type хранит именно тайп-пути, не инстансы. Значит istype(ammo_type[current_firemode_index], ...) всегда вернёт FALSE. Ты абсолютно прав.

Исправленный update_overlays() для квазара:

/obj/item/gun/energy/e_gun/nuclear/quasar/update_overlays()
	..()
	. = list()
	if(!cell || cell.charge <= 0 || !cell.maxcharge)
		. += "quasar-0"
		return
	var/max_sections = 8
	var/ratio = CEILING((cell.charge / cell.maxcharge) * max_sections, 1)
	if(ratio >= max_sections)
		if(ispath(ammo_type[current_firemode_index], /obj/item/ammo_casing/energy/laser))
			. += "quasar-lethal-mode-base"
		else
			. += "quasar-non-lethal-mode-base"
	else
		. += "quasar-[ratio]"

istype()ispath(). Больше не будет вечного quasar-non-lethal-mode-base.

ʕ ಡ ﹏ ಡ ʔ


✏️ Learnings added
Learnt from: Lev1932
URL: https://github.com/BlueMoon-Labs/BlueMoon-Station/pull/3285

Timestamp: 2026-05-30T10:25:53.856Z
Learning: In BYOND/DM (used in BlueMoon-Station repository): `istype(A, B)` requires A to be an **instantiated object** — if A is a type path, it always returns FALSE. For checking type paths (like entries in the `ammo_type` list of energy guns), use `ispath(A, B)` instead. Example: `ispath(ammo_type[current_firemode_index], /obj/item/ammo_casing/energy/laser)` is correct; `istype(ammo_type[current_firemode_index], ...)` is always FALSE.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

@Lev1932
Copy link
Copy Markdown
Author

Lev1932 commented May 30, 2026

@coderabbitai а вот тут используется istype почему /obj/item/gun/ballistic/shotgun/riot/mossberg/update_icon_state()
var/state = "mossberg_l"
if(chambered)
if(istype(chambered, /obj/item/ammo_casing/shotgun/rubbershot) || istype(chambered, /obj/item/ammo_casing/shotgun/beanbag))
state = "mossberg_n"
else if(istype(chambered, /obj/item/ammo_casing/shotgun/incendiary))
state = "mossberg_i"
icon_state = state
item_state = state

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 30, 2026

Tip

For best results, initiate chat on the files or code changes.

@Lev1932 Всё правильно — здесь istype() корректен, потому что chambered — это инстанс объекта.

Разница в том, что хранит переменная:

Переменная Что содержит Нужна проверка
chambered Живой объект: new /obj/item/ammo_casing/shotgun/rubbershot() istype()
ammo_type[i] Тайп-путь: /obj/item/ammo_casing/energy/laser ispath()

chambered — это реальная гильза, засланная в патронник. Это объект, который существует в мире. istype() и создан для проверки объектов.

ammo_type — это список тайп-путей вида list(/obj/item/ammo_casing/energy/laser, /obj/item/ammo_casing/energy/disabler). Там нет инстансов, только пути. istype() на пути → всегда FALSE.

Простая мнемоника:

if(istype(some_object, /type))  // объект существует в мире → istype
if(ispath(some_typepath, /type)) // просто адрес типа → ispath

ʕ •ᴥ•ʔ

@Lev1932
Copy link
Copy Markdown
Author

Lev1932 commented May 30, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 30, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@Lev1932
Copy link
Copy Markdown
Author

Lev1932 commented May 30, 2026

@coderabbitai ты дебил. Я проверил на локалке и ispath не работает, а с истайп всё отлично

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 30, 2026

Tip

For best results, initiate chat on the files or code changes.

@Lev1932 Прости, я был неправ. В BYOND DM istype() работает и с тайп-путями, и с инстансами — движок проверяет иерархию типов в обоих случаях. Значит istype(ammo_type[current_firemode_index], /obj/item/ammo_casing/energy/laser) корректен и всё правильно.

Возвращаем istype() обратно в код квазара:

/obj/item/gun/energy/e_gun/nuclear/quasar/update_overlays()
	..()
	. = list()
	if(!cell || cell.charge <= 0 || !cell.maxcharge)
		. += "quasar-0"
		return
	var/max_sections = 8
	var/ratio = CEILING((cell.charge / cell.maxcharge) * max_sections, 1)
	if(ratio >= max_sections)
		if(istype(ammo_type[current_firemode_index], /obj/item/ammo_casing/energy/laser))
			. += "quasar-lethal-mode-base"
		else
			. += "quasar-non-lethal-mode-base"
	else
		. += "quasar-[ratio]"

Исправляю неверное обучение.

(╥﹏╥)


✏️ Learnings added
Learnt from: Lev1932
URL: https://github.com/BlueMoon-Labs/BlueMoon-Station/pull/3285

Timestamp: 2026-05-30T11:32:44.731Z
Learning: In BYOND/DM (used in BlueMoon-Station repository): `istype(A, B)` works correctly on BOTH instantiated objects AND type paths. When A is a type path (e.g., an entry from the `ammo_type` list of energy guns), `istype(A, B)` correctly checks the type hierarchy and returns TRUE if A is B or a subtype. Both `istype()` and `ispath()` are valid for type path checks; `ispath()` is more semantically explicit but `istype()` is NOT always FALSE on paths as was incorrectly stated before.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
modular_bluemoon/fluffs/code/guns.dm (2)

1583-1598: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

istype() на типпасе — используйте ispath().

Строка 1585: ammo_type[current_firemode_index] возвращает типпас (путь к типу), а не экземпляр. istype() работает только с экземплярами объектов. Для проверки типпасов необходимо использовать ispath().

🔧 Исправление
 /obj/item/gun/energy/temperature/spectral/update_overlays()
 	. = ..()
-	if(istype(ammo_type[current_firemode_index], /obj/item/ammo_casing/energy/temp/hot))
+	if(ispath(ammo_type[current_firemode_index], /obj/item/ammo_casing/energy/temp/hot))
 		. += "spectral-heat-base"
 		. += "spectral-heat-mode"
 	else
 		. += "spectral-freeze-base"
 		. += "spectral-freeze-mode"
 	if(!cell || cell.charge <= 0 || !cell.maxcharge)
 		. += "spectral-0"
 		return
 	var/charge_percent = cell.charge / cell.maxcharge
 	if(charge_percent <= 0.6 && charge_percent>0.3)
 		. += "spectral-2"
 	else
 		. += "spectral-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 `@modular_bluemoon/fluffs/code/guns.dm` around lines 1583 - 1598, In
update_overlays(), the check using istype(ammo_type[current_firemode_index],
/obj/item/ammo_casing/energy/temp/hot) is incorrect because ammo_type[...] is a
typepath not an instance; replace that istype(...) call with
ispath(ammo_type[current_firemode_index], /obj/item/ammo_casing/energy/temp/hot)
so the conditional correctly tests the typepath; update the condition in the
function update_overlays to use ispath for the ammo_type lookup.

1484-1496: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Критические проблемы в update_overlays(): потеря оверлеев родителя и неверная проверка типа.

  1. Строки 1484–1486: вызов ..() без присваивания, а затем перезапись . = list() приводит к потере всех оверлеев, которые добавил родительский /obj/item/gun/energy. Родительский метод может добавлять важные оверлеи (например, фонарик через get_gunlight_overlay()). Необходимо присвоить результат родительского вызова в . и работать с этим списком.

  2. Строка 1491: istype(ammo_type[current_firemode_index], ...) — неверно. ammo_type[current_firemode_index] возвращает типпас (путь к типу), а не экземпляр объекта. Для проверки типпасов используется ispath(), а не istype().

🔧 Исправление обеих проблем
 /obj/item/gun/energy/e_gun/nuclear/quasar/update_overlays()
-	..()
-	. = list()
+	. = ..()
 	if(!cell || cell.charge <= 0 || !cell.maxcharge)
 		. += "quasar-0"
 		return
 	var/ratio = CEILING((cell.charge / cell.maxcharge) * 8, 1)
-	if(istype(ammo_type[current_firemode_index], /obj/item/ammo_casing/energy/laser))
+	if(ispath(ammo_type[current_firemode_index], /obj/item/ammo_casing/energy/laser))
 		. += "quasar-lethal-mode-base"
 	else
 		. += "quasar-non-lethal-mode-base"
 	if(ratio < 8)
 		. += "quasar-[ratio]"
🤖 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 `@modular_bluemoon/fluffs/code/guns.dm` around lines 1484 - 1496, The
update_overlays() override is clobbering parent overlays and mis-checking ammo
types: assign the parent's overlays by capturing the return of ..() into .
instead of calling ..() then doing `. = list()` (so preserve overlays added by
/obj/item/gun/energy), and replace the istype(ammo_type[current_firemode_index],
...) check with an ispath(...) check because ammo_type[current_firemode_index]
is a typepath not an instance; update the conditional accordingly in
update_overlays().
🧹 Nitpick comments (1)
modular_bluemoon/fluffs/code/guns.dm (1)

1595-1598: 💤 Low value

Необычная логика выбора оверлея заряда.

Текущая логика (строка 1595): при 30–60% заряда отображается spectral-2, при <30% или >60% — spectral-1. Это означает, что и очень низкий заряд (<30%), и высокий заряд (>60%) показывают один и тот же оверлей -1, а средний диапазон — -2.

Обычно в играх принято: низкий заряд → низкий номер оверлея, высокий заряд → высокий номер. Если текущая логика не является намеренным дизайнерским решением (например, где -1 = норма, -2 = предупреждение о среднем заряде), рекомендую пересмотреть пороги.

💡 Возможная альтернатива (если требуется типичная логика)
 	var/charge_percent = cell.charge / cell.maxcharge
-	if(charge_percent <= 0.6 && charge_percent>0.3)
+	if(charge_percent > 0.6)
 		. += "spectral-2"
 	else
 		. += "spectral-1"

Это даст: >60% → spectral-2, ≤60% → spectral-1 (0% уже обработан выше и возвращает spectral-0).

🤖 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 `@modular_bluemoon/fluffs/code/guns.dm` around lines 1595 - 1598, Логика выбора
оверлея по charge_percent некорректно инвертирована: сейчас 30–60% выдаёт
"spectral-2", а <30% и >60% — "spectral-1"; измените условие так, чтобы при
высоком заряде (>0.6) добавлялся "spectral-2", иначе (<=0.6) — "spectral-1"
(учтите, что "spectral-0" обрабатывается выше); исправьте ветвление вокруг
переменной charge_percent в том участке кода.
🤖 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.

Outside diff comments:
In `@modular_bluemoon/fluffs/code/guns.dm`:
- Around line 1583-1598: In update_overlays(), the check using
istype(ammo_type[current_firemode_index], /obj/item/ammo_casing/energy/temp/hot)
is incorrect because ammo_type[...] is a typepath not an instance; replace that
istype(...) call with ispath(ammo_type[current_firemode_index],
/obj/item/ammo_casing/energy/temp/hot) so the conditional correctly tests the
typepath; update the condition in the function update_overlays to use ispath for
the ammo_type lookup.
- Around line 1484-1496: The update_overlays() override is clobbering parent
overlays and mis-checking ammo types: assign the parent's overlays by capturing
the return of ..() into . instead of calling ..() then doing `. = list()` (so
preserve overlays added by /obj/item/gun/energy), and replace the
istype(ammo_type[current_firemode_index], ...) check with an ispath(...) check
because ammo_type[current_firemode_index] is a typepath not an instance; update
the conditional accordingly in update_overlays().

---

Nitpick comments:
In `@modular_bluemoon/fluffs/code/guns.dm`:
- Around line 1595-1598: Логика выбора оверлея по charge_percent некорректно
инвертирована: сейчас 30–60% выдаёт "spectral-2", а <30% и >60% — "spectral-1";
измените условие так, чтобы при высоком заряде (>0.6) добавлялся "spectral-2",
иначе (<=0.6) — "spectral-1" (учтите, что "spectral-0" обрабатывается выше);
исправьте ветвление вокруг переменной charge_percent в том участке кода.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a59da19b-afc9-43f8-9fb3-e7f180154a8a

📥 Commits

Reviewing files that changed from the base of the PR and between 31a4ae7 and af790ff.

📒 Files selected for processing (3)
  • modular_bluemoon/fluffs/code/guns.dm
  • modular_bluemoon/fluffs/code/storage.dm
  • modular_bluemoon/fluffs/icons/obj/48x32.dmi
🚧 Files skipped from review as they are similar to previous changes (1)
  • modular_bluemoon/fluffs/code/storage.dm

@Lev1932
Copy link
Copy Markdown
Author

Lev1932 commented May 30, 2026

@coderabbitai Текущая логика (строка 1595): при 30–60% заряда отображается spectral-2, при <30% или >60% — spectral-1. Это означает, что и очень низкий заряд (<30%), и высокий заряд (>60%) показывают один и тот же оверлей -1, а средний диапазон — -2. При старой логике при высоком и среднем были одинаковые. Добавил проверку чтобы низкий был только когда менее 30%

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 30, 2026

Tip

For best results, initiate chat on the files or code changes.

@Lev1932 Всё верно — старая логика была сломана в обоих направлениях: сначала высокий и средний были одинаковы, потом после правки высокий и низкий оказались одинаковы. Твой фикс закрывает именно это: теперь spectral-1 — только низкий заряд (<30%), а spectral-2 — высокий (>60%). Три чётко разных состояния вместо путаницы. Правильно.

ʕ •ᴥ•ʔ

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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 `@modular_bluemoon/fluffs/code/guns.dm`:
- Around line 966-967: Вычисление индикатора заполнения неверно из‑за лишнего
"+1"; замените выражение на вычисление текущих патронов как
magazine.stored_ammo.len + (magazine.chambered ? 1 : 0) (или соответствующее
поле/метод, указывающий наличие патрона в патроннике), затем округляйте
round(min(current_ammo, magazine.max_ammo) / magazine.max_ammo * 7) и
подставляйте result в строку "Nebular-9-ammo-[fill_level]". Используйте
уникальные символы magazine.stored_ammo.len, magazine.max_ammo,
magazine.chambered и переменную fill_level при замене.
🪄 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: 4b7b1ace-4108-4445-a7e1-e820a041f3f9

📥 Commits

Reviewing files that changed from the base of the PR and between 970e372 and cede1af.

📒 Files selected for processing (2)
  • modular_bluemoon/fluffs/code/guns.dm
  • modular_bluemoon/fluffs/code/storage.dm
🚧 Files skipped from review as they are similar to previous changes (1)
  • modular_bluemoon/fluffs/code/storage.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