Conversation
WalkthroughПеренос видимости на GetVisMaskEvent/RefreshVisibilityMask; добавлены болезнь WetHands с эффектами смазки и выпадения предметов, новые компоненты и эффекты болезни; интеграция чтения бумаги с болезнями; рефакторинг Fugitive/PNV, правки прототипов, локализаций и логики ID-карт SuperPsi. Changes
Sequence Diagram(s)sequenceDiagram
participant Reader as Player (Reader)
participant PaperSys as PaperSystem
participant DiseaseShared as SharedDiseaseSystem
participant DiseaseSrv as DiseaseSystem
participant EffectSys as DiseaseEffectSystem
participant LubeSys as DiseaseLubeHandsSystem
Reader->>PaperSys: открыть бумагу (BeforeUIOpen)
PaperSys->>DiseaseShared: OnPaperRead(ent)
DiseaseShared->>DiseaseSrv: уведомление о чтении
DiseaseSrv->>EffectSys: сгенерировать эффект (MemeticAmirmir) (25% шанс)
EffectSys-->>DiseaseSrv: применить эффект, создать/обновить DiseaseLubeHandsComponent
DiseaseSrv->>LubeSys: компонент присоединён (события AfterInteract)
Note over LubeSys,Reader: при взаимодействии LubeSys может нанести LubedComponent на предмет
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
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: 9
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
Content.Server/Backmen/Fugitive/FugitiveSystem.cs (1)
288-300: Дублирование добавления ролиFugitiveMindRole.Роль
FugitiveMindRoleдобавляется дважды:
- Строка 288:
_roleSystem.MindAddRole(mindId, FugitiveMindRole, mind, true);- Строка 299:
_roleSystem.MindAddRole(mindId, FugitiveMindRole, mind, true);Второй вызов на строке 299, вероятно, должен добавлять
JobRoleComponentдляFugitiveRole, а не дублироватьFugitiveMindRole.🐛 Предлагаемое исправление
_roleSystem.MindAddRole(mindId, FugitiveMindRole, mind, true); _mindSystem.TryAddObjective(mindId, mind, EscapeObjective); if (_prototypeManager.TryIndex<JobPrototype>(FugitiveRole, out _)) { if (_roleSystem.MindHasRole<JobRoleComponent>(mindId)) { _roleSystem.MindRemoveRole<JobRoleComponent>(mindId); } - _roleSystem.MindAddRole(mindId, FugitiveMindRole, mind, true); + _roleSystem.MindAddJobRole(mindId, jobPrototype: FugitiveRole); }
🤖 Fix all issues with AI agents
In `@Content.Server/Backmen/Disease/DiseaseSystem.cs`:
- Around line 119-120: Комментарий над условием с вероятностью заболевания не
соответствует коду: комментарий говорит про 25%, а выражение использует
_random.Prob(0.40f) (40%). Исправьте несоответствие в классе DiseaseSystem: либо
обновите комментарий, чтобы отражал 40%, либо измените вызов _random.Prob(...)
на 0.25f чтобы соответствовать 25%; отредактируйте строку с _random.Prob и
сопровождающий комментарий вместе, чтобы они всегда совпадали.
- Around line 69-70: The PaperWriteEvent subscription on DiseaseCarrierComponent
won't fire because the event is raised on the paper entity; update the
SubscribeLocalEvent call in DiseaseSystem to subscribe PaperWriteEvent for
PaperComponent (or otherwise route/forward the event from the paper to the
reader) so OnPaperRead is invoked when paper is written, and change the spawn
chance used in OnPaperRead from 0.40f to 0.25f to match the "25% chance"
comment; ensure you update any references to DiseaseCarrierComponent,
PaperComponent, PaperWriteEvent, and the OnPaperRead handler accordingly.
In `@Content.Server/Backmen/Disease/Effects/DiseaseApplyLube.cs`:
- Around line 74-88: В методе OnAfterInteract (в котором обрабатывается
Entity<DiseaseLubeHandsComponent> и параметр ref AfterInteractEvent args) нужно
добавить проверку достижимости цели: если args.CanReach == false — немедленно
вернуть; это предотвратит применение эффекта к недостижимым/закрытым объектам и
сохранить существующие проверки (ItemComponent, LubedComponent, LubeChance).
- Around line 49-59: The DiseaseApplyLube effect currently adds
DiseaseLubeHandsComponent in DiseaseApplyLube but never removes it on cure; wire
up removal by adding the existing RemoveDiseaseLubeHandsEntityEffect to the
disease prototype's cures list (or alternatively remove
DiseaseLubeHandsComponent when disease stage changes/cured). Update the disease
prototype configuration to include RemoveDiseaseLubeHandsEntityEffect under
cures, or add code in the cure/stage transition handler to
RemoveComp<DiseaseLubeHandsComponent> from the args.DiseasedEntity so the
component is cleaned up when the disease is cured.
In `@Content.Server/Backmen/Disease/Effects/DiseaseDropItems.cs`:
- Around line 32-59: В методе DiseaseDropItems вы сейчас помечаете args.Handled
= true и сразу возвращаете после вызова _handsSystem.TryDrop для активной руки,
даже если TryDrop вернул false; исправьте логику: не устанавливайте args.Handled
заранее и не возвращайте сразу после попытки дропа — вызывайте
_handsSystem.TryDrop для active hand и только если он вернул true установить
args.Handled = true и return; если TryDrop вернул false продолжать проверять
другие руки (цикл по hands.Hands.Keys) и также устанавливать args.Handled = true
и прекращать поиск только при успешном дропе.
In `@Content.Server/Backmen/Fugitive/FugitiveSystem.cs`:
- Around line 101-105: Выполни дедупликацию вызова эффектов: либо перемести
вызов DoSpawnEffects исключительно в обработчик OnSpawned
(GhostRoleSpawnerUsedEvent) и убери его из InitFugitive (MindAddedMessage), либо
добавь булев флаг (например SpawnEffectsDone) в компонент (FugitiveComponent или
FugitiveCountdownComponent) и проверяй его перед вызовом DoSpawnEffects в обоих
местах; при первом вызове устанавливай флаг в true, чтобы последующие вызовы (из
InitFugitive или OnSpawned) были пропущены; обнови места с ссылками на
DoSpawnEffects, OnSpawned, InitFugitive, GhostRoleSpawnerUsedEvent,
MindAddedMessage и FirstMindAdded.
In `@Content.Shared/Backmen/Abilities/Psionics/Items/PsionicItemsSystem.cs`:
- Around line 45-46: Проблема: HasStatusEffect вызывается с uid (шляпа) вместо
цели (игрок), поэтому проверка статуса всегда ложная и
RemComp<PsionicInsulationComponent>(args.Equipee) удаляет компонент неправильно;
исправьте вызов HasStatusEffect чтобы проверять статус
StatusEffectPsionicallyInsulated на args.Equipee (или на entity =
args.Equipee.Value/args.EquipeeId в зависимости от типа), оставив
RemComp<PsionicInsulationComponent>(args.Equipee) без изменений и добавив
необходимую проверку на null/валидность args.Equipee перед вызовом.
In `@Content.Shared/Backmen/Eye/NightVision/Systems/PNVSystem.cs`:
- Around line 45-46: При снятии ночного зрения сбрасывайте nvcomp.IsGranted =
false до вызова UpdateIsNightVision, чтобы избежать "лишнего тика" активного NV;
поправьте оба места в PNVSystem (где сейчас nvcomp.IsGranted = true / компонент
снимается deferred) — установите IsGranted = false перед вызовом
UpdateIsNightVision (или перед удалением компонента) для соответствующих веток
кода.
In `@Resources/Prototypes/_Backmen/Reagents/dry_hands.yml`:
- Around line 9-13: Переименуйте реактивную группу 'Acidic' в семантически
подходящее имя (например 'Medicine' или 'Cure') для записи reactiveEffects, так
как текущая группа предназначена для повреждающих эффектов и не подходит для
лечебного эффекта RemoveDiseaseLubeHandsEntityEffect; откройте запись,
содержащую reactiveEffects с methods: [ Touch ] и эффектом
RemoveDiseaseLubeHandsEntityEffect и замените ключ группы 'Acidic' на выбранное
имя, затем выполните поиск по проекту на вхождения 'Acidic' в контексте
реактивных групп и при необходимости обновите ссылки/документацию, чтобы
согласовать семантику.
🧹 Nitpick comments (6)
Content.Server/Backmen/Antag/SuperPsi/AutoPsiSystem.cs (1)
177-190: Магическое число40дублируется, рекомендуется извлечь в константу.
TimeSpan.FromMinutes(40)используется дважды (строки 184 и 188). Для улучшения поддерживаемости и согласованности рекомендуется вынести это значение в константу.♻️ Предлагаемое исправление
+ private static readonly TimeSpan DefaultSentenceDuration = TimeSpan.FromMinutes(40); + private void ConfIdCard(EntityUid ent) { if (_idCardSystem.TryFindIdCard(ent, out var idCard)) { if (TryComp<GenpopIdCardComponent>(idCard, out var id)) { id.Crime = Loc.GetString("genpop-prisoner-id-crime-default"); - id.SentenceDuration = TimeSpan.FromMinutes(40); + id.SentenceDuration = DefaultSentenceDuration; Dirty(idCard, id); } _idCardSystem.SetPermanent(idCard.Owner, true); - _idCardSystem.SetExpireTime(idCard.Owner, TimeSpan.FromMinutes(40) + _timing.CurTime); + _idCardSystem.SetExpireTime(idCard.Owner, DefaultSentenceDuration + _timing.CurTime); } }Content.Server/Backmen/Ghost/GhostReJoinSystem.cs (1)
212-216: Вероятность 60% - магическое число без документации.Добавление
FugitiveComponentк 60% респавнов призраков — это значительное игровое изменение. Рекомендации:
- Вынести значение
0.6fв конфигурируемый параметр (CCVar) для гибкой настройки.- Добавить комментарий, объясняющий игровую логику этого решения.
- Убедиться, что это намеренное поведение — игроки, вернувшиеся в раунд как призраки, получают статус беглеца.
♻️ Предлагаемое решение: вынести в CCVar
+ // В CCVars: + public static readonly CVarDef<float> GhostRespawnFugitiveChance = + CVarDef.Create("ghost.respawn_fugitive_chance", 0.6f, CVar.SERVERONLY);- if (_random.Prob(0.6f)) + if (_random.Prob(_configurationManager.GetCVar(CCVars.GhostRespawnFugitiveChance))) { EnsureComp<FugitiveComponent>(ev.Mob); }Content.Server/Backmen/Species/Shadowkin/Systems/ShadowkinPowerSystem.DarkSwap.cs (1)
338-345: Подозрительный паттерн с StealthComponent.Логика удаления, создания, установки и повторного удаления
StealthComponentвыглядит избыточной и неочевидной. Комментарий "Just to be sure..." указывает на неуверенность в корректности.Если цель — гарантировать сброс stealth-эффекта, рассмотрите упрощение:
♻️ Предлагаемое исправление
- // Remove the stealth shader from the entity - //if (!HasComp<GhostComponent>(uid)) - RemComp<StealthComponent>(uid); - // Just to be sure... - var stealth = EnsureComp<StealthComponent>(uid); - _stealth.SetVisibility(uid, 1f, stealth); - RemComp<StealthComponent>(uid); + // Remove the stealth shader from the entity + if (TryComp<StealthComponent>(uid, out var stealth)) + { + _stealth.SetVisibility(uid, 1f, stealth); + RemComp<StealthComponent>(uid); + }Content.Server/Backmen/Abilities/Psionics/Abilities/MetapsionicPowerSystem.cs (1)
58-75: Аналогичная несогласованность в OnAddCanSeeAll.Тот же паттерн:
RefreshVisibilityMaskдля psionic-видимости, но ручная обработка DarkSwapInvisibility. ЕслиShadowkinDarkSwappedComponentимеет собственный обработчикGetVisMaskEvent, эта логика может быть унифицирована.Content.Shared/Backmen/Eye/NightVision/Components/NightVisionComponent.cs (1)
33-34: Рассмотрите добавление атрибутов для IsGranted.Поле
IsGrantedне имеет атрибутов[DataField]и[AutoNetworkedField]. Если это состояние должно сохраняться или синхронизироваться между клиентом и сервером (какIsNightVisionна строке 13-14), добавьте соответствующие атрибуты.♻️ Возможное исправление
- public bool IsGranted = false; + [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] + public bool IsGranted = false;Resources/Prototypes/Entities/Mobs/Player/observer.yml (1)
63-101: Удалите избыточный список каналов.Свойство
receiveAllChannels: trueпереопределяет полеChannels, поэтому явный список каналов (строки 65-101) не используется и может быть удалён.
| SubscribeLocalEvent<DiseaseCarrierComponent, MobStateChangedEvent>(OnMobStateChanged); | ||
| SubscribeLocalEvent<DiseaseCarrierComponent, PaperWriteEvent>(OnPaperRead); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, find the DiseaseSystem.cs file and examine the context around lines 69-70
find . -name "DiseaseSystem.cs" -type fRepository: Rxup/space-station-14
Length of output: 206
🏁 Script executed:
# Search for PaperWriteEvent and PaperReadEvent definitions
rg -n --type=cs "class PaperWriteEvent|class PaperReadEvent" -A 3Repository: Rxup/space-station-14
Length of output: 47
🏁 Script executed:
# Search for places where these events are raised
rg -n --type=cs "RaiseLocalEvent.*PaperWriteEvent|RaiseLocalEvent.*PaperReadEvent" -B 2 -A 2Repository: Rxup/space-station-14
Length of output: 47
🏁 Script executed:
# Search for subscriptions to these events
rg -n --type=cs "SubscribeLocalEvent.*PaperWriteEvent|SubscribeLocalEvent.*PaperReadEvent" -B 2 -A 2Repository: Rxup/space-station-14
Length of output: 1125
🏁 Script executed:
# Find PaperWriteEvent definition
rg -n --type=cs "record PaperWriteEvent|class PaperWriteEvent|struct PaperWriteEvent" -A 5Repository: Rxup/space-station-14
Length of output: 551
🏁 Script executed:
# Find the OnPaperRead handler in DiseaseSystem.cs
rg -n --type=cs "OnPaperRead" -B 2 -A 10Repository: Rxup/space-station-14
Length of output: 2600
🏁 Script executed:
# Find where PaperWriteEvent is raised
rg -n --type=cs "RaiseLocalEvent.*PaperWriteEvent|EntityManager\.RaiseLocalEvent.*PaperWriteEvent" -B 3 -A 1Repository: Rxup/space-station-14
Length of output: 47
🏁 Script executed:
# Look at the DiseaseSystem.cs file around lines 106-118, 121-123
sed -n '100,130p' ./Content.Server/Backmen/Disease/DiseaseSystem.csRepository: Rxup/space-station-14
Length of output: 1069
🏁 Script executed:
# Search for where PaperWriteEvent is raised in the codebase
rg -n --type=cs "new PaperWriteEvent|RaiseLocalEvent.*new PaperWriteEvent" -B 5 -A 2Repository: Rxup/space-station-14
Length of output: 607
🏁 Script executed:
# Look for PaperSystem to understand when PaperWriteEvent is raised
rg -n --type=cs "PaperWriteEvent" Content.Shared/Paper/PaperSystem.cs -B 3 -A 3Repository: Rxup/space-station-14
Length of output: 1135
🏁 Script executed:
# Check the ActivateOnPaperOpenedComponent subscription to understand the pattern
sed -n '45,60p' Content.Shared/Paper/PaperSystem.csRepository: Rxup/space-station-14
Length of output: 648
Исправьте подписку на событие и вероятность срабатывания.
Подписка на PaperWriteEvent со стороны DiseaseCarrierComponent никогда не сработает: событие поднимается на сущности бумаги (строка 146 в Content.Shared/Paper/PaperSystem.cs: RaiseLocalEvent(args.Used, ref writeEvent)), а компонент находится на читателе. Нужно либо подписаться на PaperComponent, либо использовать другой механизм перехвата действия пользователя.
Также в комментарии указано "25% chance", но код использует 0.40f (40%), что не соответствует документации.
🤖 Prompt for AI Agents
In `@Content.Server/Backmen/Disease/DiseaseSystem.cs` around lines 69 - 70, The
PaperWriteEvent subscription on DiseaseCarrierComponent won't fire because the
event is raised on the paper entity; update the SubscribeLocalEvent call in
DiseaseSystem to subscribe PaperWriteEvent for PaperComponent (or otherwise
route/forward the event from the paper to the reader) so OnPaperRead is invoked
when paper is written, and change the spawn chance used in OnPaperRead from
0.40f to 0.25f to match the "25% chance" comment; ensure you update any
references to DiseaseCarrierComponent, PaperComponent, PaperWriteEvent, and the
OnPaperRead handler accordingly.
| private void DiseaseApplyLube(Entity<DiseaseCarrierComponent> ent, ref DiseaseEffectArgs<DiseaseApplyLube> args) | ||
| { | ||
| if(args.Handled) | ||
| return; | ||
| args.Handled = true; | ||
|
|
||
| // Add component that will handle interaction events and store effect parameters | ||
| var component = EnsureComp<DiseaseLubeHandsComponent>(args.DiseasedEntity); | ||
| component.LubeChance = args.DiseaseEffect.LubeChance; | ||
| component.Slips = args.DiseaseEffect.Slips; | ||
| component.SlipStrength = args.DiseaseEffect.SlipStrength; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Search for DiseaseLubeHandsComponent usage and removal
rg -n --type=cs "DiseaseLubeHandsComponent" -B 2 -A 2
# Search for any removal or cleanup related to this component
rg -n --type=cs -i "RemoveDiseaseLubeHands|remove.*lube.*hands|DiseaseLubeHandsComponent.*remove"
# Look for disease cure/removal handlers
rg -n --type=cs "DiseaseCure|RemoveDisease" -B 2 -A 2Repository: Rxup/space-station-14
Length of output: 20204
🏁 Script executed:
#!/bin/bash
# Search for disease prototype definitions (YAML files)
fd -e yml -e yaml | xargs grep -l "RemoveDiseaseLubeHandsEntityEffect" 2>/dev/null
# Also search for disease prototype definitions and DiseaseApplyLube
fd -e yml -e yaml | xargs grep -l "DiseaseApplyLube" 2>/dev/null
# Check how entity effects are configured in disease system
rg -n "EntityEffect" Content.Shared/Backmen/Disease/ -A 3 -B 3Repository: Rxup/space-station-14
Length of output: 117
🏁 Script executed:
cat -n Resources/Prototypes/_Backmen/Reagents/dry_hands.ymlRepository: Rxup/space-station-14
Length of output: 623
🏁 Script executed:
#!/bin/bash
# Search for disease prototype files that use DiseaseApplyLube
fd -e yml -e yaml -path "*[Dd]isease*" | xargs grep -l "DiseaseApplyLube" 2>/dev/null
# Also search all YAML files for DiseaseApplyLube
find . -name "*.yml" -o -name "*.yaml" | xargs grep -l "DiseaseApplyLube" 2>/dev/null | head -20Repository: Rxup/space-station-14
Length of output: 305
🏁 Script executed:
cat -n ./Resources/Prototypes/_Backmen/Diseases/wet_hands.ymlRepository: Rxup/space-station-14
Length of output: 2227
🏁 Script executed:
#!/bin/bash
# Search for how disease system handles curing and cleanup
rg -n "CureDisease" Content.Server/Backmen/Disease/ -A 5 -B 2
# Check if there's an entity effect system and how it works
rg -n "EntityEffect" Content.Server/Backmen/Disease/ -A 3 -B 1
# Look for the DiseaseSystem class to understand cure mechanism
rg -n "class DiseaseSystem" Content.Server/Backmen/Disease/ -A 30Repository: Rxup/space-station-14
Length of output: 13740
🏁 Script executed:
#!/bin/bash
# Find the cure queue processing to see what happens when a disease is cured
rg -n "_cureQueue" Content.Server/Backmen/Disease/DiseaseSystem.cs -A 10 -B 2
# Look for the Update method or cure processing
rg -n "Update\|_cureQueue.Add" Content.Server/Backmen/Disease/DiseaseSystem.cs -A 15 -B 2Repository: Rxup/space-station-14
Length of output: 2089
🏁 Script executed:
#!/bin/bash
# Search for where entity effects are applied - are they applied during stage changes or cure?
rg -n "EntityEffect\|RemoveComp.*DiseaseEffect" Content.Server/Backmen/Disease/ -B 3 -A 3
# Check if there's any handling of disease stage progression or removal
rg -n "StageProgression\|stage change\|remove.*effect" Content.Server/Backmen/Disease/DiseaseSystem.cs -B 2 -A 5
# Look at the full Update method to understand the complete flow
sed -n '165,225p' Content.Server/Backmen/Disease/DiseaseSystem.csRepository: Rxup/space-station-14
Length of output: 2059
🏁 Script executed:
#!/bin/bash
# Search for how disease effects are applied - when are effects triggered?
rg -n "DiseaseEffect\|effects\|stage" Content.Server/Backmen/Disease/DiseaseSystem.cs -B 2 -A 2 | head -100
# Check if there's any system that applies entity effects on cure
rg -n "RemoveDiseaseLubeHandsEntityEffect" Content.Server/ Content.Shared/ -B 5 -A 5
# Look for how effects are triggered in the stage progression
rg -n "GetStage\|StageProgression" Content.Server/Backmen/Disease/DiseaseSystem.cs -B 3 -A 10Repository: Rxup/space-station-14
Length of output: 2254
🏁 Script executed:
#!/bin/bash
# Check how disease effects are applied - look for the disease effect system
rg -n "DiseaseEffectArgs\|DiseaseApplyLube" Content.Server/Backmen/Disease/DiseaseSystem.cs -B 3 -A 5
# Look at what triggers disease effects
rg -n "RaiseLocalEvent.*DiseaseEffect" Content.Server/Backmen/Disease/ -B 2 -A 2
# Check if disease has any cure effects defined
rg -n "class.*Effect\|DiseaseEffect" Content.Server/Backmen/Disease/Effects/ -l
# Look more specifically at DiseaseApplyLube to understand the pattern
cat -n Content.Server/Backmen/Disease/Effects/DiseaseApplyLube.cs | head -80Repository: Rxup/space-station-14
Length of output: 3276
🏁 Script executed:
#!/bin/bash
# Check if entity effects are supposed to be applied on cure - search for cure effects
rg -n "cure.*effect\|effect.*cure" Content.Server/Backmen/Disease/ -i -B 2 -A 2
# Search disease prototype to see if there are cure effects
rg -n "cure.*effect" Resources/Prototypes/_Backmen/Diseases/ -B 3 -A 3
# Check DiseasePrototype definition for cure effects
rg -n "class DiseasePrototype\|cures\|effects" Content.Shared/Backmen/Disease/DiseasePrototype.cs -B 1 -A 3Repository: Rxup/space-station-14
Length of output: 47
🏁 Script executed:
#!/bin/bash
# Look at DiseasePrototype to understand the full structure
cat -n Content.Shared/Backmen/Disease/DiseasePrototype.cs | head -100
# Check how disease stages and effects work
rg -n "stage\|Stage" Content.Shared/Backmen/Disease/DiseasePrototype.cs -B 2 -A 2Repository: Rxup/space-station-14
Length of output: 3665
🏁 Script executed:
#!/bin/bash
# Check if there's a cure effects system or if effects are applied on cure
rg -n "cure.*effect\|CureEffect" Content.Server/Backmen/Disease/ Content.Shared/Backmen/Disease/ -i
# Search for where effects are actually triggered - look at DiseaseEffectSystem
rg -n "class DiseaseEffectSystem" Content.Server/Backmen/Disease/ -A 50 | head -80
# Check if there's any mechanism to run effects on cure
fd -e cs | xargs grep -l "DiseaseEffect\|cure" | xargs rg -n "RaiseLocalEvent.*DiseaseEffect" -B 3 -A 3Repository: Rxup/space-station-14
Length of output: 8509
🏁 Script executed:
#!/bin/bash
# Check if wet_hands disease has any cure effects defined
cat -n Resources/Prototypes/_Backmen/Diseases/wet_hands.yml
# Search for any cure effects in disease prototypes
rg -n "cureEffect\|cure.*effect" Resources/Prototypes/_Backmen/Diseases/ -i -B 2 -A 2
# Check how disease cures work - do they trigger entity effects?
rg -n "RaiseLocalEvent.*Cure\|cure.*effect" Content.Server/Backmen/Disease/ -i -B 2 -A 3Repository: Rxup/space-station-14
Length of output: 2227
🏁 Script executed:
#!/bin/bash
# Check if stage downgrade/progression removes effects
rg -n "stage.*change\|progression\|downgrade" Content.Server/Backmen/Disease/DiseaseSystem.cs -i -B 3 -A 5
# Look at where disease effects are applied - they're applied each tick?
rg -n "foreach.*effect\|RaiseLocalEvent.*DiseaseEffect" Content.Server/Backmen/Disease/DiseaseSystem.cs -B 2 -A 3
# Get the full picture of the Update method to see effect application
sed -n '230,280p' Content.Server/Backmen/Disease/DiseaseSystem.csRepository: Rxup/space-station-14
Length of output: 1609
🏁 Script executed:
#!/bin/bash
# Continue reading the Process method to see where disease effects are applied
sed -n '280,320p' Content.Server/Backmen/Disease/DiseaseSystem.csRepository: Rxup/space-station-14
Length of output: 1114
Добавьте удаление компонента при излечении болезни.
RemoveDiseaseLubeHandsEntityEffect существует, но не настроен в прототипе болезни. При излечении WetHands компонент DiseaseLubeHandsComponent остаётся навсегда. Добавьте эффект удаления в раздел cures протокола болезни или обработайте удаление при смене стадии болезни.
🤖 Prompt for AI Agents
In `@Content.Server/Backmen/Disease/Effects/DiseaseApplyLube.cs` around lines 49 -
59, The DiseaseApplyLube effect currently adds DiseaseLubeHandsComponent in
DiseaseApplyLube but never removes it on cure; wire up removal by adding the
existing RemoveDiseaseLubeHandsEntityEffect to the disease prototype's cures
list (or alternatively remove DiseaseLubeHandsComponent when disease stage
changes/cured). Update the disease prototype configuration to include
RemoveDiseaseLubeHandsEntityEffect under cures, or add code in the cure/stage
transition handler to RemoveComp<DiseaseLubeHandsComponent> from the
args.DiseasedEntity so the component is cleaned up when the disease is cured.
| private void OnAfterInteract(Entity<DiseaseLubeHandsComponent> entity, ref AfterInteractEvent args) | ||
| { | ||
| if (args.Handled || args.Target is not { Valid: true } target) | ||
| return; | ||
|
|
||
| // DiseaseLubeHandsComponent should only apply to entities with ItemComponent | ||
| if (!HasComp<ItemComponent>(target)) | ||
| return; | ||
|
|
||
| // Don't apply to already lubed items | ||
| if (HasComp<LubedComponent>(target)) | ||
| return; | ||
|
|
||
| if (!_random.Prob(entity.Comp.LubeChance)) | ||
| return; |
There was a problem hiding this comment.
Добавьте проверку достижимости цели при взаимодействии.
Без args.CanReach можно “смазывать” предметы на дистанции/через препятствия, т.к. AfterInteractEvent может приходить и при недостижимой цели.
🩹 Вариант правки
if (args.Handled || args.Target is not { Valid: true } target)
return;
+ if (!args.CanReach)
+ return;🤖 Prompt for AI Agents
In `@Content.Server/Backmen/Disease/Effects/DiseaseApplyLube.cs` around lines 74 -
88, В методе OnAfterInteract (в котором обрабатывается
Entity<DiseaseLubeHandsComponent> и параметр ref AfterInteractEvent args) нужно
добавить проверку достижимости цели: если args.CanReach == false — немедленно
вернуть; это предотвратит применение эффекта к недостижимым/закрытым объектам и
сохранить существующие проверки (ItemComponent, LubedComponent, LubeChance).
| private void DiseaseDropItems(Entity<DiseaseCarrierComponent> ent, ref DiseaseEffectArgs<DiseaseDropItems> args) | ||
| { | ||
| if(args.Handled) | ||
| return; | ||
| args.Handled = true; | ||
|
|
||
| if (!_random.Prob(args.DiseaseEffect.DropChance)) | ||
| return; | ||
|
|
||
| if (!TryComp<HandsComponent>(args.DiseasedEntity, out var hands)) | ||
| return; | ||
|
|
||
| Entity<HandsComponent?> handsEntity = (args.DiseasedEntity, hands); | ||
|
|
||
| // Try to drop from active hand first, then any hand | ||
| if (hands.ActiveHandId != null && _handsSystem.TryGetHeldItem(handsEntity, hands.ActiveHandId, out _)) | ||
| { | ||
| _handsSystem.TryDrop(handsEntity, hands.ActiveHandId, checkActionBlocker: false); | ||
| return; | ||
| } | ||
|
|
||
| // Drop from any hand | ||
| foreach (var handId in hands.Hands.Keys) | ||
| { | ||
| if (_handsSystem.TryGetHeldItem(handsEntity, handId, out _)) | ||
| { | ||
| _handsSystem.TryDrop(handsEntity, handId, checkActionBlocker: false); | ||
| break; |
There was a problem hiding this comment.
Не прерывайте обработку, если TryDrop не удался.
Сейчас при активной руке вы вызываете TryDrop и сразу выходите, даже если дроп не произошёл. Это может свести эффект на нет, хотя в других руках есть предметы. Лучше возвращаться только при успешном дропе и выставлять Handled именно тогда.
🩹 Вариант правки
- if(args.Handled)
+ if (args.Handled)
return;
- args.Handled = true;
if (!_random.Prob(args.DiseaseEffect.DropChance))
return;
@@
// Try to drop from active hand first, then any hand
if (hands.ActiveHandId != null && _handsSystem.TryGetHeldItem(handsEntity, hands.ActiveHandId, out _))
{
- _handsSystem.TryDrop(handsEntity, hands.ActiveHandId, checkActionBlocker: false);
- return;
+ if (_handsSystem.TryDrop(handsEntity, hands.ActiveHandId, checkActionBlocker: false))
+ {
+ args.Handled = true;
+ return;
+ }
}
@@
foreach (var handId in hands.Hands.Keys)
{
if (_handsSystem.TryGetHeldItem(handsEntity, handId, out _))
{
- _handsSystem.TryDrop(handsEntity, handId, checkActionBlocker: false);
- break;
+ if (_handsSystem.TryDrop(handsEntity, handId, checkActionBlocker: false))
+ {
+ args.Handled = true;
+ break;
+ }
}
}🤖 Prompt for AI Agents
In `@Content.Server/Backmen/Disease/Effects/DiseaseDropItems.cs` around lines 32 -
59, В методе DiseaseDropItems вы сейчас помечаете args.Handled = true и сразу
возвращаете после вызова _handsSystem.TryDrop для активной руки, даже если
TryDrop вернул false; исправьте логику: не устанавливайте args.Handled заранее и
не возвращайте сразу после попытки дропа — вызывайте _handsSystem.TryDrop для
active hand и только если он вернул true установить args.Handled = true и
return; если TryDrop вернул false продолжать проверять другие руки (цикл по
hands.Hands.Keys) и также устанавливать args.Handled = true и прекращать поиск
только при успешном дропе.
| if (!_statusEffects.HasStatusEffect(uid, "StatusEffectPsionicallyInsulated")) | ||
| RemComp<PsionicInsulationComponent>(args.Equipee); |
There was a problem hiding this comment.
Баг: проверка статус-эффекта выполняется на неправильной сущности.
Метод HasStatusEffect вызывается с uid (сущность шляпы), но статус-эффект StatusEffectPsionicallyInsulated применяется к игроку (args.Equipee). Это приведёт к тому, что проверка всегда будет возвращать false, и компонент PsionicInsulationComponent будет удаляться всегда, даже если у игрока есть другой источник псионической изоляции через статус-эффект.
🐛 Предлагаемое исправление
- if (!_statusEffects.HasStatusEffect(uid, "StatusEffectPsionicallyInsulated"))
+ if (!_statusEffects.HasStatusEffect(args.Equipee, "StatusEffectPsionicallyInsulated"))
RemComp<PsionicInsulationComponent>(args.Equipee);📝 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.
| if (!_statusEffects.HasStatusEffect(uid, "StatusEffectPsionicallyInsulated")) | |
| RemComp<PsionicInsulationComponent>(args.Equipee); | |
| if (!_statusEffects.HasStatusEffect(args.Equipee, "StatusEffectPsionicallyInsulated")) | |
| RemComp<PsionicInsulationComponent>(args.Equipee); |
🤖 Prompt for AI Agents
In `@Content.Shared/Backmen/Abilities/Psionics/Items/PsionicItemsSystem.cs` around
lines 45 - 46, Проблема: HasStatusEffect вызывается с uid (шляпа) вместо цели
(игрок), поэтому проверка статуса всегда ложная и
RemComp<PsionicInsulationComponent>(args.Equipee) удаляет компонент неправильно;
исправьте вызов HasStatusEffect чтобы проверять статус
StatusEffectPsionicallyInsulated на args.Equipee (или на entity =
args.Equipee.Value/args.EquipeeId в зависимости от типа), оставив
RemComp<PsionicInsulationComponent>(args.Equipee) без изменений и добавив
необходимую проверку на null/валидность args.Equipee перед вызовом.
| nvcomp.IsGranted = true; | ||
|
|
There was a problem hiding this comment.
Сброс IsGranted перед UpdateIsNightVision на снятии.
Сейчас UpdateIsNightVision вызывается при IsGranted=true, а компонент снимается deferred — возможен “лишний тик” активного NV.
🛠️ Предлагаемое исправление
- if(!nvcomp.IsGranted)
- return;
-
- _nightvisionableSystem.UpdateIsNightVision(args.Equipee, nvcomp);
+ if (!nvcomp.IsGranted)
+ return;
+ nvcomp.IsGranted = false;
+ _nightvisionableSystem.UpdateIsNightVision(args.Equipee, nvcomp);Also applies to: 71-72
🤖 Prompt for AI Agents
In `@Content.Shared/Backmen/Eye/NightVision/Systems/PNVSystem.cs` around lines 45
- 46, При снятии ночного зрения сбрасывайте nvcomp.IsGranted = false до вызова
UpdateIsNightVision, чтобы избежать "лишнего тика" активного NV; поправьте оба
места в PNVSystem (где сейчас nvcomp.IsGranted = true / компонент снимается
deferred) — установите IsGranted = false перед вызовом UpdateIsNightVision (или
перед удалением компонента) для соответствующих веток кода.
| reactiveEffects: | ||
| Acidic: | ||
| methods: [ Touch ] | ||
| effects: | ||
| - !type:RemoveDiseaseLubeHandsEntityEffect |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
echo "=== Searching for Touch method usage with different groups ==="
rg -n "methods:.*Touch" --type yaml -A 2 -B 2 | head -60
echo -e "\n=== Searching for Acidic group usage ==="
rg -n "Acidic:" --type yaml -A 5 | head -80
echo -e "\n=== Searching for Extinguish group usage ==="
rg -n "Extinguish:" --type yaml -A 5 | head -60
echo -e "\n=== Searching for RemoveDisease effects ==="
rg -n "RemoveDisease" --type yaml | head -40Repository: Rxup/space-station-14
Length of output: 14401
Переименуйте реактивную группу с Acidic на более подходящую.
Группа Acidic в проекте последовательно используется для повреждающих реакций с эффектами HealthChange. Применение её к лечебному эффекту RemoveDiseaseLubeHandsEntityEffect противоречит сложившемуся паттерну. Группа Extinguish предназначена для огня/холода и также не подходит. Рекомендуется выбрать или создать семантически подходящую группу для лечебных/противодействующих эффектов (например, Medicine или Cure), которая отражает назначение эффекта.
🤖 Prompt for AI Agents
In `@Resources/Prototypes/_Backmen/Reagents/dry_hands.yml` around lines 9 - 13,
Переименуйте реактивную группу 'Acidic' в семантически подходящее имя (например
'Medicine' или 'Cure') для записи reactiveEffects, так как текущая группа
предназначена для повреждающих эффектов и не подходит для лечебного эффекта
RemoveDiseaseLubeHandsEntityEffect; откройте запись, содержащую reactiveEffects
с methods: [ Touch ] и эффектом RemoveDiseaseLubeHandsEntityEffect и замените
ключ группы 'Acidic' на выбранное имя, затем выполните поиск по проекту на
вхождения 'Acidic' в контексте реактивных групп и при необходимости обновите
ссылки/документацию, чтобы согласовать семантику.
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
Content.Server/Backmen/Fugitive/FugitiveSystem.cs (1)
282-294: Дублирование вызоваMindAddRoleс идентичными параметрами.На строке 282 вызывается
_roleSystem.MindAddRole(mindId, FugitiveMindRole, mind, true)безусловно. Затем на строке 293 внутри блокаif (_prototypeManager.TryIndex<JobPrototype>(FugitiveRole, out _))выполняется идентичный вызов той же функции с теми же параметрами.Логика блока if (удаление
JobRoleComponentи повторное добавлениеFugitiveMindRole) выглядит ошибочной. Вероятно, вторая строка либо избыточна и должна быть удалена, либо должна добавлятьJobRoleComponentс рольюFugitiveRole, а не повторно добавлятьFugitiveMindRole.
🧹 Nitpick comments (1)
Content.Server/Backmen/Fugitive/FugitiveSystem.cs (1)
296-300: LGTM!Вызов
DoSpawnEffects(uid.AsNullable())корректен. Защита черезFirstMindAddedгарантирует однократное выполнение эффектов.Мелочь: опечатка в комментарии — "seperate" вместо "separate".
Summary by CodeRabbit
Примечания к выпуску
New Features
Bug Fixes
Documentation
✏️ Tip: You can customize this high-level summary in your review settings.