Add Mutatrix transformation device#833
Conversation
|
RSI Diff Bot; head commit 78d6a38 merging into 71115cd Resources/Textures/Mutatrix/Mobs/cortex.rsi
Resources/Textures/Mutatrix/Mobs/feralis.rsi
|
WalkthroughAdiciona um novo sistema "Mutatrix" completo: componentes/eventos compartilhados, UI client-side de menu radial, sistemas server-side para transformação/scanner/reversão, formas específicas (Besta, Chama, GreyMatter, QuatroBracos), protótipos YAML, texturas e localizações em en-US/pt-BR. Também estende ChangesSistema Mutatrix
Estimated code review effort: 4 (Complex) | ~75 minutes Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
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: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
Resources/Locale/pt-BR/mutatrix/besta.ftl (1)
1-3: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winCabeçalho SPDX ausente.
Todos os demais arquivos
.ftldeste PR incluem o cabeçalhoSPDX-FileCopyrightTexteSPDX-License-Identifier. Este arquivo está sem esses cabeçalhos, criando uma inconsistência de licenciamento.🔧 Correção proposta
+# SPDX-FileCopyrightText: 2026 Guilherme Galinha Azul <guilhermegalinhaazul@gmail.com> +# SPDX-License-Identifier: AGPL-3.0-or-later +# mutatrix-transformation-besta-name = Besta mutatrix-transformation-besta-desc = Uma forma cega e resistente que rastreia calor e ataca com garras.🤖 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 `@Resources/Locale/pt-BR/mutatrix/besta.ftl` around lines 1 - 3, The `besta.ftl` locale file is missing the same SPDX licensing header used by the other `.ftl` files in this PR. Add the standard `SPDX-FileCopyrightText` and `SPDX-License-Identifier` header at the top of this file, keeping the existing `mutatrix-transformation-besta-name` and `mutatrix-transformation-besta-desc` entries unchanged.Resources/Locale/pt-BR/mutatrix/greymatter.ftl (1)
1-3: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winCabeçalho SPDX ausente.
Assim como
besta.ftl, este arquivo não inclui o cabeçalhoSPDX-FileCopyrightTexteSPDX-License-Identifier, presente em todos os outros arquivos.ftldo PR.🔧 Correção proposta
+# SPDX-FileCopyrightText: 2026 Guilherme Galinha Azul <guilhermegalinhaazul@gmail.com> +# SPDX-License-Identifier: AGPL-3.0-or-later +# mutatrix-transformation-greymatter-name = Massa Cinzenta mutatrix-transformation-greymatter-desc = Forma pequena e inteligente. Enxerga no escuro, passa por baixo de obstáculos, usa ventilação, tem duas mãos e possui acesso técnico amplo à estação.🤖 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 `@Resources/Locale/pt-BR/mutatrix/greymatter.ftl` around lines 1 - 3, O arquivo greymatter.ftl está sem o cabeçalho SPDX exigido; adicione no topo os mesmos metadados presentes nos outros arquivos .ftl do PR, incluindo SPDX-FileCopyrightText e SPDX-License-Identifier. Use o padrão já aplicado em besta.ftl e nos demais arquivos de locale para manter consistência e localizar facilmente o ajuste no início do arquivo mutatrix-transformation-greymatter-name.
🧹 Nitpick comments (10)
Content.Server/Mutatrix/GreyMatter/Systems/MutatrixGreyMatterSystem.cs (1)
6-13: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueSistema vazio: considerar remoção ou documentar intenção de uso futuro.
O
MutatrixGreyMatterSystemestá registrado comoEntitySystemmas não contém lógica. Se as características da forma são puramente passivas (componentes de protótipo), o sistema não precisa existir a menos que haja planos de adicionar comportamento no futuro. Se for um placeholder, um comentário adicional esclarecendo a intenção evitaria confusão.🤖 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 `@Content.Server/Mutatrix/GreyMatter/Systems/MutatrixGreyMatterSystem.cs` around lines 6 - 13, MutatrixGreyMatterSystem is currently an empty EntitySystem, so either remove it if the grey matter traits are fully handled by passive prototype components, or document it clearly as an intentional placeholder for future behavior. Update the MutatrixGreyMatterSystem class to reflect the intended design: if no logic is needed, delete the empty system and its registration; if it must remain, add a brief comment on the class explaining why it exists.Content.Client/Mutatrix/Besta/BestaLimitedVisionOverlay.cs (1)
57-78: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low valueConsidere eliminar lookups redundantes de player/eye em
Draw.
BeforeDraw(linhas 40-44) já obtémplayerEntityeEyeComponent, masDrawrepete essas mesmas buscas (linhas 59 e 63). OEyeComponentpoderia ser armazenado em um campo junto com_visionpara evitar chamadas duplicadas deTryGetComponentpor frame.♻️ Refatoração sugerida
private readonly ShaderInstance _circleMaskShader; private BestaLimitedVisionComponent? _vision; + private EyeComponent? _eye; public BestaLimitedVisionOverlay() { IoCManager.InjectDependencies(this); // Draw early so other world-space overlays, like thermal effects, have a chance to draw over it. ZIndex = -50; _circleMaskShader = _prototypeManager.Index(CircleShader).InstanceUnique(); } protected override bool BeforeDraw(in OverlayDrawArgs args) { var playerEntity = _playerManager.LocalSession?.AttachedEntity; if (playerEntity == null) return false; - if (!_entityManager.TryGetComponent(playerEntity.Value, out EyeComponent? eyeComp)) + if (!_entityManager.TryGetComponent(playerEntity.Value, out EyeComponent? eyeComp)) return false; if (args.Viewport.Eye != eyeComp.Eye) return false; if (!_entityManager.TryGetComponent(playerEntity.Value, out BestaLimitedVisionComponent? vision)) return false; _vision = vision; + _eye = eyeComp; return true; } protected override void Draw(in OverlayDrawArgs args) { - var playerEntity = _playerManager.LocalSession?.AttachedEntity; - if (playerEntity == null || _vision == null) + if (_vision == null || _eye == null) return; - if (!_entityManager.TryGetComponent<EyeComponent>(playerEntity.Value, out var eye)) - return; - - _circleMaskShader.SetParameter("Zoom", eye.Zoom.X); + _circleMaskShader.SetParameter("Zoom", _eye.Zoom.X); _circleMaskShader.SetParameter("CircleRadius", _vision.RadiusPixels); _circleMaskShader.SetParameter("CircleMinDist", _vision.InnerRadiusPixels);🤖 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 `@Content.Client/Mutatrix/Besta/BestaLimitedVisionOverlay.cs` around lines 57 - 78, `Draw` is repeating the same player and eye lookups already done in `BeforeDraw`, causing redundant per-frame work. Refactor `BestaLimitedVisionOverlay` so `BeforeDraw` stores the resolved `EyeComponent` alongside `_vision` in a field, then have `Draw` use that cached data instead of re-reading `LocalSession`, `AttachedEntity`, and `TryGetComponent`. Keep `Draw` focused on shader setup and rendering.Resources/Prototypes/Mutatrix/cortex.yml (1)
78-134: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winTags de acesso individuais são redundantes com o grupo
AllAccess.O grupo
AllAccess(linha 80) já concede acesso a todas as áreas padrão da estação (Captain, Engineering, Medical, Security, etc.). As ~40 tags individuais listadas (linhas 83-126) são quase certamente redundantes e dificultam a manutenção — se um access for adicionado/removido no grupo, as tags individuais ficam dessincronizadas.Mantenha apenas as tags que não estão em
AllAccess:Silicon(grupo),BasicSilicon,Borg,StationAi,CentralCommand,BrigMedic,Bitrun, e as de antagonista (NuclearOperative,SyndicateAgent,Wizard,Xenoborg) se realmente necessárias.♻️ Refatoração proposta
- type: Access groups: - AllAccess - Silicon tags: - - EmergencyShuttleRepealAll - - Captain - - HeadOfPersonnel - - ChiefEngineer - - ChiefMedicalOfficer - - HeadOfSecurity - - ResearchDirector - - Command - - Cryogenics - - Security - - Detective - - Armory - - Brig - - Lawyer - - Engineering - - Medical - - Quartermaster - - Salvage - - Cargo - - Research - - Service - - Maintenance - - External - - Janitor - - Theatre - - Bar - - Chemistry - - Kitchen - - Chapel - - Hydroponics - - Atmospherics - - GenpopEnter - - GenpopLeave - - Robotics - - Journalism - - Virology - - Psychology - - Pharmacy - - Genetics - - Mail - - Mining - - BrigMedic - - Library - - Bitrun + - BrigMedic + - Bitrun - CentralCommand - Borg - BasicSilicon - StationAi - NuclearOperative - SyndicateAgent - Wizard - Xenoborg🤖 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 `@Resources/Prototypes/Mutatrix/cortex.yml` around lines 78 - 134, The Access entry in the Cortex prototype is over-specified because AllAccess already covers the standard station tags, so remove the redundant individual access tags from this prototype and keep only the non-AllAccess exceptions. Use the Access definition in the cortex prototype to retain Silicon-related access plus any truly special tags such as BasicSilicon, Borg, StationAi, CentralCommand, BrigMedic, Bitrun, and only the antagonist-specific tags if they are still required. This keeps the access list aligned with AllAccess and avoids future maintenance drift.Resources/Prototypes/Mutatrix/actions.yml (1)
46-67: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAlias de compatibilidade pode herdar do protótipo principal em vez de duplicar.
A entidade
ActionMutatrixCaptureDnaduplica integralmente todos os componentes deActionMutatrixCaptureDNA. No sistema de protótipos do SS14, usarparent: ActionMutatrixCaptureDNAelimina a duplicação e garante que mudanças na ação principal sejam automaticamente refletidas no alias.♻️ Refatoração proposta
- type: entity - parent: BaseAction + parent: ActionMutatrixCaptureDNA id: ActionMutatrixCaptureDna - name: Registrar DNA - description: Escaneia uma criatura próxima para registrar uma nova forma no Mutatrix. - components: - - type: Action - checkCanInteract: false - useDelay: 1 - icon: - sprite: Objects/Devices/mutatrix.rsi - state: icon - itemIconStyle: BigAction - - type: TargetAction - range: 1.25 - interactOnMiss: false - - type: EntityTargetAction - canTargetSelf: false - whitelist: - components: - - MobState - event: !type:MutatrixCaptureDnaActionEvent🤖 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 `@Resources/Prototypes/Mutatrix/actions.yml` around lines 46 - 67, The compatibility alias ActionMutatrixCaptureDna is duplicating the full definition of the main action prototype instead of inheriting it. Update this prototype to use ActionMutatrixCaptureDNA as its parent so it reuses the same Action, TargetAction, and EntityTargetAction components, keeping the alias automatically aligned with future changes to the اصلی prototype.Resources/Prototypes/Mutatrix/feralis.yml (1)
20-24: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueComentário desatualizado referencia o nome antigo do componente.
O comentário na linha 21 menciona
FeralisLimitedVision, mas o componente real utilizado éBestaLimitedVision(linha 22). Atualize o comentário para evitar confusão.📝 Correção do comentário
- # A limitação real da visão é feita pelo componente FeralisLimitedVision no client. + # A limitação real da visão é feita pelo componente BestaLimitedVision no client.🤖 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 `@Resources/Prototypes/Mutatrix/feralis.yml` around lines 20 - 24, The comment in the feralis prototype is stale and still references the old component name, which can confuse readers. Update the explanatory comment near the BestaLimitedVision block so it names the actual component being used, and keep the rest of the explanation aligned with the current client-side vision limitation implementation.Resources/Prototypes/Mutatrix/pyron.yml (2)
8-13: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
flatReductionsde Heat é redundante quando o coeficiente já é zero.Com
coefficients: Heat: 0, qualquer dano de calor é multiplicado por zero, tornandoflatReductions: Heat: 999irrelevante. Não é um bug, mas pode ser simplificado.♻️ Simplificar damageModifierSet
- type: damageModifierSet id: MutatrixPyronDamage coefficients: Heat: 0 - flatReductions: - Heat: 999🤖 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 `@Resources/Prototypes/Mutatrix/pyron.yml` around lines 8 - 13, The Heat entry in MutatrixPyronDamage is redundant because coefficients.Heat is already set to 0, so the flatReductions.Heat value has no effect. Simplify the damageModifierSet by removing the unnecessary flatReductions entry and keep the existing coefficient-based immunity behavior intact.
77-104: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueGrupo
Extinguishno Reactive é inefetivo comcanExtinguish: false.O componente
FlammabledefinecanExtinguish: false(linha 81), mas oReactiveincluiExtinguish: [ Touch ](linha 104). O Flammable rejeitará tentativas de extinção, tornando essa entrada de grupo inútil. A reação de dano por água (linhas 107-113) é separada e continuará funcionando. Remova a entradaExtinguishpara evitar confusão.♻️ Remover entrada Extinguish redundante
groups: Flammable: [ Touch ] - Extinguish: [ Touch ] Acidic: [ Touch, Ingestion ]🤖 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 `@Resources/Prototypes/Mutatrix/pyron.yml` around lines 77 - 104, In the MutatrixPyron prototype, the Reactive setup includes an Extinguish touch group even though Flammable has canExtinguish set to false, so that entry can never take effect. Update the pyron YAML by removing the Extinguish group from the Reactive component and keep the Touch-based Flammable interaction plus the separate water damage reaction intact. Use the Flammable, Reactive, and MutatrixPyronDamage definitions to locate the affected section.Content.Client/Mutatrix/UI/MutatrixBoundUserInterface.cs (2)
24-40: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
HiddenStaticTransformationsduplica oRemovedBuiltInsdo servidor.O conjunto
HiddenStaticTransformationsno cliente contém exatamente os mesmos 14 IDs queRemovedBuiltInsemMutatrixSystem.cs(linhas 44-60). Se uma forma for adicionada ou removida de um conjunto sem atualizar o outro, o menu pode exibir opções bloqueadas ou ocultar formas válidas.Considere mover a lista para um local compartilhado (ex.:
SharedMutatrixSystem) ou marcar as formas como ocultas via campo do protótipoMutatrixTransformationPrototype.🤖 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 `@Content.Client/Mutatrix/UI/MutatrixBoundUserInterface.cs` around lines 24 - 40, O conjunto HiddenStaticTransformations está duplicado com RemovedBuiltIns e pode sair de sincronização entre cliente e servidor. Atualize MutatrixBoundUserInterface para consumir a mesma fonte compartilhada usada por MutatrixSystem/RemovedBuiltIns, ou derive essa informação do próprio MutatrixTransformationPrototype (campo de oculto), evitando manter duas listas separadas com os mesmos IDs.
174-185: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
GetScannedDisplayNameestá duplicado no servidor.O método
GetScannedDisplayNameaqui é idêntico ao deMutatrixSystem.cs(linhas 544-555). Extrair para um local compartilhado (ex.:SharedMutatrixSystemou um helper estático) eliminaria a duplicação e garantirá comportamento consistente.🤖 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 `@Content.Client/Mutatrix/UI/MutatrixBoundUserInterface.cs` around lines 174 - 185, `GetScannedDisplayName` is duplicated with the same logic in `MutatrixSystem`, so move the shared name-resolution logic into a common place such as `SharedMutatrixSystem` or a static helper and have both callers use it. Keep the behavior identical by preserving the species lookup over `_prototype.EnumeratePrototypes<SpeciesPrototype>()` and the fallback to `entityPrototype.Name`/`prototypeId`, but remove the copy from `MutatrixBoundUserInterface` and reference the shared method from both sides.Content.Server/Mutatrix/Systems/MutatrixSystem.cs (1)
557-584: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
Durationhardcoded emCreateDynamicPolymorphConfiguration.O valor
Duration = 360(6 minutos) está fixo no código. Considere expô-lo como um campo configurável (ex.: noMutatrixComponentou noMutatrixTransformationPrototype) para permitir ajuste via YAML sem recompilação.♻️ Refatoração sugerida
- Duration = 360, + Duration = _mutatrixDuration, // ou ler de MutatrixComponent/protótipo🤖 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 `@Content.Server/Mutatrix/Systems/MutatrixSystem.cs` around lines 557 - 584, The Duration in CreateDynamicPolymorphConfiguration is hardcoded, so make it configurable instead of fixed to 360 seconds. Update the MutatrixSystem logic to read the duration from a data-driven source such as MutatrixComponent or MutatrixTransformationPrototype, and thread that value into the PolymorphConfiguration constructor while keeping the existing defaults for the other fields.
🤖 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 `@Content.Server/Mutatrix/Chama/Systems/MutatrixChamaSystem.cs`:
- Around line 42-49: O OnShutdown em MutatrixChamaSystem remove FireballGun e
FlameGun, mas deixa penduradas as ações criadas em OnMapInit. Atualize
OnShutdown para também limpar as entidades armazenadas em FireballActionEntity e
FlameActionEntity no MutatrixChamaComponent, usando os mesmos padrões de
checagem e QueueDel já aplicados às armas, para que a UI e os recursos sejam
totalmente descartados quando o componente for removido.
In `@Content.Server/Mutatrix/Systems/MutatrixSystem.cs`:
- Around line 367-453: Move the cooldown check in MutatrixSystem.TryTransform
and the matching TryTransformDynamic flow so it runs before any Polymorph.Revert
call; right now OnDnaPolymorphed adds MutatrixCooldownComponent during revert,
and the later IsOnCooldown check in TryTransform sees that fresh cooldown and
aborts the new transformation. Keep the existing unlock and prototype
validation, but ensure the cooldown gate is evaluated against the currently
transformed entity before reverting, then let the revert proceed and continue
without checking cooldown again afterward.
In `@Content.Shared/Mutatrix/Besta/Components/BestaLimitedVisionComponent.cs`:
- Around line 12-26: Add client-side state synchronization to
BestaLimitedVisionComponent by annotating the class with
AutoGenerateComponentState and marking RadiusPixels and InnerRadiusPixels with
AutoNetworkedField. This will ensure BestaLimitedVisionOverlay reads the
server-authored values instead of only the C# defaults; update the component
definition where the networked fields are declared so the client receives
prototype/YAML overrides correctly.
---
Outside diff comments:
In `@Resources/Locale/pt-BR/mutatrix/besta.ftl`:
- Around line 1-3: The `besta.ftl` locale file is missing the same SPDX
licensing header used by the other `.ftl` files in this PR. Add the standard
`SPDX-FileCopyrightText` and `SPDX-License-Identifier` header at the top of this
file, keeping the existing `mutatrix-transformation-besta-name` and
`mutatrix-transformation-besta-desc` entries unchanged.
In `@Resources/Locale/pt-BR/mutatrix/greymatter.ftl`:
- Around line 1-3: O arquivo greymatter.ftl está sem o cabeçalho SPDX exigido;
adicione no topo os mesmos metadados presentes nos outros arquivos .ftl do PR,
incluindo SPDX-FileCopyrightText e SPDX-License-Identifier. Use o padrão já
aplicado em besta.ftl e nos demais arquivos de locale para manter consistência e
localizar facilmente o ajuste no início do arquivo
mutatrix-transformation-greymatter-name.
---
Nitpick comments:
In `@Content.Client/Mutatrix/Besta/BestaLimitedVisionOverlay.cs`:
- Around line 57-78: `Draw` is repeating the same player and eye lookups already
done in `BeforeDraw`, causing redundant per-frame work. Refactor
`BestaLimitedVisionOverlay` so `BeforeDraw` stores the resolved `EyeComponent`
alongside `_vision` in a field, then have `Draw` use that cached data instead of
re-reading `LocalSession`, `AttachedEntity`, and `TryGetComponent`. Keep `Draw`
focused on shader setup and rendering.
In `@Content.Client/Mutatrix/UI/MutatrixBoundUserInterface.cs`:
- Around line 24-40: O conjunto HiddenStaticTransformations está duplicado com
RemovedBuiltIns e pode sair de sincronização entre cliente e servidor. Atualize
MutatrixBoundUserInterface para consumir a mesma fonte compartilhada usada por
MutatrixSystem/RemovedBuiltIns, ou derive essa informação do próprio
MutatrixTransformationPrototype (campo de oculto), evitando manter duas listas
separadas com os mesmos IDs.
- Around line 174-185: `GetScannedDisplayName` is duplicated with the same logic
in `MutatrixSystem`, so move the shared name-resolution logic into a common
place such as `SharedMutatrixSystem` or a static helper and have both callers
use it. Keep the behavior identical by preserving the species lookup over
`_prototype.EnumeratePrototypes<SpeciesPrototype>()` and the fallback to
`entityPrototype.Name`/`prototypeId`, but remove the copy from
`MutatrixBoundUserInterface` and reference the shared method from both sides.
In `@Content.Server/Mutatrix/GreyMatter/Systems/MutatrixGreyMatterSystem.cs`:
- Around line 6-13: MutatrixGreyMatterSystem is currently an empty EntitySystem,
so either remove it if the grey matter traits are fully handled by passive
prototype components, or document it clearly as an intentional placeholder for
future behavior. Update the MutatrixGreyMatterSystem class to reflect the
intended design: if no logic is needed, delete the empty system and its
registration; if it must remain, add a brief comment on the class explaining why
it exists.
In `@Content.Server/Mutatrix/Systems/MutatrixSystem.cs`:
- Around line 557-584: The Duration in CreateDynamicPolymorphConfiguration is
hardcoded, so make it configurable instead of fixed to 360 seconds. Update the
MutatrixSystem logic to read the duration from a data-driven source such as
MutatrixComponent or MutatrixTransformationPrototype, and thread that value into
the PolymorphConfiguration constructor while keeping the existing defaults for
the other fields.
In `@Resources/Prototypes/Mutatrix/actions.yml`:
- Around line 46-67: The compatibility alias ActionMutatrixCaptureDna is
duplicating the full definition of the main action prototype instead of
inheriting it. Update this prototype to use ActionMutatrixCaptureDNA as its
parent so it reuses the same Action, TargetAction, and EntityTargetAction
components, keeping the alias automatically aligned with future changes to the
اصلی prototype.
In `@Resources/Prototypes/Mutatrix/cortex.yml`:
- Around line 78-134: The Access entry in the Cortex prototype is over-specified
because AllAccess already covers the standard station tags, so remove the
redundant individual access tags from this prototype and keep only the
non-AllAccess exceptions. Use the Access definition in the cortex prototype to
retain Silicon-related access plus any truly special tags such as BasicSilicon,
Borg, StationAi, CentralCommand, BrigMedic, Bitrun, and only the
antagonist-specific tags if they are still required. This keeps the access list
aligned with AllAccess and avoids future maintenance drift.
In `@Resources/Prototypes/Mutatrix/feralis.yml`:
- Around line 20-24: The comment in the feralis prototype is stale and still
references the old component name, which can confuse readers. Update the
explanatory comment near the BestaLimitedVision block so it names the actual
component being used, and keep the rest of the explanation aligned with the
current client-side vision limitation implementation.
In `@Resources/Prototypes/Mutatrix/pyron.yml`:
- Around line 8-13: The Heat entry in MutatrixPyronDamage is redundant because
coefficients.Heat is already set to 0, so the flatReductions.Heat value has no
effect. Simplify the damageModifierSet by removing the unnecessary
flatReductions entry and keep the existing coefficient-based immunity behavior
intact.
- Around line 77-104: In the MutatrixPyron prototype, the Reactive setup
includes an Extinguish touch group even though Flammable has canExtinguish set
to false, so that entry can never take effect. Update the pyron YAML by removing
the Extinguish group from the Reactive component and keep the Touch-based
Flammable interaction plus the separate water damage reaction intact. Use the
Flammable, Reactive, and MutatrixPyronDamage definitions to locate the affected
section.
🪄 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: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 5e5b10d4-f456-4d9d-a009-b2929ac719b2
⛔ Files ignored due to path filters (11)
Resources/Textures/Mutatrix/Mobs/cortex.rsi/cortex-dead.pngis excluded by!**/*.pngResources/Textures/Mutatrix/Mobs/cortex.rsi/cortex-icon.pngis excluded by!**/*.pngResources/Textures/Mutatrix/Mobs/cortex.rsi/cortex.pngis excluded by!**/*.pngResources/Textures/Mutatrix/Mobs/feralis.rsi/feralis-dead.pngis excluded by!**/*.pngResources/Textures/Mutatrix/Mobs/feralis.rsi/feralis-icon.pngis excluded by!**/*.pngResources/Textures/Mutatrix/Mobs/feralis.rsi/feralis.pngis excluded by!**/*.pngResources/Textures/Mutatrix/Mobs/pyron.rsi/pyron-dead.pngis excluded by!**/*.pngResources/Textures/Mutatrix/Mobs/pyron.rsi/pyron.pngis excluded by!**/*.pngResources/Textures/Mutatrix/Mobs/tetramus.rsi/tetramus-dead.pngis excluded by!**/*.pngResources/Textures/Mutatrix/Mobs/tetramus.rsi/tetramus.pngis excluded by!**/*.pngResources/Textures/Objects/Devices/mutatrix.rsi/icon.pngis excluded by!**/*.png
📒 Files selected for processing (54)
Content.Client/Mutatrix/Besta/BestaLimitedVisionOverlay.csContent.Client/Mutatrix/Besta/BestaLimitedVisionSystem.csContent.Client/Mutatrix/UI/MutatrixBoundUserInterface.csContent.Server/Mutatrix/Chama/Components/MutatrixChamaComponent.csContent.Server/Mutatrix/Chama/Systems/MutatrixChamaSystem.csContent.Server/Mutatrix/Components/MutatrixTransformedComponent.csContent.Server/Mutatrix/GreyMatter/Systems/MutatrixGreyMatterSystem.csContent.Server/Mutatrix/QuatroBracos/Components/MutatrixQuatroBracosComponent.csContent.Server/Mutatrix/QuatroBracos/Systems/MutatrixQuatroBracosSystem.csContent.Server/Mutatrix/Systems/MutatrixScannerSystem.csContent.Server/Mutatrix/Systems/MutatrixSystem.csContent.Server/Mutatrix/Systems/MutatrixTransformedSystem.csContent.Server/Polymorph/Systems/PolymorphSystem.csContent.Shared/Mutatrix/Besta/Components/BestaLimitedVisionComponent.csContent.Shared/Mutatrix/Chama/Events/MutatrixChamaActions.csContent.Shared/Mutatrix/Components/ActiveMutatrixComponent.csContent.Shared/Mutatrix/Components/MutatrixComponent.csContent.Shared/Mutatrix/Components/MutatrixCooldownComponent.csContent.Shared/Mutatrix/Components/MutatrixDnaComponent.csContent.Shared/Mutatrix/Components/MutatrixScanComponent.csContent.Shared/Mutatrix/Events/MutatrixOpenMenuActionEvent.csContent.Shared/Mutatrix/Events/MutatrixScanDoAfterEvent.csContent.Shared/Mutatrix/Events/MutatrixUiMessages.csContent.Shared/Mutatrix/GreyMatter/Components/MutatrixGreyMatterComponent.csContent.Shared/Mutatrix/GreyMatter/Events/MutatrixGreyMatterActions.csContent.Shared/Mutatrix/Prototypes/MutatrixTransformationPrototype.csContent.Shared/Mutatrix/QuatroBracos/Events/MutatrixQuatroBracosActions.csContent.Shared/Mutatrix/Systems/SharedMutatrixSystem.csResources/Locale/en-US/mutatrix/besta.ftlResources/Locale/en-US/mutatrix/chama.ftlResources/Locale/en-US/mutatrix/mutatrix.ftlResources/Locale/en-US/mutatrix/pyron.ftlResources/Locale/en-US/mutatrix/quatrobracos.ftlResources/Locale/en-US/mutatrix/tetramus.ftlResources/Locale/pt-BR/mutatrix/besta.ftlResources/Locale/pt-BR/mutatrix/chama.ftlResources/Locale/pt-BR/mutatrix/greymatter.ftlResources/Locale/pt-BR/mutatrix/mutatrix.ftlResources/Locale/pt-BR/mutatrix/pyron.ftlResources/Locale/pt-BR/mutatrix/quatrobracos.ftlResources/Locale/pt-BR/mutatrix/tetramus.ftlResources/Prototypes/Mutatrix/actions.ymlResources/Prototypes/Mutatrix/cortex.ymlResources/Prototypes/Mutatrix/feralis.ymlResources/Prototypes/Mutatrix/mutatrix.ymlResources/Prototypes/Mutatrix/polymorphs.ymlResources/Prototypes/Mutatrix/pyron.ymlResources/Prototypes/Mutatrix/tetramus.ymlResources/Prototypes/Mutatrix/transformations.ymlResources/Textures/Mutatrix/Mobs/cortex.rsi/meta.jsonResources/Textures/Mutatrix/Mobs/feralis.rsi/meta.jsonResources/Textures/Mutatrix/Mobs/pyron.rsi/meta.jsonResources/Textures/Mutatrix/Mobs/tetramus.rsi/meta.jsonResources/Textures/Objects/Devices/mutatrix.rsi/meta.json
| private void OnShutdown(Entity<MutatrixChamaComponent> ent, ref ComponentShutdown args) | ||
| { | ||
| if (ent.Comp.FireballGun is { } fireballGun) | ||
| QueueDel(fireballGun); | ||
|
|
||
| if (ent.Comp.FlameGun is { } flameGun) | ||
| QueueDel(flameGun); | ||
| } |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
Limpar ações no OnShutdown
O OnShutdown deleta as armas (FireballGun, FlameGun) mas não remove as ações adicionadas em OnMapInit (FireballActionEntity, FlameActionEntity). Se o componente for removido sem que a entidade seja deletada, as ações persistem na UI como ícones não funcionais e as entidades de ação vazam.
♻️ Correção proposta
private void OnShutdown(Entity<MutatrixChamaComponent> ent, ref ComponentShutdown args)
{
+ _actions.RemoveAction(ent, ref ent.Comp.FireballActionEntity);
+ _actions.RemoveAction(ent, ref ent.Comp.FlameActionEntity);
+
if (ent.Comp.FireballGun is { } fireballGun)
QueueDel(fireballGun);
if (ent.Comp.FlameGun is { } flameGun)
QueueDel(flameGun);
}📝 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.
| private void OnShutdown(Entity<MutatrixChamaComponent> ent, ref ComponentShutdown args) | |
| { | |
| if (ent.Comp.FireballGun is { } fireballGun) | |
| QueueDel(fireballGun); | |
| if (ent.Comp.FlameGun is { } flameGun) | |
| QueueDel(flameGun); | |
| } | |
| private void OnShutdown(Entity<MutatrixChamaComponent> ent, ref ComponentShutdown args) | |
| { | |
| _actions.RemoveAction(ent, ref ent.Comp.FireballActionEntity); | |
| _actions.RemoveAction(ent, ref ent.Comp.FlameActionEntity); | |
| if (ent.Comp.FireballGun is { } fireballGun) | |
| QueueDel(fireballGun); | |
| if (ent.Comp.FlameGun is { } flameGun) | |
| QueueDel(flameGun); | |
| } |
🤖 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 `@Content.Server/Mutatrix/Chama/Systems/MutatrixChamaSystem.cs` around lines 42
- 49, O OnShutdown em MutatrixChamaSystem remove FireballGun e FlameGun, mas
deixa penduradas as ações criadas em OnMapInit. Atualize OnShutdown para também
limpar as entidades armazenadas em FireballActionEntity e FlameActionEntity no
MutatrixChamaComponent, usando os mesmos padrões de checagem e QueueDel já
aplicados às armas, para que a UI e os recursos sejam totalmente descartados
quando o componente for removido.
| private bool TryTransform( | ||
| EntityUid user, | ||
| ProtoId<MutatrixTransformationPrototype> transformation, | ||
| MutatrixDnaComponent? dna = null) | ||
| { | ||
| if (TryComp<PolymorphedEntityComponent>(user, out var polymorphed)) | ||
| { | ||
| var original = _polymorph.Revert((user, polymorphed)); | ||
| if (original == null || Deleted(original.Value)) | ||
| { | ||
| _popup.PopupEntity(Loc.GetString("mutatrix-popup-transform-failed"), user, user); | ||
| return false; | ||
| } | ||
|
|
||
| user = original.Value; | ||
| dna = EnsureComp<MutatrixDnaComponent>(user); | ||
| } | ||
|
|
||
| if (!Resolve(user, ref dna, false)) | ||
| return false; | ||
|
|
||
| EnsureDefaultUnlocks((user, dna)); | ||
|
|
||
| if (!IsUnlocked(dna, transformation)) | ||
| { | ||
| _popup.PopupEntity(Loc.GetString("mutatrix-popup-locked"), user, user); | ||
| return false; | ||
| } | ||
|
|
||
| if (TryComp<ActiveMutatrixComponent>(user, out var active) | ||
| && TryComp<MutatrixComponent>(active.Device, out var device) | ||
| && IsOnCooldown(user, device, out var remaining)) | ||
| { | ||
| ShowCooldown(user, remaining); | ||
| return false; | ||
| } | ||
|
|
||
| var originalName = Name(user); | ||
|
|
||
| if (!_prototype.TryIndex(transformation, out var mutatrixTransformation)) | ||
| { | ||
| _popup.PopupEntity(Loc.GetString("mutatrix-popup-transform-failed"), user, user); | ||
| return false; | ||
| } | ||
|
|
||
| if (!_prototype.TryIndex<PolymorphPrototype>(mutatrixTransformation.Polymorph, out _)) | ||
| { | ||
| _popup.PopupEntity(Loc.GetString("mutatrix-popup-transform-failed"), user, user); | ||
| return false; | ||
| } | ||
|
|
||
| dna.Selected = transformation; | ||
| dna.SelectedScannedPrototype = null; | ||
| Dirty(user, dna); | ||
|
|
||
| var result = _polymorph.PolymorphEntity(user, mutatrixTransformation.Polymorph); | ||
| if (result == null) | ||
| { | ||
| _popup.PopupEntity(Loc.GetString("mutatrix-popup-transform-failed"), user, user); | ||
| return false; | ||
| } | ||
|
|
||
| EnsureComp<MutatrixTransformedComponent>(result.Value); | ||
|
|
||
| var childDna = EnsureComp<MutatrixDnaComponent>(result.Value); | ||
| MergeDna(dna, childDna); | ||
| childDna.Selected = transformation; | ||
| childDna.SelectedScannedPrototype = null; | ||
| Dirty(result.Value, childDna); | ||
|
|
||
| if (TryComp<ActiveMutatrixComponent>(user, out active)) | ||
| { | ||
| var childActive = EnsureComp<ActiveMutatrixComponent>(result.Value); | ||
| childActive.Device = active.Device; | ||
| Dirty(result.Value, childActive); | ||
| } | ||
|
|
||
| ApplyAppearanceOverrides(result.Value, mutatrixTransformation); | ||
| ApplyOriginalName(result.Value, originalName); | ||
|
|
||
| _popup.PopupEntity( | ||
| Loc.GetString("mutatrix-popup-selected", ("name", Loc.GetString(mutatrixTransformation.Name))), | ||
| result.Value, | ||
| result.Value); | ||
|
|
||
| return true; | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win
Troca de formas quebrada: cooldown aplicado durante o revert bloqueia a transformação seguinte.
Quando o jogador já está transformado e seleciona uma nova forma, TryTransform chama _polymorph.Revert(). Durante o revert, OnDnaPolymorphed (linha 291-296) aplica um MutatrixCooldownComponent de 90s na entidade original. Em seguida, a verificação de cooldown nas linhas 396-402 detecta o cooldown recém-aplicado e falha, deixando o jogador preso na forma original. O mesmo bug existe em TryTransformDynamic (linhas 487-493).
Correção: mover a verificação de cooldown para antes do bloco de revert. A entidade polimorfada não possui MutatrixCooldownComponent, então a verificação passa, o revert aplica o cooldown na original, e a transformação prossegue sem re-verificar.
🐛 Correção proposta para TryTransform
private bool TryTransform(
EntityUid user,
ProtoId<MutatrixTransformationPrototype> transformation,
MutatrixDnaComponent? dna = null)
{
+ // Verificar cooldown antes do revert, pois o próprio revert aplica um novo cooldown.
+ if (TryComp<ActiveMutatrixComponent>(user, out var preRevertActive)
+ && TryComp<MutatrixComponent>(preRevertActive.Device, out var preRevertDevice)
+ && IsOnCooldown(user, preRevertDevice, out var preRevertRemaining))
+ {
+ ShowCooldown(user, preRevertRemaining);
+ return false;
+ }
+
if (TryComp<PolymorphedEntityComponent>(user, out var polymorphed))
{
var original = _polymorph.Revert((user, polymorphed));
if (original == null || Deleted(original.Value))
{
_popup.PopupEntity(Loc.GetString("mutatrix-popup-transform-failed"), user, user);
return false;
}
user = original.Value;
dna = EnsureComp<MutatrixDnaComponent>(user);
}
if (!Resolve(user, ref dna, false))
return false;
EnsureDefaultUnlocks((user, dna));
if (!IsUnlocked(dna, transformation))
{
_popup.PopupEntity(Loc.GetString("mutatrix-popup-locked"), user, user);
return false;
}
- if (TryComp<ActiveMutatrixComponent>(user, out var active)
- && TryComp<MutatrixComponent>(active.Device, out var device)
- && IsOnCooldown(user, device, out var remaining))
- {
- ShowCooldown(user, remaining);
- return false;
- }
-
var originalName = Name(user);🐛 Correção equivalente para TryTransformDynamic
private bool TryTransformDynamic(EntityUid user, string entityPrototypeId, MutatrixDnaComponent? dna = null)
{
+ // Verificar cooldown antes do revert, pois o próprio revert aplica um novo cooldown.
+ if (TryComp<ActiveMutatrixComponent>(user, out var preRevertActive)
+ && TryComp<MutatrixComponent>(preRevertActive.Device, out var preRevertDevice)
+ && IsOnCooldown(user, preRevertDevice, out var preRevertRemaining))
+ {
+ ShowCooldown(user, preRevertRemaining);
+ return false;
+ }
+
if (string.IsNullOrWhiteSpace(entityPrototypeId) || DisallowedDynamicPrototypeIds.Contains(entityPrototypeId) || IsBorgLikePrototypeId(entityPrototypeId))
{
_popup.PopupEntity(Loc.GetString("mutatrix-popup-transform-failed"), user, user);
return false;
}
if (TryComp<PolymorphedEntityComponent>(user, out var polymorphed))
{
var original = _polymorph.Revert((user, polymorphed));
if (original == null || Deleted(original.Value))
{
_popup.PopupEntity(Loc.GetString("mutatrix-popup-transform-failed"), user, user);
return false;
}
user = original.Value;
dna = EnsureComp<MutatrixDnaComponent>(user);
}
if (!Resolve(user, ref dna, false))
return false;
EnsureDefaultUnlocks((user, dna));
if (!IsDynamicUnlocked(dna, entityPrototypeId))
{
_popup.PopupEntity(Loc.GetString("mutatrix-popup-locked"), user, user);
return false;
}
- if (TryComp<ActiveMutatrixComponent>(user, out var active)
- && TryComp<MutatrixComponent>(active.Device, out var device)
- && IsOnCooldown(user, device, out var remaining))
- {
- ShowCooldown(user, remaining);
- return false;
- }
-
var originalName = Name(user);Also applies to: 455-541
🤖 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 `@Content.Server/Mutatrix/Systems/MutatrixSystem.cs` around lines 367 - 453,
Move the cooldown check in MutatrixSystem.TryTransform and the matching
TryTransformDynamic flow so it runs before any Polymorph.Revert call; right now
OnDnaPolymorphed adds MutatrixCooldownComponent during revert, and the later
IsOnCooldown check in TryTransform sees that fresh cooldown and aborts the new
transformation. Keep the existing unlock and prototype validation, but ensure
the cooldown gate is evaluated against the currently transformed entity before
reverting, then let the revert proceed and continue without checking cooldown
again afterward.
| [RegisterComponent, NetworkedComponent] | ||
| public sealed partial class BestaLimitedVisionComponent : Component | ||
| { | ||
| /// <summary> | ||
| /// Visible circle radius in screen pixels at normal zoom. | ||
| /// 70px aumenta bem o campo de visão da Besta, mantendo o resto escuro e permitindo que ThermalVision destaque entidades. | ||
| /// </summary> | ||
| [DataField] | ||
| public float RadiusPixels = 70f; | ||
|
|
||
| /// <summary> | ||
| /// Inner clear area before the fade starts. | ||
| /// </summary> | ||
| [DataField] | ||
| public float InnerRadiusPixels = 0f; |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Adicione [AutoGenerateComponentState] e [AutoNetworkedField] para sincronização client-side.
O overlay client-side lê RadiusPixels e InnerRadiusPixels diretamente do componente (linhas 67-68 de BestaLimitedVisionOverlay.cs), mas sem [AutoGenerateComponentState] na classe e [AutoNetworkedField] nos campos, esses valores não são sincronizados com o cliente. O componente existirá no cliente (por ser [NetworkedComponent]), mas sempre com os valores padrão do C# (70f e 0f), ignorando qualquer personalização feita em protótipos YAML.
🔧 Correção proposta
-[RegisterComponent, NetworkedComponent]
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class BestaLimitedVisionComponent : Component
{
/// <summary>
/// Visible circle radius in screen pixels at normal zoom.
/// 70px aumenta bem o campo de visão da Besta, mantendo o resto escuro e permitindo que ThermalVision destaque entidades.
/// </summary>
- [DataField]
+ [DataField, AutoNetworkedField]
public float RadiusPixels = 70f;
/// <summary>
/// Inner clear area before the fade starts.
/// </summary>
- [DataField]
+ [DataField, AutoNetworkedField]
public float InnerRadiusPixels = 0f;
}📝 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.
| [RegisterComponent, NetworkedComponent] | |
| public sealed partial class BestaLimitedVisionComponent : Component | |
| { | |
| /// <summary> | |
| /// Visible circle radius in screen pixels at normal zoom. | |
| /// 70px aumenta bem o campo de visão da Besta, mantendo o resto escuro e permitindo que ThermalVision destaque entidades. | |
| /// </summary> | |
| [DataField] | |
| public float RadiusPixels = 70f; | |
| /// <summary> | |
| /// Inner clear area before the fade starts. | |
| /// </summary> | |
| [DataField] | |
| public float InnerRadiusPixels = 0f; | |
| [RegisterComponent, NetworkedComponent, AutoGenerateComponentState] | |
| public sealed partial class BestaLimitedVisionComponent : Component | |
| { | |
| /// <summary> | |
| /// Visible circle radius in screen pixels at normal zoom. | |
| /// 70px aumenta bem o campo de visão da Besta, mantendo o resto escuro e permitindo que ThermalVision destaque entidades. | |
| /// </summary> | |
| [DataField, AutoNetworkedField] | |
| public float RadiusPixels = 70f; | |
| /// <summary> | |
| /// Inner clear area before the fade starts. | |
| /// </summary> | |
| [DataField, AutoNetworkedField] | |
| public float InnerRadiusPixels = 0f; |
🤖 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 `@Content.Shared/Mutatrix/Besta/Components/BestaLimitedVisionComponent.cs`
around lines 12 - 26, Add client-side state synchronization to
BestaLimitedVisionComponent by annotating the class with
AutoGenerateComponentState and marking RadiusPixels and InnerRadiusPixels with
AutoNetworkedField. This will ensure BestaLimitedVisionOverlay reads the
server-authored values instead of only the C# defaults; update the component
definition where the networked fields are declared so the client receives
prototype/YAML overrides correctly.
Source: Learnings
|
Percebi que tem uma diferença no nome dos arquivos. Enquanto em um local chama-se "pyron", no outro você chama de "chama" e assim vai com outros aliens. Eu só olhei o código por cima, então talvez esteja errado. De qualquer forma, nomes de arquivos, métodos e variáveis sempre são em inglês para seguir um padrão, o que não acontece na nomenclatura de vários dos arquivos do seu Pull Request. Acho que o maintainer vai te dizer a mesma coisa também. |
|
a historia começou quando um relogio esquisito e sim, biel está certo, nomenclatura de pastas, variaveis e outros são sempre em ingles |
|
Além da nomenclatura dos arquivos que já falaram também precisaria mudar a organização deles. Isso tudo deveria estar em _Dumont de cada local relevante. Texturas também estão muito diferentes da do SS14, e pessoalmente eu adoro a ideia mas não acho legal uma literal cópia do alien do Ben 10. Deveria tentar fazer algo mais alinhado ao universo do SS14 que seja uma referência ao Ben 10 ao invés de diretamente fazer igual. Mutantrix o item e os mobs que criou estão todos com descrição e nome em português no prototype. Isso não é bom porque acentuação facilmente causa problema fora de arquivos ftl. Melhor deixar tudo em inglês e deixar só o ftl traduzindo.
Fora isso, tem vários ftl vazios que deveria deletar. O coelho também fez umas observações que seria bom dar uma lida. Questão de balanceamento, acho que funcionar com IPC e conseguir virar IPC não faz sentido. O sistema de scan funciona com blacklist, isso é muito perigoso conforme o jogo cresce e eventualmente vai dar problema. Aí vai de cada um, se esse item for somente Admeme ok, se for se tornar um item antag ele deveria operar com whitelist pra evitar problemas. Qualquer coisa pode ter uma variante antag que funciona com whitelist e a variante Admeme que pode se tornar qualquer um escaneado. Massa cinzenta simplesmente ter AA de admin é meio demais, deveria limitar isso pra apenas estação ou tornar uma forma de doAfter meio longo dele "hackeado" pra liberar acesso. Ele também tem vent crawler então ele já possui um semi AA na estação, isso é insanamente forte caso de torne coisa antag. Você pode invadir arsenal e então abrir as armas e ir blasting. Absurdamente desbalanceado o massa cinzenta. Até visão noturna esse bicho tem. Não lembro dele ver no escuro no desenho. Tem insulated permanente e ainda tamanho pequeno e anda super rápido. Uma coisa que faria sentido dele é saber todas as línguas, mas ele só sabe tau ceti. Os outros mobs deveriam provavelmente herdar apenas a língua da entidade original, senão quando transformar a pessoa aprenderia tau ceti se não sabia antes. Besta em especial eu acho que nem deveria saber falar nada, deveria só fazer grunido mas ainda entender. O chama tá levando 20 de dano de água, acho que isso é até mais doque slime. Colocar multiplicador de dano de calor em 0 e ainda colocar redução direta de 999 não acho que seja um problema real mas parece meio redundante kkkk mas vai saber né oq os jogadores inventam. O quatro braços não é exatamente um problema gigante, mas é meio ruim ele não mostrar o que tem nas mãos. A pessoa pode andar com L6 ou estar com escudo e ninguém vai saber. E afinal porque ele tem noSlip? Acho que o que eu vi de maior seria isso. @isTheSuperN0va é nosso maintainer e vai conseguir uma Review bem melhor pra você quando tiver o tempo de ver sua PR. |
|
eu realmente só queria apresentar a ideia, adoraria ver um round tipo de domingo um cara do nada recebendo esse item, de qualquer forma quem quiser pegar e modificar a ideia é livre pra fazer o que quiser. |








Sobre a PR
Adiciona o Mutatrix, um item de pulso inspirado em dispositivo de transformação, disponível para testes via sandbox/admin.
O item permite ao jogador abrir uma roda de seleção e se transformar temporariamente em formas/mobs genéricos configurados por protótipos.
Inclui formas iniciais como:
Também adiciona um sistema de scanner de DNA para desbloquear transformações compatíveis.
Por quê? / Balanceamento
A ideia é adicionar uma mecânica divertida e modular de transformação temporária, inicialmente limitada para sandbox/admin, ou futuramente para um ou mais antagonistas sem afetar rounds normais diretamente.
As transformações possuem duração limitada e retorno automático em situações críticas, evitando que o jogador mantenha a forma indefinidamente.
O scanner bloqueia borgs/cyborgs/xenoborgs/chassis para evitar problemas com entidades incompatíveis, mas permite IPCs e sintéticos compatíveis.
Detalhes Técnicos
Principais mudanças:
Anexos
Sem anexos por enquanto.
Requerimentos
Changelog
🆑