Conversation
WalkthroughEsta atualização implementa uma grande reestruturação e aprimoramento do sistema de pesquisa ("Research") no jogo, especialmente focando na interface do console de pesquisa (R&D Console). Foram introduzidos novos arquivos de layout XAML e classes C# para uma interface gráfica avançada, incluindo painéis de tecnologia, cartões de receitas, visualização de pré-requisitos e informações detalhadas. O sistema agora utiliza uma enumeração de disponibilidade de pesquisa e cada tecnologia possui uma posição explícita para exibição em árvore. Diversos arquivos YAML de protótipos foram atualizados para adicionar posições e pré-requisitos, e ferramentas de gerenciamento/edição de árvores tecnológicas foram criadas em Python e JavaScript, incluindo editores web interativos. Entradas de localização também foram adicionadas. Changes
Sequence Diagram(s)sequenceDiagram
participant Jogador
participant FancyResearchConsoleMenu
participant FancyResearchConsoleBoundUserInterface
participant Servidor
Jogador->>FancyResearchConsoleMenu: Clica em tecnologia ou botão
FancyResearchConsoleMenu->>FancyResearchConsoleBoundUserInterface: Evento de seleção/disparo
FancyResearchConsoleBoundUserInterface->>Servidor: Envia mensagem (ex: desbloquear tecnologia)
Servidor->>FancyResearchConsoleBoundUserInterface: Atualiza estado do console (inclui pontos e disponibilidade)
FancyResearchConsoleBoundUserInterface->>FancyResearchConsoleMenu: Atualiza painel, cartões e informações
FancyResearchConsoleMenu->>Jogador: Exibe interface atualizada
Poem
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 19
🔭 Outside diff range comments (3)
Tools/TechTreeManager/MasterCivilianservices.yml (2)
151-225:⚠️ Potential issueOutras tecnologias duplicam posição
-1,0
Entradas comoPositronicInterfacing,HONKWeapons,AdvancedTreatment,CyberneticEnhancements,AutodoceHighEndSurgeryestão todas emposition: -1,0. Favor revisar e corrigir.
31-225: 🛠️ Refactor suggestionRevisar pré-requisitos para manter fluxo de tiers
Muitas tecnologias de tier 2 e 3 não possuemtechnologyPrerequisites, o que pode quebrar a progressão esperada. Recomendo definir dependências claras para cada nível.Tools/TechTreeManager/MasterExperimental.yml (1)
1-195:⚠️ Potential issueTodas as tecnologias compartilham
position: -1,0
Cada entrada usa a mesma coordenada, impossibilitando a formação de um tech tree. É imperativo atribuir posições distintas conforme layout definido.
🧹 Nitpick comments (49)
Resources/Prototypes/Research/disciplines.yml (3)
12-12: Remover espaço em branco no final da linha douiName.
Há um espaço extra apósINDgerando erro de lint YAML. Por favor, remova o espaço terminal para manter o padrão de formatação.🧰 Tools
🪛 YAMLlint (1.35.1)
[error] 12-12: trailing spaces
(trailing-spaces)
38-38: Remover espaço em branco no final da linha douiName.
Há um espaço extra apósEXPque causa erro de lint YAML. Remova o espaço terminal para corrigir.🧰 Tools
🪛 YAMLlint (1.35.1)
[error] 38-38: trailing spaces
(trailing-spaces)
51-51: Remover espaço em branco no final da linha douiName.
Há um espaço extra apósSRVgerando erro de lint YAML. Por favor, remova esse espaço para atender às regras do YAMLlint.🧰 Tools
🪛 YAMLlint (1.35.1)
[error] 51-51: trailing spaces
(trailing-spaces)
Resources/Locale/en-US/_Goobstation/research/ui.ftl (1)
6-12: Textos de interface bem definidosOs textos de localização estão bem definidos e cobrem todas as necessidades da nova interface do console de pesquisa. Eles são claros e informativos, proporcionando uma boa experiência ao usuário.
Seria adequado também criar a versão em português (pt-BR) destes textos para manter a consistência de idiomas no jogo.
Content.Shared/_Goobstation/Research/SharedResearchSystem.Goob.cs (1)
16-17: Considerar melhoria de performance para chamadas frequentesA enumeração e filtragem de todos os protótipos de tecnologia pode ser ineficiente se este método for chamado com frequência. Considere armazenar em cache os resultados ou otimizar esta operação para melhorar o desempenho.
Content.Client/_Goobstation/Research/UI/FancyResearchConsoleMenu.xaml (4)
8-15: Considerar redimensionamento dinâmico da janela
Atualmente oFancyWindowusaSetSize="1260 850", o que fixa o tamanho inicial. Para evitar cortes ou barras de rolagem indesejadas em resoluções menores, sugiro adicionar propriedades comoMinSizeou habilitar flags de redimensionamento (SizeFlagsExpand) conforme as diretrizes de UI.
41-44: Extrair cor hard-coded para recurso de tema
OBackgroundColor="#000000FF"está definido inline. Para facilitar manutenção e consistência com temas futuros, considere mover essa cor para um recurso XAML (ex.:<Color x:Key="ResearchBackground">#000000FF</Color>).
57-58: Evitar margin negativa em botão
ORecenterButtonusaMargin="5 -5", o que pode gerar cortes em torno do botão. Avalie a possibilidade de ajustar a margem ou usar padding interno no container em vez de valores negativos.
60-70: Adicionar ScrollContainer para painel de informações
OInfoContainerestá preparado para exibir detalhes, mas se houver overflow de conteúdo, umScrollContainerao redor do BoxContainer pode melhorar a usabilidade.Tools/TechTreeManager/MasterArsenal.yml (2)
218-226: Ausência de pré-requisitos em PrototypeWeapons
PrototypeWeaponsestá em tier 3 mas não possuitechnologyPrerequisites. Para manter a hierarquia de tiers, avalie adicionar pré-requisito, comoAdvancedWeapons.
303-316: Sugestão: adicionar pré-requisito a KineticModifications
KineticModificationsé tier 2 sem dependências; provavelmente deveria exigirBasicWeaponsou nível equivalente para manter a progressão lógica.Tools/TechTreeManager/MasterExperimental.yml (1)
1-195: Sugestão: definir dependências para tiers avançados
Para tecnologias de tier 2 e 3 em Experimental, especifiquetechnologyPrerequisitesadequados (por exemplo,BasicAnomalousResearch→AdvancedAnomalyResearch) para guiar a progressão.Resources/Prototypes/_Goobstation/Research/experimental.yml (1)
20-20: Sugerir uso de sequência YAML para posição
Para evitar ambiguidades de parsing e deixar o formato mais claro, considere usar uma lista YAML:-position: 7,1 +position: [7, 1]Tools/TechTreeManager/web/style.css (1)
1-5: Estilização dobodyparece consistente
Definirfont-family,marginepaddingnobodygarante base limpa.
Como sugestão opcional, adicione:* { box-sizing: border-box; }para melhorar o cálculo de tamanho de elementos.
Tools/TechTreeManager/web/index.html (2)
4-5: Adicionar meta viewport para responsividadeÉ recomendável inserir
<meta name="viewport" content="width=device-width, initial-scale=1.0">logo após a declaração de charset para garantir que a interface se adapte corretamente em diferentes tamanhos de tela.
22-23: Especificartype="button"nos botõesPor padrão,
<button>semtypepode atuar como submit em um formulário futuro. Para evitar comportamentos indesejados, adicionetype="button"em:<button id="save" type="button">Save</button> <button id="download" type="button">Download YAML</button>Resources/Prototypes/_Shitmed/Research/civilianservices.yml (4)
17-17: Usar sequência YAML parapositionEm vez de uma string
" -4,-3", prefira um array para tipagem explícita:-position: -4,-3 +position: [ -4, -3 ]Isso evita ambiguidades de parsing e alinha-se a boas práticas de YAML.
36-36: Unificar formato depositionMesma recomendação para esta entrada:
-position: -2,-4 +position: [ -2, -4 ]
49-52: Padronizar definição depositione validartechnologyPrerequisitesPara
Autodoc, convertapositionem uma sequência e confira a indentação:-position: -3,-4 -technologyPrerequisites: - - AdvancedTreatment +position: [ -3, -4 ] +technologyPrerequisites: + - AdvancedTreatment
65-68: Atualizar formato depositionem HighEndSurgeryMesmo ajuste para manter consistência:
-position: -4,-4 -technologyPrerequisites: - - AdvancedTreatment +position: [ -4, -4 ] +technologyPrerequisites: + - AdvancedTreatmentContent.Client/_Goobstation/Research/UI/FancyResearchConsoleItem.xaml (1)
8-11: Remover namespace não utilizadoxmlns:gfxO prefixo
gfxnão é referenciado neste arquivo (você usagraphics:). Para clareza, remova:- xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"Resources/Locale/pt-BR/_Goobstation/research/ui.ftl (1)
6-8: Ajustar capitalização de legendasEm PT-BR, recomenda-se caixa baixa após a primeira palavra em labels:
-research-console-unlocks-text = Receitas Desbloqueadas: +research-console-unlocks-text = Receitas desbloqueadas: -research-console-required-text = Pré-Requisitos: +research-console-required-text = Pré-requisitos:Content.Client/_Goobstation/Research/UI/MiniRecipeCardControl.xaml (1)
13-19: Evitar margin negativa para layoutO
Margin="0 0 -5 0"noPanelContaineré um workaround que pode gerar confusão. Considere realinhar ou ajustarHorizontalExpand/SeparationOverrideem vez de usar margem negativa para manter o layout mais legível.Tools/TechTreeManager/web/all_view.html (3)
6-22: Adicionar metatag de viewport para responsividade móvel
Sem<meta name="viewport">, a página pode ficar ilegível em dispositivos móveis, pois o canvas tem largura fixa de 2000 px. Inclua a metatag para que o layout se adapte a diferentes tamanhos de tela.<meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0">
25-33: Melhorar acessibilidade e semântica dos controles
- O
<input type="file">não possui<label>, dificultando uso por leitores de tela.- O
<button>não especificatype="button"; embora fora de<form>isso não quebre nada, é boa prática.- Considere adicionar
aria-labelao canvas para descrever seu propósito (ex.: “Área de visualização da árvore tecnológica”).Exemplo:
- <input type="file" id="file-input" multiple> + <label for="file-input">Carregar YAMLs:</label> + <input type="file" id="file-input" multiple> - <button id="export">Download All YML</button> + <button id="export" type="button">Baixar YAML unificado</button>
29-33: Canvas com tamanho fixo pode causar uso excessivo de memória
Definirwidth="2000"eheight="2000"força alocação constante de ~16 MB para cada instância do canvas. Caso a ferramenta precise apenas exibir parte da árvore, considere ajustar o tamanho via CSS ou dimensionar dinamicamente conforme o conteúdo/zoom para reduzir consumo de recursos.Content.Server/Research/Systems/ResearchSystem.Console.cs (1)
73-108: Enumerar protótipos a cada atualização pode degradar desempenho
PrototypeManager.EnumeratePrototypes<TechnologyPrototype>().ToList()é chamado sempre que pontos mudam ou o UI é aberto. Em servidores com centenas de tecnologias, isso gera alocações e LINQ extra desnecessário. Armazene a lista em cache (ex.: camporeadonlypreenchido emInitialize) ou use umLazy<T>para evitar re-enumerar.Content.Client/_Goobstation/Research/UI/ResearchesContainerPanel.cs (2)
40-52: Variáveis alocadas dentro deDrawgeram GC em cada frame
new Vector2(...)eColor.Whitesão criados por iteração. Em UIs renderizadas a 60 FPS, isso pressiona o GC. CacheColor.White(já é struct, ok) e calcule vetores com métodos que evitam instanciar novos objetos, ou use camposVector2reutilizados.
43-49: Conexão ortogonal apenas para diferenças verticais
O código trata somente quandoYdifere; seXdiferir masYfor igual, sempre desenha linha reta, o que pode atravessar outros nós. Avalie sempre usar a conexão em “L” quando existir qualquer deslocamento nos dois eixos.Tools/TechTreeManager/web/default.yml (1)
1-1096: Excelente estruturação dos dados da árvore tecnológica!O arquivo YAML define de forma abrangente todas as tecnologias do jogo com uma estrutura consistente e bem organizada. Cada entrada contém todos os metadados necessários:
- Identificadores, nomes e ícones bem definidos
- Agrupamento lógico por disciplina e nível
- Posicionamento espacial para visualização em árvore
- Pré-requisitos claramente definidos
- Listas detalhadas de receitas desbloqueadas
Algumas observações e sugestões:
- Algumas tecnologias possuem campos adicionais
_xe_yalém doposition- seria útil documentar a diferença entre eles- Considere adicionar comentários separando as diferentes disciplinas para facilitar a navegação no arquivo
- Verifique se todas as receitas desbloqueadas nos campos
recipeUnlocksrealmente existem nos protótipos do jogo- type: technology id: BasicWeapons name: research-technology-basic-weapons + # Arsenal - Tier 1 icon: sprite: Objects/Weapons/Guns/Battery/laser_gun.rsi state: iconContent.Client/_Goobstation/Research/UI/FancyTechnologyInfoPanel.xaml.cs (3)
57-63: Estado "Available" não está sendo tratado no switch de coresO switch para determinar cores não inclui uma condição explícita para
ResearchAvailability.Available. Embora o caso padrão (_) retornenull, seria mais claro incluir o casoAvailableexplicitamente para melhorar a legibilidade e manutenção.Color? color = availability switch { ResearchAvailability.Researched => Color.LimeGreen, ResearchAvailability.PrereqsMet => Color.Crimson, ResearchAvailability.Unavailable => Color.Crimson, + ResearchAvailability.Available => null, _ => null };
69-70: Botão desabilitado com critérios invertidosA lógica para desabilitar o botão está definida corretamente, mas para maior clareza, considere usar uma expressão positiva em vez de negativa. Isto pode tornar o código mais fácil de ler à primeira vista.
- ResearchButton.Disabled = !hasAccess || availability != ResearchAvailability.Available; + ResearchButton.Disabled = !(hasAccess && availability == ResearchAvailability.Available);ou alternativa mais legível:
- ResearchButton.Disabled = !hasAccess || availability != ResearchAvailability.Available; + ResearchButton.Enabled = hasAccess && availability == ResearchAvailability.Available;
33-71: Reorganização do construtor pode melhorar legibilidadeO construtor contém muitas inicializações e configurações. Considere extrair mais blocos lógicos em métodos auxiliares privados, semelhante ao que foi feito com
InitializePrerequisiteseInitializeRecipeUnlocks.Exemplo de refatoração:
public FancyTechnologyInfoPanel(TechnologyPrototype proto, bool hasAccess, ResearchAvailability availability, SpriteSystem sprite) { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); var lathe = _ent.System<LatheSystem>(); var research = _ent.System<ResearchSystem>(); Prototype = proto; InitializeLabelsAndTextures(proto, sprite); InitializePrerequisites(proto, research, sprite); InitializeRecipeUnlocks(proto, lathe, sprite); ConfigureResearchButton(hasAccess, availability, proto); ResearchButton.OnPressed += Bought; } private void InitializeLabelsAndTextures(TechnologyPrototype proto, SpriteSystem sprite) { TechnologyNameLabel.Text = Loc.GetString(proto.Name); DisciplineTexture.Texture = sprite.Frame0(_proto.Index(proto.Discipline).Icon); TechnologyTexture.Texture = sprite.Frame0(proto.Icon); } private void ConfigureResearchButton(bool hasAccess, ResearchAvailability availability, TechnologyPrototype proto) { ResearchButton.ToolTip = !hasAccess ? Loc.GetString("research-console-no-access-popup") : null; ResearchButton.Text = availability == ResearchAvailability.Researched ? Loc.GetString("research-console-menu-server-researched-button") : ResearchButton.Text; Color? color = availability switch { ResearchAvailability.Researched => Color.LimeGreen, ResearchAvailability.PrereqsMet => Color.Crimson, ResearchAvailability.Unavailable => Color.Crimson, _ => null }; TechnologyCostLabel.SetMessage( Loc.GetString("research-console-tech-cost-label", ("cost", proto.Cost)), defaultColor: color ); ResearchButton.Disabled = !hasAccess || availability != ResearchAvailability.Available; }Tools/TechTreeManager/web/all_view.js (2)
30-62: Otimizar a função de desenho para melhor desempenho e visualizaçãoA função
draw()tem algumas limitações:
- Não há escala dinâmica para ajustar ao tamanho do canvas
- O texto pode estourar as bordas dos retângulos para IDs longos
- Não há diferenciação visual entre tecnologias de diferentes disciplinas ou tiers
Considere melhorar a visualização com cores diferentes para tiers, tamanho de texto ajustado e visualização mais detalhada.
function draw() { ctx.clearRect(0, 0, canvas.width, canvas.height); for (const tech of techs) { const [x, y] = tech.position.split(',').map(Number); tech._x = x * 100 + canvas.width / 2; tech._y = y * 100 + canvas.height / 2; } + // Desenha linhas de conexão com cores baseadas no nível de dependência for (const tech of techs) { if (tech.technologyPrerequisites) { for (const id of tech.technologyPrerequisites) { const target = techs.find(t => t.id === id); if (target) { ctx.beginPath(); ctx.moveTo(tech._x + 50, tech._y + 25); ctx.lineTo(target._x + 50, target._y + 25); - ctx.strokeStyle = '#aaa'; + ctx.strokeStyle = tech.tier === target.tier ? '#aaa' : '#888'; + ctx.lineWidth = 2; ctx.stroke(); } } } } for (const tech of techs) { + // Cores diferentes para os diferentes tiers + const tierColors = ['#f8f8ff', '#eef', '#ddf', '#ccf']; + const tierColor = tierColors[Math.min(tech.tier || 0, tierColors.length - 1)]; - ctx.fillStyle = '#fff'; + ctx.fillStyle = tierColor; ctx.strokeStyle = '#000'; ctx.fillRect(tech._x, tech._y, 100, 50); ctx.strokeRect(tech._x, tech._y, 100, 50); ctx.fillStyle = '#000'; - ctx.fillText(tech.id, tech._x + 5, tech._y + 20); + // Trunca IDs longos + const displayId = tech.id.length > 12 ? tech.id.substring(0, 10) + '...' : tech.id; + ctx.font = '12px Arial'; + ctx.fillText(displayId, tech._x + 5, tech._y + 20); + + // Adiciona o tier e o custo + ctx.font = '10px Arial'; + ctx.fillText(`T${tech.tier} (${tech.cost})`, tech._x + 5, tech._y + 40); } }
101-108: Adicionar feedback visual ao exportarA função de exportação não fornece feedback visual ao usuário após a exportação, o que pode confundir os usuários sobre se a operação foi bem-sucedida.
function exportYML() { const yaml = jsyaml.dump(techs, { lineWidth: -1 }); const blob = new Blob([yaml], { type: "text/yaml" }); const link = document.createElement("a"); link.href = URL.createObjectURL(blob); link.download = "combined_tech.yml"; link.click(); + + // Mostrar feedback ao usuário + const status = document.createElement("div"); + status.textContent = "Arquivo exportado com sucesso!"; + status.style.position = "fixed"; + status.style.bottom = "20px"; + status.style.right = "20px"; + status.style.padding = "10px"; + status.style.backgroundColor = "#4CAF50"; + status.style.color = "white"; + status.style.borderRadius = "5px"; + document.body.appendChild(status); + + // Remover o feedback após alguns segundos + setTimeout(() => { + document.body.removeChild(status); + }, 3000); }Tools/TechTreeManager/UpdateAllYML/appUpdate.py (2)
24-25: Importação desnecessária em local incomum.A importação do módulo io está posicionada no meio do código, quando deveria estar agrupada com as outras importações no início do arquivo.
-import ioE adicione esta linha no início do arquivo junto com as outras importações:
import os import yaml +import io
26-67: Lógica de atualização de arquivos bem implementada, mas poderia ser documentada.A função update_file possui uma implementação cuidadosa para preservar a formatação YAML, mas a abordagem específica de serialização (escrevendo cada item individualmente e removendo os colchetes) poderia ser melhor documentada para facilitar a manutenção futura.
Considere adicionar um comentário explicativo mais detalhado sobre o motivo desta abordagem personalizada:
- # Dump each item individually + # Serialização individual de cada item para manter formatação consistente + # e garantir que cada tecnologia fique em sua própria seção YAML. + # Esta abordagem preserva a estrutura dos arquivos originais.Content.Client/_Goobstation/Research/UI/FancyResearchConsoleBoundUserInterface.cs (2)
20-25: Melhore o formato do comentário de migração.O comentário que explica a migração de ResearchConsoleMenu para FancyResearchConsoleMenu é útil, mas está muito longo para uma linha de comentário inline.
- private FancyResearchConsoleMenu? _consoleMenu; // Goobstation R&D Console rework - ResearchConsoleMenu -> FancyResearchConsoleMenu + // Parte do Goobstation R&D Console rework - Substitui ResearchConsoleMenu + private FancyResearchConsoleMenu? _consoleMenu;
65-80: Otimização da atualização de estado pode ser melhorada.A verificação para evitar atualizações desnecessárias é uma boa prática, mas a estrutura de código com múltiplos retornos e condicionais aninhados pode ser simplificada.
protected override void UpdateState(BoundUserInterfaceState state) { base.UpdateState(state); if (state is not ResearchConsoleBoundInterfaceState castState) return; // Goobstation checks added // Thats for avoiding refresh spam when only points are updated - if (_consoleMenu == null) - return; - if (!_consoleMenu.List.SequenceEqual(castState.Researches)) - _consoleMenu.UpdatePanels(castState.Researches); - if (_consoleMenu.Points != castState.Points) - _consoleMenu.UpdateInformationPanel(castState.Points); + if (_consoleMenu != null) + { + // Atualiza painéis apenas se a lista de pesquisas mudou + if (!_consoleMenu.List.SequenceEqual(castState.Researches)) + _consoleMenu.UpdatePanels(castState.Researches); + + // Atualiza painel de informações apenas se os pontos mudaram + if (_consoleMenu.Points != castState.Points) + _consoleMenu.UpdateInformationPanel(castState.Points); + } }Tools/TechTreeManager/app.py (2)
1-5: Remova importação não utilizada do módulo ttk.O módulo ttk está sendo importado mas não é utilizado no código.
import os import yaml import tkinter as tk -from tkinter import ttk, messagebox +from tkinter import messagebox🧰 Tools
🪛 Ruff (0.8.2)
4-4:
tkinter.ttkimported but unusedRemove unused import:
tkinter.ttk(F401)
69-75: Considere adicionar escala configurável para o grid.A função display_grid usa um tamanho fixo de 100x100 para cada célula. Seria útil ter a possibilidade de ajustar este tamanho.
def display_grid(self): + # Tamanho de cada célula + cell_size = 100 + for (x, y), label in self.grid_data.items(): - screen_x = x * 100 - screen_y = y * 100 - self.canvas.create_rectangle(screen_x, screen_y, screen_x + 100, screen_y + 100, fill="lightblue") - self.canvas.create_text(screen_x + 50, screen_y + 50, text=label, anchor="center") + screen_x = x * cell_size + screen_y = y * cell_size + self.canvas.create_rectangle(screen_x, screen_y, screen_x + cell_size, screen_y + cell_size, fill="lightblue") + self.canvas.create_text(screen_x + cell_size/2, screen_y + cell_size/2, text=label, anchor="center")Tools/TechTreeManager/FetchAllResearchYML.py (1)
6-34: Considere refatorar a lógica de travessia de diretórios em um módulo compartilhado.A função collect_ymls implementa uma lógica de travessia de diretórios similar à encontrada em outros scripts (app.py, appUpdate.py). Esta funcionalidade poderia ser extraída para um módulo comum para evitar duplicação.
Você poderia criar um módulo comum (
common_utils.py) com uma função para encontrar arquivos alvo:# Novo arquivo: common_utils.py import os def find_target_files(target_files, base_path=None): """ Encontra arquivos alvo em diretórios Research. Args: target_files: Conjunto de nomes de arquivos a serem encontrados base_path: Caminho base opcional (padrão: path relativo ao Prototypes) Returns: Lista de tuplas (caminho_completo, nome_arquivo) """ if base_path is None: base_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "Resources", "Prototypes")) result = [] direct_research = os.path.join(base_path, "Research") # Check direct Research folder if os.path.isdir(direct_research): for file in os.listdir(direct_research): if file in target_files: result.append((os.path.join(direct_research, file), file)) # Check each subfolder in Prototypes for Research for folder in os.listdir(base_path): full_path = os.path.join(base_path, folder, "Research") if os.path.isdir(full_path): for file in os.listdir(full_path): if file in target_files: result.append((os.path.join(full_path, file), file)) return resultE então usar no script atual:
import os import yaml +import common_utils TARGET_FILES = {"arsenal.yml", "civilianservices.yml", "experimental.yml", "industrial.yml"} def collect_ymls(): result = {name: [] for name in TARGET_FILES} - start_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "Resources", "Prototypes")) - direct_research = os.path.join(start_path, "Research") - - def process_dir(path): - for file in os.listdir(path): - if file in TARGET_FILES: - full_path = os.path.join(path, file) - try: - with open(full_path, "r", encoding="utf-8") as f: - data = yaml.safe_load(f) - if isinstance(data, list): - result[file].extend(data) - except Exception as e: - print(f"Failed to read {full_path}: {e}") - - # Check direct Research folder - if os.path.isdir(direct_research): - process_dir(direct_research) - - # Check each subfolder in Prototypes for Research - for folder in os.listdir(start_path): - full_path = os.path.join(start_path, folder, "Research") - if os.path.isdir(full_path): - process_dir(full_path) + + target_files = common_utils.find_target_files(TARGET_FILES) + + for full_path, file_name in target_files: + try: + with open(full_path, "r", encoding="utf-8") as f: + data = yaml.safe_load(f) + if isinstance(data, list): + result[file_name].extend(data) + except Exception as e: + print(f"Failed to read {full_path}: {e}") return resultContent.Client/_Goobstation/Research/UI/FancyResearchConsoleItem.xaml.cs (2)
24-26: Evite campos públicos: transforme-os em propriedades somente-leituraExpor
Prototype,SelectActioneAvailabilitycomo campos públicos viola o encapsulamento e facilita modificações acidentais vindas de fora do controle. Prefira propriedadesinit-only ouget-only para tornar a API mais segura.
90-93: Chamebase.DrawModeChanged()no overrideSem a chamada ao método base, a lógica interna de
Buttonque depende dessa notificação pode falhar (por exemplo, alteração de estado visual padrão).protected override void DrawModeChanged() { + base.DrawModeChanged(); OnDrawModeChanged?.Invoke(); }Tools/TechTreeManager/web/app.js (2)
68-81: Melhore performance criando um mapa de busca para pré-requisitosDentro do duplo
for, cadafindé O(n²). Para árvores grandes, o render travará. Monte um dicionárioid → techuma única vez:const idMap = Object.fromEntries(techs.map(t => [t.id, t])); ... const target = idMap[prereqId];
109-121: Throttle odraw()durante o arraste usandorequestAnimationFrameChamar
draw()a cadamousemove(que pode disparar >100 vezes/seg) é custoso. Armazene um flag e desenhe na próxima animação.let needsRedraw = false; ... canvas.addEventListener("mousemove", (e) => { if (!dragging) return; ... - draw(); + needsRedraw = true; }); function loop() { if (needsRedraw) { draw(); needsRedraw = false; } requestAnimationFrame(loop); } loop();Content.Client/_Goobstation/Research/UI/FancyResearchConsoleMenu.xaml.cs (2)
66-68: Erro de digitação em_dragginO campo booleano possui typo; use
_draggingpara coerência com restante do código e melhor legibilidade.
170-176: Atualize posição única, não cada filho individualmenteDurante o arraste do “canvas”, cada child é movido e, depois, quando
Recenter()ou outro redraw ocorrer, a posição relativa será recalculada novamente, causando deriva acumulada. Considere armazenar apenas_positionglobal e recalcular posições de todos os filhos nodraw/UpdatePanels, similar ao que foi feito na classe JS.Tools/TechTreeManager/UpdateAllYML/updated.yml (1)
1-1120: Unificação de coordenadas: simplificarposition,_xe_y
Cada entrada declaraposition(às vezes como string, às vezes numérico) e também_x/_y, o que pode gerar discrepâncias de manutenção.
Recomendo migrar para um único objeto de coordenadas, por exemplo:position: x: 4 y: 0e remover os campos
_xe_yredundantes.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
Resources/Textures/_Goobstation/Interface/rnd-static.rsi/static.pngis excluded by!**/*.png
📒 Files selected for processing (51)
Content.Client/Research/UI/MiniTechnologyCardControl.xaml(2 hunks)Content.Client/_Goobstation/Research/UI/FancyResearchConsoleBoundUserInterface.cs(1 hunks)Content.Client/_Goobstation/Research/UI/FancyResearchConsoleItem.xaml(1 hunks)Content.Client/_Goobstation/Research/UI/FancyResearchConsoleItem.xaml.cs(1 hunks)Content.Client/_Goobstation/Research/UI/FancyResearchConsoleMenu.xaml(1 hunks)Content.Client/_Goobstation/Research/UI/FancyResearchConsoleMenu.xaml.cs(1 hunks)Content.Client/_Goobstation/Research/UI/FancyTechnologyInfoPanel.xaml(1 hunks)Content.Client/_Goobstation/Research/UI/FancyTechnologyInfoPanel.xaml.cs(1 hunks)Content.Client/_Goobstation/Research/UI/MiniRecipeCardControl.xaml(1 hunks)Content.Client/_Goobstation/Research/UI/MiniRecipeCardControl.xaml.cs(1 hunks)Content.Client/_Goobstation/Research/UI/ResearchesContainerPanel.cs(1 hunks)Content.Server/Research/Systems/ResearchSystem.Console.cs(2 hunks)Content.Server/Research/Systems/ResearchSystem.Technology.cs(1 hunks)Content.Shared/Research/Components/SharedResearchConsoleComponent.cs(2 hunks)Content.Shared/Research/Prototypes/TechDisciplinePrototype.cs(2 hunks)Content.Shared/Research/Prototypes/TechnologyPrototype.cs(2 hunks)Content.Shared/Research/Systems/SharedResearchSystem.cs(5 hunks)Content.Shared/_Goobstation/Research/ResearchAvailability.cs(1 hunks)Content.Shared/_Goobstation/Research/SharedResearchSystem.Goob.cs(1 hunks)Resources/Locale/en-US/_Goobstation/research/ui.ftl(1 hunks)Resources/Locale/pt-BR/_Goobstation/research/ui.ftl(1 hunks)Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml(1 hunks)Resources/Prototypes/Nyanotrasen/Research/experimental.yml(2 hunks)Resources/Prototypes/Research/arsenal.yml(13 hunks)Resources/Prototypes/Research/civilianservices.yml(6 hunks)Resources/Prototypes/Research/disciplines.yml(4 hunks)Resources/Prototypes/Research/experimental.yml(11 hunks)Resources/Prototypes/Research/industrial.yml(16 hunks)Resources/Prototypes/_Arcadis/Entities/Objects/Computers/recipes.yml(1 hunks)Resources/Prototypes/_EE/Research/civilianservices.yml(1 hunks)Resources/Prototypes/_Goobstation/Research/arsenal.yml(3 hunks)Resources/Prototypes/_Goobstation/Research/civilianservices.yml(1 hunks)Resources/Prototypes/_Goobstation/Research/experimental.yml(1 hunks)Resources/Prototypes/_Lavaland/Research/arsenal.yml(1 hunks)Resources/Prototypes/_Shitmed/Research/civilianservices.yml(4 hunks)Resources/Textures/_Goobstation/Interface/rnd-static.rsi/meta.json(1 hunks)Tools/TechTreeManager/FetchAllResearchYML.py(1 hunks)Tools/TechTreeManager/MasterArsenal.yml(1 hunks)Tools/TechTreeManager/MasterCivilianservices.yml(1 hunks)Tools/TechTreeManager/MasterExperimental.yml(1 hunks)Tools/TechTreeManager/MasterIndustrial.yml(1 hunks)Tools/TechTreeManager/UpdateAllYML/appUpdate.py(1 hunks)Tools/TechTreeManager/UpdateAllYML/update_log.txt(1 hunks)Tools/TechTreeManager/UpdateAllYML/updated.yml(1 hunks)Tools/TechTreeManager/app.py(1 hunks)Tools/TechTreeManager/web/all_view.html(1 hunks)Tools/TechTreeManager/web/all_view.js(1 hunks)Tools/TechTreeManager/web/app.js(1 hunks)Tools/TechTreeManager/web/default.yml(1 hunks)Tools/TechTreeManager/web/index.html(1 hunks)Tools/TechTreeManager/web/style.css(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (5)
Content.Shared/_Goobstation/Research/SharedResearchSystem.Goob.cs (1)
Content.Shared/Research/Systems/SharedResearchSystem.cs (1)
SharedResearchSystem(12-303)
Tools/TechTreeManager/FetchAllResearchYML.py (3)
Tools/TechTreeManager/web/app.js (1)
yaml(22-22)Tools/TechTreeManager/web/all_view.js (1)
yaml(102-102)Tools/TechTreeManager/UpdateAllYML/appUpdate.py (1)
process_dir(76-80)
Content.Shared/Research/Systems/SharedResearchSystem.cs (1)
Content.Shared/_Goobstation/Research/SharedResearchSystem.Goob.cs (1)
SharedResearchSystem(12-25)
Content.Client/_Goobstation/Research/UI/FancyResearchConsoleBoundUserInterface.cs (2)
Content.Client/_Goobstation/Research/UI/FancyResearchConsoleMenu.xaml.cs (4)
FancyResearchConsoleMenu(76-92)SetEntity(94-95)UpdatePanels(97-116)UpdateInformationPanel(118-160)Content.Shared/Research/Components/SharedResearchConsoleComponent.cs (2)
ConsoleUnlockTechnologyMessage(18-21)ResearchConsoleBoundInterfaceState(39-43)
Tools/TechTreeManager/UpdateAllYML/appUpdate.py (3)
Tools/TechTreeManager/web/app.js (1)
yaml(22-22)Tools/TechTreeManager/web/all_view.js (1)
yaml(102-102)Tools/TechTreeManager/FetchAllResearchYML.py (1)
process_dir(11-21)
🪛 YAMLlint (1.35.1)
Resources/Prototypes/Research/disciplines.yml
[error] 12-12: trailing spaces
(trailing-spaces)
[error] 38-38: trailing spaces
(trailing-spaces)
[error] 51-51: trailing spaces
(trailing-spaces)
🪛 Ruff (0.8.2)
Tools/TechTreeManager/app.py
4-4: tkinter.ttk imported but unused
Remove unused import: tkinter.ttk
(F401)
🔇 Additional comments (101)
Resources/Prototypes/Research/disciplines.yml (1)
25-25: CampouiNameadicionado corretamente para Arsenal (SEC).
A sintaxe está correta e sem espaços extras. Esse ajuste alinha o protótipo à nova propriedade doTechDisciplinePrototype.Content.Shared/Research/Systems/SharedResearchSystem.cs (9)
12-12: Classe transformada em parcial para suportar extensõesA declaração da classe foi modificada para
partial, permitindo que a funcionalidade seja estendida em outros arquivos. Isso facilita a separação de responsabilidades e organização do código.
76-77: Verificação de restrição de tier comentadaA verificação de tier foi comentada como parte da reformulação do Console R&D do Goobstation. Isso remove as verificações de disciplina principal, potencialmente alterando a mecânica de jogo ao permitir que mais tecnologias estejam disponíveis independentemente do tier.
É importante verificar se esta alteração foi intencional e se ela não causará desequilíbrio na progressão do jogo. Confirme que outras partes do sistema levam em conta esta mudança de comportamento.
157-158: Substituição de AddMarkup por AddMarkupOrThrowO método
AddMarkupfoi substituído porAddMarkupOrThrow, que lançará exceções quando ocorrerem erros de markup em vez de falhar silenciosamente.Esta é uma mudança positiva que facilita a detecção de erros durante o desenvolvimento.
166-167: Substituição de AddMarkup por AddMarkupOrThrowO método
AddMarkupfoi substituído porAddMarkupOrThrowpara garantir que erros de markup não sejam ignorados.
172-173: Substituição de AddMarkup por AddMarkupOrThrowO método
AddMarkupfoi substituído porAddMarkupOrThrowpara garantir que erros de markup sejam detectados imediatamente.
177-179: Substituição de AddMarkup por AddMarkupOrThrowContinuação da padronização do uso de
AddMarkupOrThrowem vez deAddMarkuppara melhorar a detecção de erros.
183-183: Substituição de AddMarkup por AddMarkupOrThrowMais uma substituição de
AddMarkupporAddMarkupOrThrowpara consistência e melhor tratamento de erros.
188-190: Substituição de AddMarkup por AddMarkupOrThrowSubstituição consistente de
AddMarkupporAddMarkupOrThrowna listagem de receitas desbloqueadas.
194-196: Substituição de AddMarkup por AddMarkupOrThrowÚltima substituição de
AddMarkupporAddMarkupOrThrowpara garantir consistência em todo o métodoGetTechnologyDescription.Content.Server/Research/Systems/ResearchSystem.Technology.cs (1)
88-88:Details
❓ Verification inconclusive
Confirmação necessária sobre a alteração do comportamento da disciplina principal.
A remoção da chamada para
TrySetMainDisciplinemodifica o comportamento do sistema quando uma nova tecnologia é desbloqueada. Isto parece ser parte da implementação da árvore tecnológica, mas é importante entender como as disciplinas principais são agora gerenciadas.Algumas questões a considerar:
- Como as disciplinas principais são agora determinadas sem esta chamada?
- Esta mudança foi testada para garantir que não causa efeitos colaterais inesperados?
- Seria útil adicionar um comentário mais detalhado explicando a razão desta alteração para futuros desenvolvedores.
🏁 Script executed:
#!/bin/bash # Verificar como as disciplinas principais são gerenciadas em outros lugares do código echo "Procurando por referências à MainDiscipline no código:" rg "MainDiscipline" --type csLength of output: 1268
Confirmação necessária: Gestão de
MainDisciplineapós remoção deTrySetMainDisciplineAntes de aprovar, precisamos entender como a disciplina principal está sendo definida sem aquela chamada:
- Em Content.Shared/Research/Systems/SharedResearchSystem.cs
• MétodoTrySetMainDisciplineainda atribuicomponent.MainDiscipline = prototype.Discipline.- Em Content.Server/Research/Systems/ResearchSystem.Technology.cs
• A chamada aTrySetMainDiscipline(prototype, serverEnt.Value)foi comentada.
• Há atribuição direta decomponent.MainDiscipline = nulle cópia deotherDb.MainDiscipline.- Na UI (Content.Client/Research/UI/ResearchConsoleMenu.xaml.cs) a label de disciplina principal depende desse valor.
Pontos a validar:
- Qual fluxo substitui a lógica original de
TrySetMainDisciplineno servidor?- Há testes que garantam que a disciplina principal seja atualizada corretamente ao desbloquear novas tecnologias?
- Sugiro adicionar um comentário resumindo a razão dessa alteração e documentar o novo comportamento para futuros mantenedores.
Resources/Prototypes/_Lavaland/Research/arsenal.yml (1)
14-14: Adição de posicionamento na árvore tecnológica.A adição do atributo
position: 5,1está alinhada com a reestruturação da árvore tecnológica, permitindo um posicionamento preciso desta tecnologia na nova interface do console de pesquisa.Content.Shared/Research/Prototypes/TechDisciplinePrototype.cs (1)
49-54: CampoUiNameadicionado corretamente para suportar a nova UI.A adição do campo
UiNamepara exibir nomes curtos nos botões de disciplina está bem documentada e implementada corretamente com o atributorequired: true, garantindo que todas as disciplinas forneçam este valor.Resources/Prototypes/_EE/Research/civilianservices.yml (1)
12-12: Posicionamento adicionado para visualização na árvore tecnológica.A adição do atributo
position: -1,-4está correta e consistente com as mudanças em outros arquivos de protótipos de pesquisa, permitindo o posicionamento espacial desta tecnologia na nova interface.Content.Shared/Research/Prototypes/TechnologyPrototype.cs (2)
76-81: PropriedadePositionadicionada corretamente para o sistema de árvore tecnológica.A implementação da propriedade
Positioncom um setter privado é uma boa prática para garantir imutabilidade após a inicialização. A documentação XML está clara e a marcação como campo obrigatório (required: true) garante que todas as tecnologias terão uma posição definida na interface.
1-82:Details
✅ Verification successful
Verificar possíveis tecnologias sem posição definida
Como a propriedade
Positionagora é obrigatória, é importante garantir que todos os protótipos de tecnologia existentes no projeto tenham esta propriedade definida, caso contrário, poderá haver erros durante a inicialização do jogo.
🏁 Script executed:
#!/bin/bash # Verificar protótipos de tecnologia sem a propriedade "position" definida echo "Procurando por protótipos de tecnologia sem posição definida..." rg -l "- type: technology" Resources/Prototypes/ | xargs rg -l "id: " | xargs grep -L "position: " | sortLength of output: 66185
🏁 Script executed:
#!/bin/bash # Verificar protótipos de tecnologia sem 'position' definido echo "Procurando arquivos YAML de protótipos de tecnologia sem 'position:'..." rg -l "^\s*-\s*type:\s*technology" Resources/Prototypes/ --glob '*.yml' | xargs grep -L "^\s*position:" | sortLength of output: 271
Verificação concluída: todas as tecnologias têm
PositiondefinidoNão foram encontrados protótipos
type: technologysem a propriedadeposition:nos arquivos YAML em Resources/Prototypes. Não há ajustes adicionais necessários.Resources/Prototypes/_Goobstation/Research/arsenal.yml (3)
24-24: Coordenadas de posição adicionadas corretamente!A adição de coordenadas de posição para a tecnologia Gygax parece apropriada para a visualização da árvore tecnológica na nova interface do console de pesquisa.
39-39: Posicionamento consistente para ExplosiveMechAmmunitionA posição 5,3 parece bem alinhada com o layout geral da árvore de tecnologia, permitindo uma visualização adequada dos relacionamentos com outras tecnologias.
64-65: Coordenadas e pré-requisitos bem definidos para DurandA posição 4,3 para Durand, combinada com seu pré-requisito (Gygax em 4,4), cria uma relação visual lógica na árvore de tecnologias, onde Durand aparece acima de seu pré-requisito Gygax.
Content.Shared/_Goobstation/Research/ResearchAvailability.cs (1)
14-21: Enumeração bem definida para estados de disponibilidade de pesquisaA enumeração
ResearchAvailabilityestá bem estruturada com quatro estados claramente definidos que representam os diferentes níveis de disponibilidade de uma tecnologia (Pesquisada, Disponível, Pré-requisitos Atendidos e Indisponível). A definição como serializável e serializável para rede permitirá uma comunicação eficiente entre cliente e servidor.Resources/Textures/_Goobstation/Interface/rnd-static.rsi/meta.json (3)
5-8: Dimensões da textura parecem apropriadasAs dimensões de 1284x724 pixels são adequadas para uma textura de interface de usuário de console de pesquisa.
9-20: Configuração de animação adequadaA configuração da animação "static" com quatro frames e delay uniforme de 0.05 segundos parece apropriada para um efeito visual de estática.
3-4:Details
❓ Verification inconclusive
Verificar a fonte original da textura
A atribuição de direitos autorais menciona que a textura foi obtida do Pinterest, que é um agregador de conteúdo e não uma fonte original. Seria mais adequado identificar e creditar o criador original da textura para garantir compliance com a licença CC-BY-SA-3.0.
🌐 Web query:
Qual a fonte original da imagem com PIN https://www.pinterest.com/pin/681450987343974739/?💡 Result:
Para identificar a fonte original de uma imagem no Pinterest, é importante seguir alguns passos, pois muitas vezes as imagens são compartilhadas sem créditos ou podem ter sido retiradas de suas fontes originais. Vamos analisar a imagem referenciada pelo PIN 681450987343974739:
1. Verificação do Pinterest
- O link leva a uma página do Pinterest, onde normalmente estão disponíveis informações como:
- Quem salvou o PIN
- Descrição da imagem
- Fonte (o site de onde a imagem pode ter sido originalmente pinada)
2. Análise da Fonte Apresentada
No caso desse PIN específico, navegando até a página, observa-se:
- Muitas vezes, a imagem pode não ter um link claro para a fonte original, principalmente se foi carregada diretamente por um usuário.
- Se houver um link "visit", "ir para o site", ou "salvo de...", clique nele para ver se redireciona para a fonte.
- Se a imagem foi apenas "Enviada por usuário", provavelmente não há fonte original listada.
3. Pesquisa Reversa de Imagem
Se o Pinterest não indicar a fonte:
- Faça o download da imagem (se permitido).
- Use ferramentas de busca reversa de imagem (como Google Imagens, TinEye) para tentar localizar outros sites que publicaram a mesma imagem.
- Muitas vezes, a fonte original pode ser um site de fotografia, um blog, uma loja virtual, ou um perfil em rede social.
4. Resultado de Consulta Direta (Resumo)
Ao acessar o PIN 681450987343974739:
- Não há indicação direta de fonte original na página Pinterest.
- O PIN foi salvo por um usuário e não há link para um site externo de onde a imagem foi retirada.
- Provavelmente a imagem foi enviada diretamente ao Pinterest (upload feito pelo usuário).
Como Encontrar a Fonte Original
- Clique em “Salvo de” (caso disponível): Isso pode levar ao site original.
- Faça uma busca reversa da imagem: Baixe a imagem e use Google Imagens ou TinEye para encontrar possíveis fontes originais.
- Procure marca d’água ou texto na imagem: Às vezes, indica o autor ou o site de origem.
Resumo Final
A fonte original da imagem do PIN 681450987343974739 não está indicada na página do Pinterest. Para identificar a origem, recomenda-se usar busca reversa de imagem. Se precisar de ajuda com a busca reversa, me envie uma descrição da imagem ou, se possível, um link direto para a imagem em alta resolução — assim posso instruí-lo sobre como realizar esse procedimento.
Verificar fonte original da textura
A atribuição em
Resources/Textures/_Goobstation/Interface/rnd-static.rsi/meta.jsonatualmente aponta apenas para o Pinterest, que é um agregador e não garante identificação do autor original. Para cumprir a licença CC-BY-SA-3.0, é necessário:
- Realizar busca reversa de imagem (Google Imagens, TinEye) com o arquivo de textura.
- Se encontrar o site ou perfil do criador, atualizar o campo
"copyright"com o nome do autor e a URL original.- Se não for possível localizar a fonte, documentar no repositório o método de pesquisa e o resultado obtido.
Content.Client/_Goobstation/Research/UI/FancyResearchConsoleMenu.xaml (3)
1-6: Verificação de cabeçalho e licença
O cabeçalho SPDX está consistente e segue a mesma licença do projeto.
15-32: Layout do painel de topo está claro
A disposição vertical/horizontal e o uso de um placeholder (<Control VerticalExpand="True"/>) estão corretos e garantem que o rótulo e o display de níveis se ajustem corretamente.
45-57: Configuração do container de pesquisas
O uso deAnimatedTextureRectcontendo oResearchesContainerPanelcomRectClipContent="True"eMouseFilter="Pass"está correto para suportar arraste e zoom.Resources/Prototypes/Research/civilianservices.yml (6)
31-34: Adição de posição e pré-requisito em BasicCybernetics
Excelente inclusão deposition: -1,-2etechnologyPrerequisites: [BasicElectronics]. Isso alinha o protótipo ao novo layout.
60-61: Adição de posição em BasicElectronics
Bom trabalho definindoposition: 0,-2para o nó inicial de eletrônica.
85-88: Adição de posição e pré-requisito em BasicLifeImprovements
position: -2,-3e dependência deBasicCyberneticsestão corretos para a sequência de pesquisa.
108-109: Adição de posição em HONKMech
position: -4,-5posiciona corretamente o nó HONKMech, favor confirmar sem pré-requisitos intencionais.
124-126: Adição de posição em AdvancedLifeImprovements
position: 0,-5esoftCapContributionconfigurada adequadamente.
148-150: Adição de posição e pré-requisito em AdvancedTranslation
position: -2,-5e dependênciaCyberneticEnhancementssatisfazem a lógica de progressão.Tools/TechTreeManager/MasterExperimental.yml (1)
176-187: Pré-requisito cross-discipline em ModsuitsTech
ModsuitsTechrequerAdvancedTacsuits(Arsenal). Confirme se dependências entre disciplinas são suportadas e se o ID está correto.Resources/Prototypes/Research/industrial.yml (16)
15-18: Verificar desbloqueio e posição deSalvageEquipment.
Foi adicionado o recipeUnlockMechEquipmentDrille a posição-1,0. Confirme se o ID do recipe está correto e se esta coordenada não conflita com outros nós do UI.
34-35: Confirmar posição deAdvancedPowercells.
A coordenada-2,3foi atribuída para este nó. Verifique se ela está de acordo com o layout pretendido e não gera sobreposição.
47-47: Validar posição deMechanicalCompression.
A posição-3,2foi adicionada; assegure-se de que está alinhada no grid do UI.
63-63: Validar posição deIndustrialEngineering.
Coordenada-1,1inserida; confirme consistência com o restante da disciplina.
78-82: Verificar nova receita e posição emPowerGeneration.
Foi incluídoPowerComputerCircuitboarde a posição-4,3. Certifique-se de que o recipe existe e a posição não causa conflito visual.
97-97: Confirmar posição deAtmosphericTech.
Coordenada-3,3adicionada; valide sua localização no layout.
117-117: Confirmar posição deRipleyAPLU.
Posição2,3definida; verifique alinhamento com outros nós de mecha.
132-132: Validar posição deSpaceScanning.
Coordenada-2,1adicionada; certifique-se de que corresponde ao design da árvore.
148-148: Validar posição deShuttlecraft.
Posição-4,2inserida; confira se mantém o espaçamento adequado entre níveis.
163-163: Confirmar posição deAdvancedAtmospherics.
Coordenada-2,2adicionada; valide sua colocação em relação aos demais nós.
175-183: Verificar receitas e pré-requisito emAdvancedToolsTechnology.
Foram adicionados vários recipeUnlocks (WelderExperimental, PowerDrill, JawsOfLife, BorgModuleAdvancedTool, BorgModuleRCD), além da posição-1,2e do pré-requisitoIndustrialEngineering. Garanta que todos os recipes existem e que a dependência está corretamente declarada.
197-197: Validar posição deMassExcavation.
Coordenada-3,0adicionada; confirme que está no local correto da árvore de tecnologia.
213-213: Confirmar posição deRipley2.
Posição2,4definida; verifique o alinhamento em relação aRipleyAPLU.
236-236: Validar posição deClarke.
Coordenada0,4inserida; assegure que está consistente com seu pré-requisitoRipley2.
253-255: Verificar posição e pré-requisito emBluespaceStorage.
Adicionadas posição-3,4e dependênciaPortableFission. Confirme que osoftCapContributionpermanece correto e que o prereq existe.
271-271: Validar posição dePortableFission.
Coordenada-2,4adicionada; confirme que reflete o posicionamento desejado e não causa conflito.Resources/Prototypes/Research/arsenal.yml (10)
14-14: Verificar receitas e posição deBasicWeapons.
Confira seWeaponMechCombatFiredartLaser,WeaponMechCombatDisablereMechEquipmentKineticAcceleratorestão corretos e existem. Confirme também a posição4,0no grid do UI.Also applies to: 23-24, 26-26
56-59: Validar posição e pré-requisito deDraconicMunitions.
Posição4,-1e dependênciaBasicWeaponsadicionadas; garanta que ambos estão corretos e que o relacionamento reflete o fluxo de pesquisa.
77-77: Verificar desbloqueio, posição e pré-requisito deUraniumMunitions.
Foi adicionadoSpeedLoaderRifleHeavyUranium, posição6,0e dependênciaBasicWeapons. Confirme existência do recipe e consistência do prereq.Also applies to: 87-90
104-107: Validar posição e pré-requisito deAdvancedTacsuits.
Posição6,1e dependênciaUraniumMunitionsinseridas; assegure que a ligação está correta para o tier seguinte.
125-128: VerificarExplosiveTechnology: posição e pré-requisito.
Coordenada5,2e dependênciaAdvancedTacsuitsadicionadas; confirme alinhamento no layout e exatidão do prereq.
151-153: ValidarShrapnelMunitions: posição e pré-requisito.
Posição6,2e dependênciaAdvancedTacsuitsinseridas; verifique consistência com o tier e fluxo de pesquisa.
177-187: VerificarAdvancedWeapons: desbloqueio, posição e pré-requisito.
RecipeWeaponMechCombatSolarisLaseradicionado, posição4,1e dependênciaBasicWeapons. Confirme validade do recipe e diagrama de pesquisa.
205-206: Validar posição dePrototypeTacsuits.
Coordenada7,2adicionada; confirme se reflete o design esperado para tier 3.
224-224: Confirmar posição deLaserTurrets.
Posição4,2adicionada; verifique o layout de conexão comAdvancedWeapons.
241-241: VerificarPrototypeWeapons: desbloqueio e posição.
RecipeWeaponMechCombatImmolationGunadicionado e posição7,3; assegure que o recipe exista e o nó esteja corretamente posicionado.Also applies to: 247-248
Resources/Prototypes/_Goobstation/Research/civilianservices.yml (1)
13-13: Validar posição deHONKWeapons.
Coordenada0,-4atribuída; confirme que reflete o layout esperado e não entra em conflito com outras tecnologias.Content.Client/Research/UI/MiniTechnologyCardControl.xaml (1)
22-22: Ajuste de escala de textura emMiniTechnologyCardControl.
A propriedadeTextureScalefoi alterada de0.5 0.5para1 1. Verifique se essa mudança mantém a consistência visual em diferentes resoluções e não causa estouro de layout.Resources/Prototypes/_Arcadis/Entities/Objects/Computers/recipes.yml (1)
13-13: Validar posição deModularComputing.
Foi adicionada a coordenada-2,0; confirme que corresponde à exibição prevista no UI e não conflita com outros elementos do menu de pesquisa.Resources/Prototypes/_Goobstation/Research/experimental.yml (1)
20-20: Verificar formato e unicidade da posição de ModsuitsTech
A adição deposition: 7,1define onde o ícone aparecerá na árvore de pesquisa, mas é importante garantir que:
- O parser YAML do jogo reconheça esse formato (string “7,1”) corretamente.
- Não existam outras tecnologias usando as mesmas coordenadas, evitando sobreposição na UI.
Tools/TechTreeManager/web/style.css (3)
6-10: Estilo docanvasaprovado
Uma borda leve, margem e fundo suave tornam o canvas visível e arejado.
23-25: Largura dos inputs no editor OK
#editor input { width: 100%; }garante campos responsivos.
26-28: Labels como bloco estão adequados
label { display: block; }facilita alinhamento vertical dos rótulos.Resources/Prototypes/Nyanotrasen/Research/experimental.yml (2)
5-5: Validar caminho do sprite dePsionicCountermeasures
Foi alterado paraNyanotrasen/Clothing/Head/Helmets/insulative_skullcap.rsi.
Confirme se o arquivo existe com esse caminho e nome (sensível a maiúsculas/minúsculas) no diretório de sprites.
16-16: Verificar formato e colisão de posição
A entradaposition: -3,1define um local negativo na UI, o que é intencional, mas confirme que:
- O parser YAML aceita valores negativos nesse formato (string).
- Não haja outra tecnologia ocupando as mesmas coordenadas.
Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml (1)
600-602: Confirmar integração do novo BoundUserInterface
A interface foi trocada paraFancyResearchConsoleBoundUserInterface. Verifique se:
- A enum
ResearchConsoleUiKey.Keycontinua apontando corretamente para essa classe.- O cliente já carrega/registrou
FancyResearchConsoleBoundUserInterface.- Não restam referências à UI antiga (
ResearchConsoleBoundUserInterface) em outros protótipos.Content.Server/Research/Systems/ResearchSystem.Console.cs (1)
73-108: Possível NRE seTechnologyPrerequisitesfor null
O acessoproto.TechnologyPrerequisites.All(...)assume que a lista existe. Embora os protótipos atuais preencham o campo, uma omissão futura quebrará o método. Proteja com?.ou assegure lista vazia no protótipo por default.Content.Client/_Goobstation/Research/UI/FancyTechnologyInfoPanel.xaml (1)
1-114: Bom trabalho na estruturação da interface da árvore tecnológica!O layout XAML está bem organizado com uma hierarquia clara de contêineres e controles. Aprecio especialmente:
- A separação lógica entre as seções de informação, pré-requisitos e receitas desbloqueadas
- O uso adequado de ScrollContainer para listas potencialmente longas
- A implementação correta de localização para textos da interface
- A estrutura responsiva que se expande conforme necessário
Como sugestão para melhorar ainda mais a acessibilidade e usabilidade:
- Considere adicionar ToolTips para o botão de pesquisa e ícones de tecnologia
- Talvez incluir um indicador visual de progresso para tecnologias parcialmente pesquisadas
Content.Client/_Goobstation/Research/UI/MiniRecipeCardControl.xaml.cs (1)
1-43: Implementação limpa e bem estruturada do controle de cartão de receita!O código está bem organizado e segue boas práticas:
- Verificações apropriadas para valores nulos usando
HasValue- Boa integração com os sistemas de sprites e localização
- Implementação elegante de tooltips para descrições de receitas
Uma pequena sugestão para considerar:
- Poderia ser útil adicionar um método para atualizar dinamicamente a receita exibida, caso precise reutilizar o mesmo controle para diferentes receitas sem criar uma nova instância.
Content.Shared/Research/Components/SharedResearchConsoleComponent.cs (1)
33-43: Boa melhoria na estrutura de dados para disponibilidade de pesquisas!A substituição do
SoftCapMultiplierpor um dicionário completo de pesquisas e seus estados de disponibilidade é uma mudança significativa que oferece muito mais flexibilidade e clareza ao sistema.Esta alteração permite:
- Representação explícita do estado de cada tecnologia
- Melhor sincronização entre cliente e servidor
- Interface mais informativa com estados visuais diferenciados
Content.Client/_Goobstation/Research/UI/FancyTechnologyInfoPanel.xaml.cs (1)
97-102: Boa prática de limpeza em ExitedTreeExcelente implementação do método
ExitedTreepara remover o handler de evento ao sair da árvore UI. Isso evita vazamentos de memória e comportamentos inesperados que poderiam ocorrer se o controle fosse reutilizado.Resources/Prototypes/Research/experimental.yml (2)
111-112: Excelente adição de pré-requisitos tecnológicosA adição de pré-requisitos tecnológicos explícitos é uma melhoria significativa. Isso cria uma árvore tecnológica coerente e permite visualização adequada das dependências. Os pré-requisitos fazem sentido do ponto de vista de progressão:
- NightVisionTech e ThermalVisionTech dependem de AdvancedParts
- SuperParts depende de AdvancedParts
- GravityManipulation e QuantumLeaping dependem de SuperParts
Essa estrutura cria uma progressão lógica e equilibrada no sistema de pesquisa.
Also applies to: 126-127, 144-145, 161-162, 177-178
16-16: Posições consistentes na árvore tecnológicaA adição de coordenadas de posição para cada tecnologia é essencial para visualização em uma interface gráfica de árvore tecnológica. As posições parecem ter sido cuidadosamente escolhidas para criar um layout visualmente lógico:
- Tier 1: posições y entre -2 e -3
- Tier 2: posições y entre -3 e -4
- Tier 3: posição y em -5
Isso cria uma progressão visual de cima para baixo que se alinha com o aumento dos níveis de tier.
Also applies to: 33-33, 46-46, 62-62, 80-80, 94-94, 110-110, 125-125, 143-143, 160-160, 176-176
Tools/TechTreeManager/MasterIndustrial.yml (2)
197-199: Relações de pré-requisitos tecnológicos bem construídasAs relações de pré-requisitos definidas para as tecnologias industriais são lógicas e coerentes:
- Ripley2 requer RipleyAPLU como pré-requisito
- Clarke requer Ripley2 como pré-requisito
- PortableFission requer AdvancedPowercells como pré-requisito
Essas relações criam um caminho de progressão lógico e coerente para o jogador seguir.
Also applies to: 219-221, 249-251
10-17: Desbloqueios de receitas bem distribuídos entre as tecnologiasOs desbloqueios de receitas são bem distribuídos entre as várias tecnologias, oferecendo recompensas relevantes para cada avanço tecnológico. As tecnologias desbloquem itens que fazem sentido temático com seus nomes e áreas, como equipamentos de salvamento, células de energia avançadas, atmosféricos, etc.
Also applies to: 29-32, 43-44, 55-60, 70-77, 88-92, 102-110, 121-124, 135-139, 150-153, 164-169, 181-183, 194-196, 210-218, 231-235, 247-248
Tools/TechTreeManager/UpdateAllYML/appUpdate.py (5)
4-5: Conjunto de arquivos a serem atualizados bem definido.O TARGET_FILES define claramente quais arquivos de pesquisa serão processados pelo script.
7-21: Boa implementação da função de carregamento de itens.A função carrega corretamente os itens do arquivo YAML e remove as chaves de posição (_x, _y) antes de criar um dicionário baseado nos IDs. O tratamento de erros está bem implementado.
72-89: Boa implementação da travessia de diretórios.A função update_all_files encontra corretamente os arquivos alvo em ambos os diretórios de Research (direto e aninhado). A lógica é clara e consistente com outros scripts do projeto.
90-102: Registro de alterações implementado adequadamente.A função write_log cria um arquivo de log claro e informativo, com tratamento adequado de erros.
104-114: Interface de usuário em linha de comando simples e funcional.O bloco principal de execução solicita a entrada do usuário, valida o caminho do arquivo e processa as atualizações de forma clara e com mensagens informativas.
Content.Client/_Goobstation/Research/UI/FancyResearchConsoleBoundUserInterface.cs (5)
1-9: Cabeçalhos de copyright e licença adequados.Os cabeçalhos de copyright e licença seguem o padrão do projeto.
10-18: Importações organizadas corretamente.As importações estão organizadas de forma lógica, agrupando importações do sistema, do projeto compartilhado e do framework.
26-29: Construtor implementado corretamente.O construtor passa corretamente os parâmetros para a classe base.
30-49: Método Open implementado corretamente com bons gerenciadores de eventos.O método Open cria a janela da interface, define a entidade associada e configura os gerenciadores de eventos corretamente para enviar mensagens ao servidor quando o usuário interage com a interface.
51-63: Tratamento adequado de recarregamento de protótipos.O método OnProtoReload verifica corretamente se os protótipos de tecnologia foram modificados e atualiza a interface quando necessário.
Tools/TechTreeManager/app.py (4)
6-7: Conjunto de arquivos alvo bem definido e consistente com outros scripts.O TARGET_FILES define os mesmos arquivos alvo que são utilizados nos outros scripts do TechTreeManager.
8-27: Boa estrutura inicial da classe TechBrowser.A interface do visualizador é bem configurada com canvas, barras de rolagem e lista de tecnologias. A estrutura é clara e funcional.
46-68: Boa implementação da análise de arquivos YAML.A função parse_file carrega corretamente os arquivos YAML, extrai os dados relevantes e tem um tratamento de erros adequado. A conversão de posição para coordenadas é tratada de forma robusta.
77-82: Configuração da janela principal implementada corretamente.O código principal configura adequadamente a janela, define pesos para linhas e colunas, e inicia o loop principal do Tkinter.
Tools/TechTreeManager/FetchAllResearchYML.py (3)
1-4: Importações e constantes bem definidas.As importações são mínimas e adequadas, e o TARGET_FILES é consistente com os outros scripts.
35-48: Boa implementação da função de salvar arquivos master.A função save_master_files é bem implementada, com capitalização apropriada do nome do arquivo, formatação consistente e bom tratamento de erros.
49-51: Bloco principal simples e eficaz.O bloco principal executa as funções na ordem correta para coletar e salvar os dados.
Content.Client/_Goobstation/Research/UI/FancyResearchConsoleItem.xaml.cs (1)
37-58: Atualize a atribuição de cores após renomear os camposApós o ajuste sugerido acima, troque a tupla para usar
BaseColoreBaseBorderColor:- (Color, HoveredColor, BorderColor) = availability switch + (BaseColor, HoveredColor, BaseBorderColor) = availability switchSem esta correção, o código continuará referenciando os nomes antigos.
Tools/TechTreeManager/UpdateAllYML/updated.yml (5)
1-343: Bloco Arsenal: definições e custos coerentes
As tecnologias sob a disciplinaArsenal(linhas 1–343) apresentam estrutura consistente de tiers,costerecipeUnlocks.
IDs, nomes e ícones estão formatados de forma uniforme e sem erros aparentes.
344-568: Bloco CivilianServices: aprovação geral
As entradas deCivilianServices(linhas 344–568) mantêm a lógica de tiers e pré-requisitos correta.
Nenhuma inconsistência encontrada nasrecipeUnlocksou custo.
603-831: Bloco Experimental: conferência de tiers e softCapContribution
As tecnologias deExperimental(linhas 603–831) corretamente aplicamsoftCapContributionem tiers avançados.
Verifique se os valores (1.2 vs 1.5) estão alinhados com o balanceamento desejado.
833-1118: Bloco Industrial: consistência verificada
As entradas deIndustrial(linhas 833–1118) seguem o mesmo padrão de estrutura, tiers e dependências.
Sem problemas de formatação ou lógica detectados.
1-1120:Details
✅ Verification successful
Revisão geral: consistência de IDs e dependências de pesquisa
O arquivo define mais de 100 tecnologias agrupadas por disciplina (Arsenal, CivilianServices, Experimental, Industrial).
Sugiro validar que todos os valores emtechnologyPrerequisitescorrespondam aidexistentes e que a cadeia de pré-requisitos reflita a progressão desejada (sem lacunas ou ciclos).Execute este script para verificar referências inválidas:
🏁 Script executed:
#!/bin/bash pip install pyyaml python3 - << 'EOF' import yaml data = yaml.safe_load(open("Tools/TechTreeManager/UpdateAllYML/updated.yml")) ids = {t["id"] for t in data} errors = False for t in data: for prereq in t.get("technologyPrerequisites", []): if prereq not in ids: print(f"❌ Dependência inválida: '{prereq}' (usado em '{t['id']}')") errors = True if not errors: print("✅ Todas as dependências referenciam IDs válidos.") EOFLength of output: 248
Verificação de dependências concluída com sucesso
✅ Todas as entradas emtechnologyPrerequisitesreferenciam IDs existentes no arquivo.
Não foram encontradas dependências inválidas ou ausentes.
| public int GetTierCompletionPercentage(TechnologyDatabaseComponent component, TechDisciplinePrototype techDiscipline) | ||
| { | ||
| var allTech = PrototypeManager.EnumeratePrototypes<TechnologyPrototype>() | ||
| .Where(p => p.Discipline == techDiscipline.ID && !p.Hidden).ToList(); | ||
|
|
||
| var percentage = (float) component.UnlockedTechnologies | ||
| .Where(x => PrototypeManager.Index<TechnologyPrototype>(x).Discipline == techDiscipline.ID) | ||
| .Count() / (float) allTech.Count * 100f; | ||
|
|
||
| return (int) Math.Clamp(percentage, 0, 100); | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Implementar verificação de divisão por zero
O método GetTierCompletionPercentage calcula corretamente a porcentagem de tecnologias desbloqueadas, mas não contém proteção contra divisão por zero caso não existam tecnologias na disciplina especificada (quando allTech.Count for 0).
- var percentage = (float) component.UnlockedTechnologies
- .Where(x => PrototypeManager.Index<TechnologyPrototype>(x).Discipline == techDiscipline.ID)
- .Count() / (float) allTech.Count * 100f;
-
- return (int) Math.Clamp(percentage, 0, 100);
+ if (allTech.Count == 0)
+ return 0;
+
+ var percentage = (float) component.UnlockedTechnologies
+ .Where(x => PrototypeManager.Index<TechnologyPrototype>(x).Discipline == techDiscipline.ID)
+ .Count() / (float) allTech.Count * 100f;
+
+ return (int) Math.Clamp(percentage, 0, 100);📝 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.
| public int GetTierCompletionPercentage(TechnologyDatabaseComponent component, TechDisciplinePrototype techDiscipline) | |
| { | |
| var allTech = PrototypeManager.EnumeratePrototypes<TechnologyPrototype>() | |
| .Where(p => p.Discipline == techDiscipline.ID && !p.Hidden).ToList(); | |
| var percentage = (float) component.UnlockedTechnologies | |
| .Where(x => PrototypeManager.Index<TechnologyPrototype>(x).Discipline == techDiscipline.ID) | |
| .Count() / (float) allTech.Count * 100f; | |
| return (int) Math.Clamp(percentage, 0, 100); | |
| } | |
| public int GetTierCompletionPercentage(TechnologyDatabaseComponent component, TechDisciplinePrototype techDiscipline) | |
| { | |
| var allTech = PrototypeManager.EnumeratePrototypes<TechnologyPrototype>() | |
| .Where(p => p.Discipline == techDiscipline.ID && !p.Hidden).ToList(); | |
| if (allTech.Count == 0) | |
| return 0; | |
| var percentage = (float) component.UnlockedTechnologies | |
| .Where(x => PrototypeManager.Index<TechnologyPrototype>(x).Discipline == techDiscipline.ID) | |
| .Count() / (float) allTech.Count * 100f; | |
| return (int) Math.Clamp(percentage, 0, 100); | |
| } |
| - AdvancedTacsuits | ||
| softCapContribution: 1.5 | ||
| position: 6,2 | ||
| - type: technology |
There was a problem hiding this comment.
Posição duplicada em PrototypeTacsuits
PrototypeTacsuits está em position: 6,2, mesma coordenada de PrototypeWeapons. Ajuste para evitar colisão visual.
| - ExplosivePayload | ||
| - ChemicalPayload | ||
| position: 4,2 | ||
| technologyPrerequisites: | ||
| - AdvancedTacsuits | ||
| - type: technology | ||
| id: ShrapnelMunitions | ||
| name: research-technology-shrapnel-munitions |
There was a problem hiding this comment.
Posição duplicada em ShrapnelMunitions
Tanto ExplosiveTechnology (posição 4,2) quanto ShrapnelMunitions usam position: 4,2, o que causará sobreposição de nós na UI. Favor atribuir coordenadas únicas.
| - EnergyCutlass | ||
| - WeaponSubMachineGunBRDIR25 | ||
| softCapContribution: 1.5 | ||
| position: 6,2 | ||
| - type: technology |
There was a problem hiding this comment.
Posição duplicada em PrototypeWeapons
PrototypeWeapons também usa position: 6,2. Precisa de um novo par de coordenadas.
| id: Gygax | ||
| name: research-technology-gygax | ||
| icon: | ||
| sprite: Objects/Specific/Mech/mecha.rsi | ||
| state: gygax | ||
| discipline: Arsenal | ||
| tier: 2 | ||
| cost: 12000 | ||
| recipeUnlocks: | ||
| - GygaxHarness | ||
| - GygaxArmor | ||
| - GygaxHead | ||
| - GygaxLArm | ||
| - GygaxLLeg | ||
| - GygaxRArm | ||
| - GygaxRLeg | ||
| - GygaxCentralElectronics | ||
| - GygaxPeripheralsElectronics | ||
| - GygaxTargetingElectronics | ||
| - WeaponMechCombatUltraRifle | ||
| technologyPrerequisites: | ||
| - Ripley2 | ||
| position: 3,0 | ||
| - type: technology |
There was a problem hiding this comment.
Dependência inválida: Ripley2 não existe no arsenal
O Gygax lista technologyPrerequisites: [Ripley2], mas não há protótipo Ripley2 neste arquivo. Verifique se o ID está correto ou se faltou definir esse protótipo.
| def load_data(self): | ||
| start_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "Resources", "Prototypes")) | ||
| direct_research = os.path.join(start_path, "Research") | ||
|
|
||
| if os.path.isdir(direct_research): | ||
| for file in os.listdir(direct_research): | ||
| if file in TARGET_FILES: | ||
| self.parse_file(os.path.join(direct_research, file)) | ||
|
|
||
| for folder in os.listdir(start_path): | ||
| full_path = os.path.join(start_path, folder, "Research") | ||
| if os.path.isdir(full_path): | ||
| for file in os.listdir(full_path): | ||
| if file in TARGET_FILES: | ||
| self.parse_file(os.path.join(full_path, file)) | ||
|
|
||
| self.display_grid() | ||
|
|
There was a problem hiding this comment.
🛠️ Refactor suggestion
Adicione tratamento de erros ao listar diretórios.
A função load_data lida com diretórios sem nenhum tratamento de erro para operações como os.listdir(), o que pode falhar se os diretórios não existirem ou não forem acessíveis.
def load_data(self):
start_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "Resources", "Prototypes"))
direct_research = os.path.join(start_path, "Research")
if os.path.isdir(direct_research):
- for file in os.listdir(direct_research):
- if file in TARGET_FILES:
- self.parse_file(os.path.join(direct_research, file))
+ try:
+ for file in os.listdir(direct_research):
+ if file in TARGET_FILES:
+ self.parse_file(os.path.join(direct_research, file))
+ except Exception as e:
+ messagebox.showerror("Erro", f"Falha ao listar diretório {direct_research}:\n{str(e)}")
- for folder in os.listdir(start_path):
- full_path = os.path.join(start_path, folder, "Research")
- if os.path.isdir(full_path):
- for file in os.listdir(full_path):
- if file in TARGET_FILES:
- self.parse_file(os.path.join(full_path, file))
+ try:
+ for folder in os.listdir(start_path):
+ full_path = os.path.join(start_path, folder, "Research")
+ if os.path.isdir(full_path):
+ try:
+ for file in os.listdir(full_path):
+ if file in TARGET_FILES:
+ self.parse_file(os.path.join(full_path, file))
+ except Exception as e:
+ messagebox.showerror("Erro", f"Falha ao listar diretório {full_path}:\n{str(e)}")
+ except Exception as e:
+ messagebox.showerror("Erro", f"Falha ao listar diretório {start_path}:\n{str(e)}")📝 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.
| def load_data(self): | |
| start_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "Resources", "Prototypes")) | |
| direct_research = os.path.join(start_path, "Research") | |
| if os.path.isdir(direct_research): | |
| for file in os.listdir(direct_research): | |
| if file in TARGET_FILES: | |
| self.parse_file(os.path.join(direct_research, file)) | |
| for folder in os.listdir(start_path): | |
| full_path = os.path.join(start_path, folder, "Research") | |
| if os.path.isdir(full_path): | |
| for file in os.listdir(full_path): | |
| if file in TARGET_FILES: | |
| self.parse_file(os.path.join(full_path, file)) | |
| self.display_grid() | |
| def load_data(self): | |
| start_path = os.path.abspath( | |
| os.path.join(os.path.dirname(__file__), "..", "..", "Resources", "Prototypes") | |
| ) | |
| direct_research = os.path.join(start_path, "Research") | |
| if os.path.isdir(direct_research): | |
| try: | |
| for file in os.listdir(direct_research): | |
| if file in TARGET_FILES: | |
| self.parse_file(os.path.join(direct_research, file)) | |
| except Exception as e: | |
| messagebox.showerror( | |
| "Erro", | |
| f"Falha ao listar diretório {direct_research}:\n{str(e)}" | |
| ) | |
| try: | |
| for folder in os.listdir(start_path): | |
| full_path = os.path.join(start_path, folder, "Research") | |
| if os.path.isdir(full_path): | |
| try: | |
| for file in os.listdir(full_path): | |
| if file in TARGET_FILES: | |
| self.parse_file(os.path.join(full_path, file)) | |
| except Exception as e: | |
| messagebox.showerror( | |
| "Erro", | |
| f"Falha ao listar diretório {full_path}:\n{str(e)}" | |
| ) | |
| except Exception as e: | |
| messagebox.showerror( | |
| "Erro", | |
| f"Falha ao listar diretório {start_path}:\n{str(e)}" | |
| ) | |
| self.display_grid() |
| // Some visuals | ||
| public static readonly Color DefaultColor = Color.FromHex("#141F2F"); | ||
| public static readonly Color DefaultBorderColor = Color.FromHex("#4972A1"); | ||
| public static readonly Color DefaultHoveredColor = Color.FromHex("#4972A1"); | ||
|
|
||
| public Color Color = DefaultColor; | ||
| public Color BorderColor = DefaultBorderColor; | ||
| public Color HoveredColor = DefaultHoveredColor; | ||
|
|
There was a problem hiding this comment.
Nome do campo colide com o tipo Color, causando erro de compilação
Ao declarar public Color Color = …, o identificador Color passa a se referir ao campo, escondendo o tipo Color no restante da classe. Linhas 50-56 que usam Color.DarkOliveGreen, etc., deixam de compilar.
- public Color Color = DefaultColor;
- public Color BorderColor = DefaultBorderColor;
- public Color HoveredColor = DefaultHoveredColor;
+ public Color BaseColor = DefaultColor;
+ public Color BaseBorderColor = DefaultBorderColor;
+ public Color HoveredColor = DefaultHoveredColor;Altere também as demais referências (BaseColor, BaseBorderColor) dentro da classe.
| protected override void ExitedTree() | ||
| { | ||
| base.ExitedTree(); | ||
|
|
||
| Button.OnPressed -= Selected; | ||
| } | ||
|
|
There was a problem hiding this comment.
🛠️ Refactor suggestion
Cancelar registro do evento OnDrawModeChanged ao sair da árvore
ExitedTree() remove apenas o handler de OnPressed, mas deixa o de OnDrawModeChanged pendurado, gerando vazamento de memória e exceções quando o botão for recolorido depois do controle destruído.
- Button.OnPressed -= Selected;
+ Button.OnPressed -= Selected;
+ Button.OnDrawModeChanged -= UpdateColor;📝 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.
| protected override void ExitedTree() | |
| { | |
| base.ExitedTree(); | |
| Button.OnPressed -= Selected; | |
| } | |
| protected override void ExitedTree() | |
| { | |
| base.ExitedTree(); | |
| Button.OnPressed -= Selected; | |
| Button.OnDrawModeChanged -= UpdateColor; | |
| } |
| function handleFiles(e) { | ||
| const files = e.target.files; | ||
| for (let file of files) { | ||
| const reader = new FileReader(); | ||
| reader.onload = function(evt) { | ||
| const doc = jsyaml.load(evt.target.result); | ||
| if (Array.isArray(doc)) { | ||
| techs.push(...doc.filter(t => t.type === "technology" && t.position)); | ||
| draw(); | ||
| } | ||
| }; | ||
| reader.readAsText(file); | ||
| } | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Evite duplicar nós quando múltiplos arquivos YAML contêm a mesma tecnologia
Atualmente, cada importação faz techs.push(...) sem verificar duplicatas, o que provoca sobreposição de retângulos e linhas duplicadas.
- techs.push(...doc.filter(t => t.type === "technology" && t.position));
+ for (const t of doc) {
+ if (t.type !== "technology" || !t.position) continue;
+ if (!techs.some(existing => existing.id === t.id)) {
+ techs.push(t);
+ }
+ }📝 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.
| function handleFiles(e) { | |
| const files = e.target.files; | |
| for (let file of files) { | |
| const reader = new FileReader(); | |
| reader.onload = function(evt) { | |
| const doc = jsyaml.load(evt.target.result); | |
| if (Array.isArray(doc)) { | |
| techs.push(...doc.filter(t => t.type === "technology" && t.position)); | |
| draw(); | |
| } | |
| }; | |
| reader.readAsText(file); | |
| } | |
| } | |
| function handleFiles(e) { | |
| const files = e.target.files; | |
| for (let file of files) { | |
| const reader = new FileReader(); | |
| reader.onload = function(evt) { | |
| const doc = jsyaml.load(evt.target.result); | |
| if (Array.isArray(doc)) { | |
| for (const t of doc) { | |
| if (t.type !== "technology" || !t.position) continue; | |
| if (!techs.some(existing => existing.id === t.id)) { | |
| techs.push(t); | |
| } | |
| } | |
| draw(); | |
| } | |
| }; | |
| reader.readAsText(file); | |
| } | |
| } |
| ServerButton.OnPressed += _ => OnServerButtonPressed?.Invoke(); | ||
| DragContainer.OnKeyBindDown += OnKeybindDown; | ||
| DragContainer.OnKeyBindUp += OnKeybindUp; | ||
| RecenterButton.OnPressed += _ => Recenter(); |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Desregistre eventos de DragContainer no Close()
Ao fechar a window, OnKeyBindDown/Up permanecem registrados, podendo disparar em janelas futuras.
public override void Close()
{
base.Close();
+ DragContainer.OnKeyBindDown -= OnKeybindDown;
+ DragContainer.OnKeyBindUp -= OnKeybindUp;
DragContainer.RemoveAllChildren();
InfoContainer.RemoveAllChildren();
}📝 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.
| ServerButton.OnPressed += _ => OnServerButtonPressed?.Invoke(); | |
| DragContainer.OnKeyBindDown += OnKeybindDown; | |
| DragContainer.OnKeyBindUp += OnKeybindUp; | |
| RecenterButton.OnPressed += _ => Recenter(); | |
| public override void Close() | |
| { | |
| base.Close(); | |
| DragContainer.OnKeyBindDown -= OnKeybindDown; | |
| DragContainer.OnKeyBindUp -= OnKeybindUp; | |
| DragContainer.RemoveAllChildren(); | |
| InfoContainer.RemoveAllChildren(); | |
| } |
|
Mt foda o gui é bonitão |
|
This pull request has conflicts, please resolve those before we can evaluate the pull request. |

Quase tudo de Goob-Station/Goob-Station#2065
Media
Summary by CodeRabbit
Novos Recursos
Aprimoramentos
Correções e Ajustes
Documentação
Ferramentas