From 0e4be8c7768fb3fe1a7baaa0fe0a30895b65d9b3 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Wed, 19 Jun 2024 18:25:07 +0000 Subject: [PATCH 1/9] Fix crash on sieging Citadel or Castle --- AI/BattleAI/BattleExchangeVariant.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/AI/BattleAI/BattleExchangeVariant.cpp b/AI/BattleAI/BattleExchangeVariant.cpp index 29ed104ea..1f83b58e8 100644 --- a/AI/BattleAI/BattleExchangeVariant.cpp +++ b/AI/BattleAI/BattleExchangeVariant.cpp @@ -621,6 +621,9 @@ BattleScore BattleExchangeEvaluator::calculateExchange( if(!exchangeBattle->getForUpdate(u->unitId())->alive()) return false; + if (!u->getPosition().isValid()) + return false; // e.g. tower shooters + return vstd::contains_if(reachabilityMap.at(u->getPosition()), [&attacker](const battle::Unit * other) -> bool { return attacker->unitId() == other->unitId(); From 2b7131cfea335caf292a38195020f558b6cc1fd6 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Wed, 19 Jun 2024 18:25:54 +0000 Subject: [PATCH 2/9] Show error message if vcmi unable to access data directory instead of silent crash --- client/CMT.cpp | 9 ++++++++- lib/filesystem/CFileInputStream.cpp | 4 +++- lib/filesystem/CFilesystemLoader.cpp | 10 +++++++++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/client/CMT.cpp b/client/CMT.cpp index fc6885136..c54d27e2d 100644 --- a/client/CMT.cpp +++ b/client/CMT.cpp @@ -208,7 +208,14 @@ int main(int argc, char * argv[]) logGlobal->info("The log file will be saved to %s", logPath); // Init filesystem and settings - preinitDLL(::console, false); + try + { + preinitDLL(::console, false); + } + catch (const DataLoadingException & e) + { + handleFatalError(e.what(), true); + } Settings session = settings.write["session"]; auto setSettingBool = [&](std::string key, std::string arg) { diff --git a/lib/filesystem/CFileInputStream.cpp b/lib/filesystem/CFileInputStream.cpp index 8f10d0d36..f777669de 100644 --- a/lib/filesystem/CFileInputStream.cpp +++ b/lib/filesystem/CFileInputStream.cpp @@ -10,6 +10,8 @@ #include "StdInc.h" #include "CFileInputStream.h" +#include "../ExceptionsCommon.h" + VCMI_LIB_NAMESPACE_BEGIN CFileInputStream::CFileInputStream(const boost::filesystem::path & file, si64 start, si64 size) @@ -18,7 +20,7 @@ CFileInputStream::CFileInputStream(const boost::filesystem::path & file, si64 st fileStream{file.c_str(), std::ios::in | std::ios::binary} { if (fileStream.fail()) - throw std::runtime_error("File " + file.string() + " isn't available."); + throw DataLoadingException("Failed to open file '" + file.string() + "'. Reason: " + strerror(errno) ); if (dataSize == 0) { diff --git a/lib/filesystem/CFilesystemLoader.cpp b/lib/filesystem/CFilesystemLoader.cpp index 09073660c..8086989e3 100644 --- a/lib/filesystem/CFilesystemLoader.cpp +++ b/lib/filesystem/CFilesystemLoader.cpp @@ -12,14 +12,22 @@ #include "CFileInputStream.h" +#include "../ExceptionsCommon.h" + VCMI_LIB_NAMESPACE_BEGIN CFilesystemLoader::CFilesystemLoader(std::string _mountPoint, boost::filesystem::path baseDirectory, size_t depth, bool initial): baseDirectory(std::move(baseDirectory)), mountPoint(std::move(_mountPoint)), - fileList(listFiles(mountPoint, depth, initial)), recursiveDepth(depth) { + try { + fileList = listFiles(mountPoint, depth, initial); + } + catch (const boost::filesystem::filesystem_error & e) { + throw DataLoadingException("Failed to load content of '" + baseDirectory.string() + "'. Reason: " + e.what()); + } + logGlobal->trace("File system loaded, %d files found", fileList.size()); } From 4e9feca8d49db9c6496da623d41c6ca07d7d341d Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Wed, 19 Jun 2024 18:26:25 +0000 Subject: [PATCH 3/9] Validate mod.json as json5 instead of strict json since Android launcher no longer exists --- lib/modding/CModHandler.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/modding/CModHandler.cpp b/lib/modding/CModHandler.cpp index 173fd921a..1cf7b7ba9 100644 --- a/lib/modding/CModHandler.cpp +++ b/lib/modding/CModHandler.cpp @@ -226,10 +226,7 @@ void CModHandler::loadOneMod(std::string modName, const std::string & parent, co if(CResourceHandler::get("initial")->existsResource(CModInfo::getModFile(modFullName))) { - JsonParsingSettings settings; - settings.mode = JsonParsingSettings::JsonFormatMode::JSON; // TODO: remove once Android launcher with its strict parser is gone - - CModInfo mod(modFullName, modSettings[modName], JsonNode(CModInfo::getModFile(modFullName), settings)); + CModInfo mod(modFullName, modSettings[modName], JsonNode(CModInfo::getModFile(modFullName))); if (!parent.empty()) // this is submod, add parent to dependencies mod.dependencies.insert(parent); From cfcecbf630e7260e0db06772e7a4a2b245857631 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Wed, 19 Jun 2024 18:26:52 +0000 Subject: [PATCH 4/9] Fix documentation to match actual behavior --- docs/modders/Bonus/Bonus_Types.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/modders/Bonus/Bonus_Types.md b/docs/modders/Bonus/Bonus_Types.md index 8232599b5..b94c81bfc 100644 --- a/docs/modders/Bonus/Bonus_Types.md +++ b/docs/modders/Bonus/Bonus_Types.md @@ -349,10 +349,10 @@ Negates all natural immunities for affected stacks. (Orb of Vulnerability) ### OPENING_BATTLE_SPELL -In battle, army affected by this bonus will cast spell at the very start of the battle +In battle, army affected by this bonus will cast spell at the very start of the battle. Spell is always cast at expert level. - subtype: spell identifer -- val: spell mastery level +- val: duration of the spell, in rounds ### FREE_SHIP_BOARDING From 8c63a3e4de4a8ba30a9d1d2d694761ef95c4a216 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Wed, 19 Jun 2024 18:27:26 +0000 Subject: [PATCH 5/9] Running out of timer during battle will no longer force retreat --- server/TurnTimerHandler.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/server/TurnTimerHandler.cpp b/server/TurnTimerHandler.cpp index c6d46b142..b8dd196ed 100644 --- a/server/TurnTimerHandler.cpp +++ b/server/TurnTimerHandler.cpp @@ -313,10 +313,8 @@ void TurnTimerHandler::onBattleLoop(const BattleID & battleID, int waitTime) } else { - BattleAction retreat; - retreat.side = side; - retreat.actionType = EActionType::RETREAT; //harsh punishment - gameHandler.battles->makePlayerBattleAction(battleID, player, retreat); + // battle vs neutrals - no-op, let battle run till the end + // once battle is over player turn will be over due to running out of timer on adventure map } } } From edf10d81749aa9cac077036ee9be70ab5f4f8b62 Mon Sep 17 00:00:00 2001 From: altiereslima Date: Wed, 19 Jun 2024 15:28:46 -0300 Subject: [PATCH 6/9] Update Portuguese Translation (#4121) * Update Portuguese Translation --- Mods/vcmi/config/vcmi/portuguese.json | 58 +++++++++--------- launcher/translation/portuguese.ts | 84 ++++++++++++++------------- mapeditor/translation/portuguese.ts | 30 +++++----- 3 files changed, 87 insertions(+), 85 deletions(-) diff --git a/Mods/vcmi/config/vcmi/portuguese.json b/Mods/vcmi/config/vcmi/portuguese.json index 8fa1d5286..4405870fc 100644 --- a/Mods/vcmi/config/vcmi/portuguese.json +++ b/Mods/vcmi/config/vcmi/portuguese.json @@ -55,7 +55,7 @@ "vcmi.radialWheel.moveDown" : "Mover para baixo", "vcmi.radialWheel.moveBottom" : "Mover para o fundo", - "vcmi.spellBook.search" : "procurar...", + "vcmi.spellBook.search" : "Procurar...", "vcmi.mainMenu.serverConnecting" : "Conectando...", "vcmi.mainMenu.serverAddressEnter" : "Insira o endereço:", @@ -139,9 +139,9 @@ "vcmi.server.errors.existingProcess" : "Outro processo do servidor VCMI está em execução. Por favor, termine-o antes de iniciar um novo jogo.", "vcmi.server.errors.modsToEnable" : "{Os seguintes mods são necessários}", "vcmi.server.errors.modsToDisable" : "{Os seguintes mods devem ser desativados}", - "vcmi.server.errors.modNoDependency" : "Falha ao carregar mod {'%s'}!\n Ele depende do mod {'%s'} que não está ativo!\n", - "vcmi.server.errors.modConflict" : "Falha ao carregar mod {'%s'}!\n Conflita com o mod ativo {'%s'}!\n", - "vcmi.server.errors.unknownEntity" : "Falha ao carregar salvamento! Entidade desconhecida '%s' encontrada no jogo salvo! O salvamento pode não ser compatível com a versão atualmente instalada dos mods!", + "vcmi.server.errors.modNoDependency" : "Falha ao carregar o mod {'%s'}!\n Ele depende do mod {'%s'} que não está ativo!\n", + "vcmi.server.errors.modConflict" : "Falha ao carregar o mod {'%s'}!\n Conflita com o mod ativo {'%s'}!\n", + "vcmi.server.errors.unknownEntity" : "Falha ao carregar o salvamento! Entidade desconhecida '%s' encontrada no jogo salvo! O salvamento pode não ser compatível com a versão atualmente instalada dos mods!", "vcmi.dimensionDoor.seaToLandError" : "Não é possível teleportar do mar para a terra ou vice-versa com uma Porta Dimensional.", @@ -189,8 +189,8 @@ "vcmi.adventureOptions.infoBarPick.help" : "{Mostra as Mensagens no Painel de Informações}\n\nSempre que possível, as mensagens do jogo provenientes de objetos no mapa serão mostradas no painel de informações, em vez de aparecerem em uma janela separada.", "vcmi.adventureOptions.numericQuantities.hover" : "Quantidades Numéricas de Criaturas", "vcmi.adventureOptions.numericQuantities.help" : "{Quantidades Numéricas de Criaturas}\n\nMostra as quantidades aproximadas de criaturas inimigas no formato numérico A-B.", - "vcmi.adventureOptions.forceMovementInfo.hover" : "Mostrar Sempre o Custo de Movimento", - "vcmi.adventureOptions.forceMovementInfo.help" : "{Mostrar Sempre o Custo de Movimento}\n\nSempre mostra os dados de pontos de movimento na barra de status (em vez de apenas visualizá-los enquanto você mantém pressionada a tecla ALT).", + "vcmi.adventureOptions.forceMovementInfo.hover" : "Sempre Mostrar o Custo de Movimento", + "vcmi.adventureOptions.forceMovementInfo.help" : "{Sempre Mostrar o Custo de Movimento}\n\nSempre mostra os dados de pontos de movimento na barra de status (em vez de apenas visualizá-los enquanto você mantém pressionada a tecla ALT).", "vcmi.adventureOptions.showGrid.hover" : "Mostrar Grade", "vcmi.adventureOptions.showGrid.help" : "{Mostrar Grade}\n\nMostra a sobreposição da grade, destacando as fronteiras entre as telhas do mapa de aventura.", "vcmi.adventureOptions.borderScroll.hover" : "Rolagem de Borda", @@ -235,8 +235,8 @@ "vcmi.battleOptions.showStickyHeroInfoWindows.help": "{Mostra as Janelas de Estatísticas de Heróis}\n\nAlterna permanentemente as janelas de estatísticas dos heróis que mostram estatísticas primárias e pontos de feitiço.", "vcmi.battleOptions.skipBattleIntroMusic.hover": "Pular Música de Introdução", "vcmi.battleOptions.skipBattleIntroMusic.help": "{Pula a Música de Introdução}\n\nPermite ações durante a música de introdução que toca no início de cada batalha.", - "vcmi.battleOptions.endWithAutocombat.hover": "Terminar a Batalha", - "vcmi.battleOptions.endWithAutocombat.help": "{Termina a Batalha}\n\nO Combate Automático reproduz a batalha até o final instantâneo.", + "vcmi.battleOptions.endWithAutocombat.hover": "Terminar a batalha", + "vcmi.battleOptions.endWithAutocombat.help": "{Termina a batalha}\n\nO Combate Automático reproduz a batalha até o final instantâneo.", "vcmi.adventureMap.revisitObject.hover" : "Revisitar Objeto", "vcmi.adventureMap.revisitObject.help" : "{Revisitar Objeto}\n\nSe um herói estiver atualmente em um Objeto do Mapa, ele pode revisitar o local.", @@ -277,9 +277,9 @@ "vcmi.tutorialWindow.decription.AbortSpell" : "Toque e mantenha pressionado para cancelar um feitiço.", "vcmi.otherOptions.availableCreaturesAsDwellingLabel.hover" : "Mostrar Criaturas Disponíveis", - "vcmi.otherOptions.availableCreaturesAsDwellingLabel.help" : "{Mostrar Criaturas Disponíveis}\n\nMostra o número de criaturas disponíveis para compra em vez de seu crescimento no resumo da cidade (canto inferior esquerdo da tela da cidade).", - "vcmi.otherOptions.creatureGrowthAsDwellingLabel.hover" : "Mostrar Crescimento Semanal de Criaturas", - "vcmi.otherOptions.creatureGrowthAsDwellingLabel.help" : "{Mostrar Crescimento Semanal de Criaturas}\n\nMostra o crescimento semanal das criaturas em vez da quantidade disponível no resumo da cidade (canto inferior esquerdo da tela da cidade).", + "vcmi.otherOptions.availableCreaturesAsDwellingLabel.help" : "{Mostrar Criaturas Disponíveis}\n\nMostra o número de criaturas disponíveis para compra em vez de sua produção no resumo da cidade (canto inferior esquerdo da tela da cidade).", + "vcmi.otherOptions.creatureGrowthAsDwellingLabel.hover" : "Mostrar Produção Semanal de Criaturas", + "vcmi.otherOptions.creatureGrowthAsDwellingLabel.help" : "{Mostrar Produção Semanal de Criaturas}\n\nMostra a produção semanal das criaturas em vez da quantidade disponível no resumo da cidade (canto inferior esquerdo da tela da cidade).", "vcmi.otherOptions.compactTownCreatureInfo.hover" : "Informações Compactas de Criaturas", "vcmi.otherOptions.compactTownCreatureInfo.help" : "{Informações Compactas de Criaturas}\n\nMostra informações menores para criaturas da cidade no resumo da cidade (canto inferior esquerdo da tela da cidade).", @@ -352,18 +352,18 @@ "vcmi.optionsTab.turnTime.select" : "Selecionar cronômetro do turno", "vcmi.optionsTab.turnTime.unlimited" : "Tempo de turno ilimitado", - "vcmi.optionsTab.turnTime.classic.1" : "Cronômetro clássico: 1 minuto", - "vcmi.optionsTab.turnTime.classic.2" : "Cronômetro clássico: 2 minutos", - "vcmi.optionsTab.turnTime.classic.5" : "Cronômetro clássico: 5 minutos", - "vcmi.optionsTab.turnTime.classic.10" : "Cronômetro clássico: 10 minutos", - "vcmi.optionsTab.turnTime.classic.20" : "Cronômetro clássico: 20 minutos", - "vcmi.optionsTab.turnTime.classic.30" : "Cronômetro clássico: 30 minutos", - "vcmi.optionsTab.turnTime.chess.20" : "Xadrez: 20:00 + 10:00 + 02:00 + 00:00", - "vcmi.optionsTab.turnTime.chess.16" : "Xadrez: 16:00 + 08:00 + 01:30 + 00:00", - "vcmi.optionsTab.turnTime.chess.8" : "Xadrez: 08:00 + 04:00 + 01:00 + 00:00", - "vcmi.optionsTab.turnTime.chess.4" : "Xadrez: 04:00 + 02:00 + 00:30 + 00:00", - "vcmi.optionsTab.turnTime.chess.2" : "Xadrez: 02:00 + 01:00 + 00:15 + 00:00", - "vcmi.optionsTab.turnTime.chess.1" : "Xadrez: 01:00 + 01:00 + 00:00 + 00:00", + "vcmi.optionsTab.turnTime.classic.1" : "Cronômetro clássico 1 minuto", + "vcmi.optionsTab.turnTime.classic.2" : "Cronômetro clássico 2 minutos", + "vcmi.optionsTab.turnTime.classic.5" : "Cronômetro clássico 5 minutos", + "vcmi.optionsTab.turnTime.classic.10" : "Cronômetro clássico 10 minutos", + "vcmi.optionsTab.turnTime.classic.20" : "Cronômetro clássico 20 minutos", + "vcmi.optionsTab.turnTime.classic.30" : "Cronômetro clássico 30 minutos", + "vcmi.optionsTab.turnTime.chess.20" : "Xadrez 20:00 + 10:00 + 02:00 + 00:00", + "vcmi.optionsTab.turnTime.chess.16" : "Xadrez 16:00 + 08:00 + 01:30 + 00:00", + "vcmi.optionsTab.turnTime.chess.8" : "Xadrez 08:00 + 04:00 + 01:00 + 00:00", + "vcmi.optionsTab.turnTime.chess.4" : "Xadrez 04:00 + 02:00 + 00:30 + 00:00", + "vcmi.optionsTab.turnTime.chess.2" : "Xadrez 02:00 + 01:00 + 00:15 + 00:00", + "vcmi.optionsTab.turnTime.chess.1" : "Xadrez 01:00 + 01:00 + 00:00 + 00:00", "vcmi.optionsTab.simturns.select" : "Selecionar turnos simultâneos", "vcmi.optionsTab.simturns.none" : "Sem turnos simultâneos", @@ -490,13 +490,13 @@ "core.bonus.AIR_IMMUNITY.description" : "Imune a todos os feitiços da escola de magia do Ar", "core.bonus.ATTACKS_ALL_ADJACENT.name" : "Ataque em Todas as Direções", "core.bonus.ATTACKS_ALL_ADJACENT.description" : "Ataca todos os inimigos adjacentes", - "core.bonus.BLOCKS_RETALIATION.name" : "Sem Contra-ataques", + "core.bonus.BLOCKS_RETALIATION.name" : "Evita Contra-ataques", "core.bonus.BLOCKS_RETALIATION.description" : "O inimigo não pode contra-atacar", - "core.bonus.BLOCKS_RANGED_RETALIATION.name" : "Sem Contra-ataques à Distância", + "core.bonus.BLOCKS_RANGED_RETALIATION.name" : "Evita Contra-ataques à Distância", "core.bonus.BLOCKS_RANGED_RETALIATION.description" : "O inimigo não pode contra-atacar usando um ataque à distância", "core.bonus.CATAPULT.name" : "Catapulta", "core.bonus.CATAPULT.description" : "Ataca as muralhas de cerco", - "core.bonus.CHANGES_SPELL_COST_FOR_ALLY.name" : "Reduz Custo de Conjuração (${val})", + "core.bonus.CHANGES_SPELL_COST_FOR_ALLY.name" : "Custo de Conjuração (${val})", "core.bonus.CHANGES_SPELL_COST_FOR_ALLY.description" : "Reduz o custo de conjuração de feitiços para o herói em ${val}", "core.bonus.CHANGES_SPELL_COST_FOR_ENEMY.name" : "Absorvedor Mágico (${val})", "core.bonus.CHANGES_SPELL_COST_FOR_ENEMY.description" : "Aumenta o custo de conjuração dos feitiços inimigos em ${val}", @@ -507,7 +507,7 @@ "core.bonus.DEATH_STARE.name" : "Olhar da Morte (${val}%)", "core.bonus.DEATH_STARE.description" : "Tem ${val}% de chance de matar uma única criatura", "core.bonus.DEFENSIVE_STANCE.name" : "Bônus de Defesa", - "core.bonus.DEFENSIVE_STANCE.description" : "+${val} de defesa ao se defender", + "core.bonus.DEFENSIVE_STANCE.description" : "+${val} de Defesa ao se defender", "core.bonus.DESTRUCTION.name" : "Destruição", "core.bonus.DESTRUCTION.description" : "Tem ${val}% de chance de matar unidades extras após o ataque", "core.bonus.DOUBLE_DAMAGE_CHANCE.name" : "Golpe Mortal", @@ -521,7 +521,7 @@ "core.bonus.ENCHANTED.name" : "Encantado", "core.bonus.ENCHANTED.description" : "Afetado por ${subtype.spell} permanente", "core.bonus.ENEMY_ATTACK_REDUCTION.name" : "Ignorar Ataque (${val}%)", - "core.bonus.ENEMY_ATTACK_REDUCTION.description" : "Ao ser atacado, ${val}% do ataque do atacante é ignorado", + "core.bonus.ENEMY_ATTACK_REDUCTION.description" : "Ao ser atacado, ${val}% do ataque do agressor é ignorado", "core.bonus.ENEMY_DEFENCE_REDUCTION.name" : "Ignorar Defesa (${val}%)", "core.bonus.ENEMY_DEFENCE_REDUCTION.description" : "Ao atacar, ${val}% da defesa do defensor é ignorada", "core.bonus.FIRE_IMMUNITY.name" : "Imunidade ao Fogo", @@ -545,7 +545,7 @@ "core.bonus.GENERAL_DAMAGE_REDUCTION.name" : "Redução de Dano (${val}%)", "core.bonus.GENERAL_DAMAGE_REDUCTION.description" : "Reduz o dano físico de ataques à distância ou corpo a corpo", "core.bonus.HATE.name" : "Odeia ${subtype.creature}", - "core.bonus.HATE.description" : "Causa ${val}% a mais de dano a ${subtype.creature}", + "core.bonus.HATE.description" : "${val}% a mais de dano a ${subtype.creature}", "core.bonus.HEALER.name" : "Curandeiro", "core.bonus.HEALER.description" : "Cura unidades aliadas", "core.bonus.HP_REGENERATION.name" : "Regeneração", diff --git a/launcher/translation/portuguese.ts b/launcher/translation/portuguese.ts index 14702f883..a30e0b25e 100644 --- a/launcher/translation/portuguese.ts +++ b/launcher/translation/portuguese.ts @@ -79,7 +79,7 @@ Configuration files directory - + Diretório de arquivos de configuração @@ -294,7 +294,7 @@ Reload repositories - + Recarregar repositórios @@ -574,7 +574,7 @@ Instalar o download realizado com sucesso? Required mod %1 is not enabled - O mod necessário %1 não está habilitado + O mod necessário %1 não está ativado @@ -664,132 +664,132 @@ Instalar o download realizado com sucesso? Adventure Map Allies - Aliados do mapa de aventura + Aliados do Mapa de Aventura Online Lobby port - + Porta da Sala de Espera On-line Autocombat AI in battles - + IA de combate automático nas batalhas Sticks Sensitivity - + Sensibilidade dos Analógicos Haptic Feedback - + Resposta Tátil Software Cursor - + Cursor por Software Online Lobby address - + Endereço da Sala de Espera On-line Upscaling Filter - + Filtro de Aumento de Escala Use Relative Pointer Mode - + Usar Modo de Ponteiro Relativo Nearest - + Mais Próximo Linear - + Linear Best (Linear) - + Melhor (Linear) Input - Touchscreen - + Entrada - Tela de Toque Adventure Map Enemies - Inimigos do mapa de aventura + Inimigos do Mapa de Aventura Network - + Linear Audio - + Áudio Relative Pointer Speed - + Velocidade do Ponteiro Relativo Music Volume - + Volume da Música Ignore SSL errors - + Ignorar erros SSL Input - Mouse - + Entrada - Mouse Long Touch Duration - + Duração do Toque Longo % - + % Controller Click Tolerance - + Tolerância de Clique do Controle Touch Tap Tolerance - + Tolerância de Toque Tátil Input - Controller - + Entrada - Controle Sound Volume - + Volume do Som @@ -818,7 +818,7 @@ Instalar o download realizado com sucesso? Framerate Limit - Limite de taxa de quadros + Limite de Taxa de Quadros @@ -828,12 +828,12 @@ Instalar o download realizado com sucesso? Mouse Click Tolerance - + Tolerância de Clique do Mouse Sticks Acceleration - + Aceleração dos Analógicos @@ -1064,12 +1064,12 @@ Heroes® of Might and Magic® III HD atualmente não é suportado! Use offline installer from gog.com - + Usar instalador offline do gog.com You can manually copy directories Maps, Data and Mp3 from the original game directory to VCMI data directory that you can see on top of this page - + Você pode copiar manualmente os diretórios Mapas, Dados e Mp3 do diretório do jogo original para o diretório de dados do VCMI que você pode ver no topo desta página @@ -1106,23 +1106,24 @@ Heroes® of Might and Magic® III HD atualmente não é suportado! Installing... %p% - + Instalando... %p% If you already have Heroes III files on your device, you can select this directory and VCMI will copy the existing data automatically. - + Se você já tem arquivos do Heroes III no seu dispositivo, você pode selecionar este diretório e o VCMI irá copiar os dados existentes automaticamente. Copy existing files - + Copiar arquivos existentes If you own Heroes III on gog.com you can download backup offline installer from gog.com, and VCMI will import Heroes III data using offline installer. Offline installer consists of two parts, .exe and .bin. Make sure you download both of them. - + Se você possui o Heroes III no gog.com, você pode baixar o instalador offline de backup do gog.com, e o VCMI irá importar os dados do Heroes III usando o instalador offline. +O instalador offline consiste em duas partes, .exe e .bin. Certifique-se de baixar ambas. @@ -1173,7 +1174,7 @@ Offline installer consists of two parts, .exe and .bin. Make sure you download b Manual Installation - + Instalação Manual @@ -1487,13 +1488,14 @@ Por favor, selecione o diretório com Heroes III: Complete Edition ou Heroes III Error starting executable - + Erro ao iniciar o executável Failed to start %1 Reason: %2 - + Falha ao iniciar %1 +Motivo: %2 diff --git a/mapeditor/translation/portuguese.ts b/mapeditor/translation/portuguese.ts index d713fc3c0..15353214c 100644 --- a/mapeditor/translation/portuguese.ts +++ b/mapeditor/translation/portuguese.ts @@ -129,37 +129,37 @@ Spells - Feitiços + Feitiços Customize spells - + Personalizar feitiços Level 1 - + Nível 1 Level 2 - + Nível 2 Level 3 - + Nível 3 Level 4 - + Nível 4 Level 5 - + Nível 5 @@ -1555,12 +1555,12 @@ Spell scroll %1 is prohibited by map settings - O pergaminho de feitiço %1 é proibido pelas configurações do mapa + O pergaminho mágico %1 é proibido pelas configurações do mapa Spell scroll %1 doesn't have instance assigned and must be removed - O pergaminho de feitiço %1 não tem instância atribuída e deve ser removido + O pergaminho mágico %1 não tem instância atribuída e deve ser removido @@ -1738,32 +1738,32 @@ S (36x36) - + S (36x36) M (72x72) - + M (72x72) L (108x108) - + L (108x108) H (180x180) - + H (180x180) XH (216x216) - + XH (216x216) G (252x252) - + G (252x252) From a9dae99a75ac33dbe07af2cd4fa25e019d29fb60 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Wed, 19 Jun 2024 20:01:31 +0000 Subject: [PATCH 7/9] Final changelog update --- ChangeLog.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ChangeLog.md b/ChangeLog.md index 6087d8940..e604c3be4 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -9,6 +9,8 @@ * Game should now generate crash dump on uncaught c++ exception throw * Fixed crash when player finishes game with negative score * Fixed crash when opening tavern window in some localisations +* Fixed crash on loading previously generated random map when mods that add object with same name are used +* Game will now display an error message instead of silent crash if game data directory is not accessible ### Mechanics * Transport Artefact victory condition will no longer trigger if another player has completed it. @@ -18,6 +20,7 @@ * Fixed hero not being able to learn spells from a mod in some cases, even if they are available from the town's mage guild. * The game will now actually take resources from seers' huts with the Gather Resources mission instead of awarding them. * Heroes with double spell points will no longer trigger the Mana Vortex. +* If turn timer runs out during pve battle game will end player turn after a battle instead of forcing retreat ### Interface * Fixed reversed button functions in Exchange Window @@ -58,6 +61,7 @@ * Fixed potential crash when Nullkiller AI has access to Town Portal spell * Fixed potential crash when Battle AI selects a spell to cast from a hero with summon spells. * Several fixes to Nullkiller AI exploration logic +* Fixed bug leading to Battle AI doing nothing if targeted unit is unreachable ### Random Maps Generator * Fixed crash when player selects a random number of players and selects a different colour to play, resulting in a non-continuous list of players. From f0ad2e042e69ede725a3e8f09bc1d5f52c5aba9f Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Wed, 19 Jun 2024 20:17:05 +0000 Subject: [PATCH 8/9] Add download counter for 1.5.3 --- docs/Readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/Readme.md b/docs/Readme.md index 0f8d5fcbc..e5f16ac7f 100644 --- a/docs/Readme.md +++ b/docs/Readme.md @@ -2,6 +2,7 @@ [![Github Downloads](https://img.shields.io/github/downloads/vcmi/vcmi/1.5.0/total)](https://github.com/vcmi/vcmi/releases/tag/1.5.0) [![Github Downloads](https://img.shields.io/github/downloads/vcmi/vcmi/1.5.1/total)](https://github.com/vcmi/vcmi/releases/tag/1.5.1) [![Github Downloads](https://img.shields.io/github/downloads/vcmi/vcmi/1.5.2/total)](https://github.com/vcmi/vcmi/releases/tag/1.5.2) +[![Github Downloads](https://img.shields.io/github/downloads/vcmi/vcmi/1.5.3/total)](https://github.com/vcmi/vcmi/releases/tag/1.5.3) [![Github Downloads](https://img.shields.io/github/downloads/vcmi/vcmi/total)](https://github.com/vcmi/vcmi/releases) # VCMI Project From 0d3408ee68eea6a4c7f83d5a6151b14981572dd6 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Thu, 20 Jun 2024 10:08:49 +0000 Subject: [PATCH 9/9] Add better runtime error on invalid building ID --- client/windows/CCastleInterface.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/windows/CCastleInterface.cpp b/client/windows/CCastleInterface.cpp index eb90d6a0e..588effed9 100644 --- a/client/windows/CCastleInterface.cpp +++ b/client/windows/CCastleInterface.cpp @@ -1540,6 +1540,9 @@ CHallInterface::CHallInterface(const CGTownInstance * Town): const CBuilding * building = nullptr; for(auto & buildingID : boxList[row][col])//we are looking for the first not built structure { + if (town->town->buildings.count(buildingID) == 0) + throw std::runtime_error("Town " + Town->town->faction->getJsonKey() + " has no building with ID " + std::to_string(buildingID.getNum())); + const CBuilding * current = town->town->buildings.at(buildingID); if(vstd::contains(town->builtBuildings, buildingID)) {