mirror of
https://github.com/vcmi/vcmi.git
synced 2025-08-13 19:54:17 +02:00
Merge pull request #3972 from IvanSavenko/release_151
Release 1.5.1 preparation
This commit is contained in:
31
.github/workflows/github.yml
vendored
31
.github/workflows/github.yml
vendored
@@ -384,3 +384,34 @@ jobs:
|
||||
name: ${{ env.VCMI_PACKAGE_FILE_NAME }}
|
||||
path: |
|
||||
${{ env.ANDROID_APK_PATH }}
|
||||
|
||||
|
||||
deploy-src:
|
||||
if: always() && github.ref == 'refs/heads/master'
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Build Number
|
||||
run: |
|
||||
source '${{github.workspace}}/CI/get_package_name.sh'
|
||||
echo VCMI_PACKAGE_FILE_NAME="$VCMI_PACKAGE_FILE_NAME" >> $GITHUB_ENV
|
||||
|
||||
- name: Create source code archive (including submodules)
|
||||
run: |
|
||||
git archive HEAD -o "release.tar" --worktree-attributes -v
|
||||
git submodule update --init --recursive
|
||||
git submodule --quiet foreach 'cd "$toplevel"; tar -rvf "release.tar" "$sm_path"'
|
||||
gzip release.tar
|
||||
|
||||
- name: Upload source code archive
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ env.VCMI_PACKAGE_FILE_NAME }}
|
||||
path: |
|
||||
./release.tar.gz
|
||||
|
53
ChangeLog.md
53
ChangeLog.md
@@ -2,12 +2,61 @@
|
||||
|
||||
### Stability
|
||||
* Fixed possible crash on accessing faction description
|
||||
* Fixed possible thread race on leaving to main menu
|
||||
* Fixed possible thread race on exit to main menu
|
||||
* Game will now show error message instead of silent crash on corrupted H3 data
|
||||
* Fixed possible crash on double-deletion of quest artifacts placed by RMG
|
||||
* Fixed crash on loading save made in version 1.4 with removed from map Quest Guards
|
||||
* Added workaround for crash on accessing Altar of Sacrifice on saves made in 1.4
|
||||
* Fixed possible crash on map restart request
|
||||
* Fixed crash on attempt to open scenario list with no save or map selected
|
||||
* Fixed crash on host resolving error when connecting to online lobby
|
||||
* If json file specified in mod.json is missing, vcmi will now only log an error instead of crashing
|
||||
|
||||
### Interface
|
||||
* Fixed possible freeze on attempt to move hero when hero has non-zero movement points but not enough to reach first tile in path
|
||||
* Added retaliation damage and kills preview when hovering over units that can be attacked in melee during combat
|
||||
* Clicking on combat log would now open a window with full combat log history
|
||||
* Removed message length limit in text input fields, such as global lobby chat
|
||||
* Tapping on already active text input field will display on-screen keyboard on systems with one
|
||||
* Fixed possible freeze when trying to move hero if hero has non-zero movement points but not enough to reach first tile in path
|
||||
* Fixed selection of the wrong reward in dialogs such as the level-up window when double-clicking on it
|
||||
* Fixed launch of wrong map or save when double-clicking in scenario list screen
|
||||
* Right-clicking on a hero in a tavern will now select that hero as well, in line with H3
|
||||
* Fixed slow map list parsing when hota map format is enabled
|
||||
* MacOS and iOS can now use either Ctrl or Cmd key for all keyboard shortcuts
|
||||
* Small windows no longer dim the entire screen by default
|
||||
|
||||
### Mechanics
|
||||
* Recruiting a hero will now immediately reveal the fog of war around him
|
||||
* When both a visiting hero and a garrisoned hero are in town, the garrisoned hero will visit town buildings first.
|
||||
|
||||
### Multiplayer
|
||||
* Fixed in-game chat text not being visible after switching from achannel with a long history
|
||||
* Fixed lag when switching to channel with long history
|
||||
* Game now automatically scrolls in-game chat on new messages
|
||||
* Game will now only plays chat sound for active channel and for private channels
|
||||
* Cheats are now disabled by default in multiplayer
|
||||
* Game will now show status of cheats and battle replays on map start
|
||||
* It is possible to change cheats or battle replay on game loading
|
||||
* It is now possible to join rooms hosted by different hotfix versions, e.g. 1.5.1 can join 1.5.0 games
|
||||
* Fixed game rooms remaining visible in the lobby even after they have been closed
|
||||
* Fixed possible lag when there is a player in lobby with a very slow (or dying) connection
|
||||
* Game will show correctly if player has been invited into a room
|
||||
* Fixed overflow in invite window when there are more than 8 players in the lobby
|
||||
|
||||
### Random Maps Generator
|
||||
* Generator will now prefer to place roads away from zone borders
|
||||
|
||||
### AI
|
||||
* Fixed possible crash when Nullkiller AI tries to upgrade army
|
||||
* Nullkiller AI will now recruit new heroes if he left with 0 heroes
|
||||
* AI in combat now knows when an enemy unit has used all of its retaliations.
|
||||
|
||||
### Map Editor
|
||||
* Fixed setting up hero types of heroes in Prisons placed in map editor
|
||||
* Fixed crash on setting up Seer Hut in map editor
|
||||
* Added text auto-completion hints for army widget
|
||||
* Editor will now automatically add .vmap extensions when saving map
|
||||
* Fixed text size in map validation window
|
||||
|
||||
# 1.4.5 -> 1.5.0
|
||||
|
||||
|
@@ -180,16 +180,19 @@
|
||||
"vcmi.adventureMap.revisitObject.help" : "{Revisitar objeto}\n\nSi un héroe se encuentra actualmente en un objeto del mapa, puede volver a visitar la ubicación.",
|
||||
|
||||
"vcmi.battleWindow.pressKeyToSkipIntro" : "Presiona cualquier tecla para empezar la batalla inmediatamente",
|
||||
"vcmi.battleWindow.damageEstimation.melee" : "Atacar %CREATURE (%DAÑO).",
|
||||
"vcmi.battleWindow.damageEstimation.meleeKills" : "Atacar %CREATURE (%DAÑO, %BAJAS).",
|
||||
"vcmi.battleWindow.damageEstimation.ranged" : "Disparar a %CREATURE (%DISPAROS, %DAÑO).",
|
||||
"vcmi.battleWindow.damageEstimation.rangedKills" : "Disparar a %CREATURE (%DISPAROS, %DAÑO, %BAJAS).",
|
||||
"vcmi.battleWindow.damageEstimation.melee" : "Atacar %CREATURE (%DAMAGE).",
|
||||
"vcmi.battleWindow.damageEstimation.meleeKills" : "Atacar %CREATURE (%DAMAGE, %KILLS).",
|
||||
"vcmi.battleWindow.damageEstimation.ranged" : "Disparar a %CREATURE (%SHOTS, %DAMAGE).",
|
||||
"vcmi.battleWindow.damageEstimation.rangedKills" : "Disparar a %CREATURE (%SHOTS, %DAMAGE, %KILLS).",
|
||||
"vcmi.battleWindow.damageEstimation.shots" : "%d disparos restantes",
|
||||
"vcmi.battleWindow.damageEstimation.shots.1" : "%d disparo restante",
|
||||
"vcmi.battleWindow.damageEstimation.damage" : "%d daño",
|
||||
"vcmi.battleWindow.damageEstimation.damage.1" : "%d daño",
|
||||
"vcmi.battleWindow.damageEstimation.kills" : "%d perecerán",
|
||||
"vcmi.battleWindow.damageEstimation.kills.1" : "%d perecerá",
|
||||
"vcmi.battleWindow.damageRetaliation.will" : "Contratacará ",
|
||||
"vcmi.battleWindow.damageRetaliation.may" : "Puede contratacar ",
|
||||
"vcmi.battleWindow.damageRetaliation.never" : "No contratacará.",
|
||||
"vcmi.battleWindow.killed" : "Eliminados",
|
||||
"vcmi.battleWindow.accurateShot.resultDescription.0" : "%d %s han sido eliminados por disparos certeros",
|
||||
"vcmi.battleWindow.accurateShot.resultDescription.1" : "%d %s ha sido eliminado por un disparo certero",
|
||||
@@ -352,16 +355,16 @@
|
||||
|
||||
"core.bonus.ADDITIONAL_ATTACK.name": "Doble Ataque",
|
||||
"core.bonus.ADDITIONAL_ATTACK.description": "Ataca dos veces",
|
||||
"core.bonus.ADDITIONAL_RETALIATION.name": "Contraataques adicionales",
|
||||
"core.bonus.ADDITIONAL_RETALIATION.description": "Puede contraatacar ${val} veces adicionales",
|
||||
"core.bonus.ADDITIONAL_RETALIATION.name": "Contrataques adicionales",
|
||||
"core.bonus.ADDITIONAL_RETALIATION.description": "Puede contratacar ${val} veces adicionales",
|
||||
"core.bonus.AIR_IMMUNITY.name": "Inmunidad al Aire",
|
||||
"core.bonus.AIR_IMMUNITY.description": "Inmune a todos los hechizos de la escuela de Aire",
|
||||
"core.bonus.ATTACKS_ALL_ADJACENT.name": "Ataque en todas las direcciones",
|
||||
"core.bonus.ATTACKS_ALL_ADJACENT.description": "Ataca a todos los enemigos adyacentes",
|
||||
"core.bonus.BLOCKS_RETALIATION.name": "Sin contraataque",
|
||||
"core.bonus.BLOCKS_RETALIATION.description": "El enemigo no puede contraatacar",
|
||||
"core.bonus.BLOCKS_RANGED_RETALIATION.name": "Sin contraataque a distancia",
|
||||
"core.bonus.BLOCKS_RANGED_RETALIATION.description": "El enemigo no puede contraatacar disparando",
|
||||
"core.bonus.BLOCKS_RETALIATION.name": "Evita contrataque",
|
||||
"core.bonus.BLOCKS_RETALIATION.description": "El enemigo no puede contratacar",
|
||||
"core.bonus.BLOCKS_RANGED_RETALIATION.name": "Evita contrataque a distancia",
|
||||
"core.bonus.BLOCKS_RANGED_RETALIATION.description": "El enemigo no puede contratacar disparando",
|
||||
"core.bonus.CATAPULT.name": "Catapulta",
|
||||
"core.bonus.CATAPULT.description": "Ataca a las paredes de asedio",
|
||||
"core.bonus.CHANGES_SPELL_COST_FOR_ALLY.name": "Reducir coste del conjuro (${val})",
|
||||
@@ -397,7 +400,7 @@
|
||||
"core.bonus.FIRE_SHIELD.name": "Escudo de Fuego (${val}%)",
|
||||
"core.bonus.FIRE_SHIELD.description": "Refleja una parte del daño cuerpo a cuerpo",
|
||||
"core.bonus.FIRST_STRIKE.name": "Primer Ataque",
|
||||
"core.bonus.FIRST_STRIKE.description": "Esta criatura ataca primero en lugar de contraatacar",
|
||||
"core.bonus.FIRST_STRIKE.description": "Esta criatura ataca primero en lugar de contratacar",
|
||||
"core.bonus.FEAR.name": "Miedo",
|
||||
"core.bonus.FEAR.description": "Causa miedo a un grupo enemigo",
|
||||
"core.bonus.FEARLESS.name": "Inmune al miedo",
|
||||
@@ -450,8 +453,8 @@
|
||||
"core.bonus.NON_LIVING.description": "Inmunidad a muchos efectos",
|
||||
"core.bonus.RANDOM_SPELLCASTER.name": "Lanzador de hechizos aleatorio",
|
||||
"core.bonus.RANDOM_SPELLCASTER.description": "Puede lanzar hechizos aleatorios",
|
||||
"core.bonus.RANGED_RETALIATION.name": "Contraataque a distancia",
|
||||
"core.bonus.RANGED_RETALIATION.description": "Puede realizar un contraataque a distancia",
|
||||
"core.bonus.RANGED_RETALIATION.name": "Contrataque a distancia",
|
||||
"core.bonus.RANGED_RETALIATION.description": "Puede realizar un contrataque a distancia",
|
||||
"core.bonus.RECEPTIVE.name": "Receptivo",
|
||||
"core.bonus.RECEPTIVE.description": "No tiene inmunidad a hechizos amistosos",
|
||||
"core.bonus.REBIRTH.name": "Renacimiento (${val}%)",
|
||||
@@ -492,8 +495,8 @@
|
||||
"core.bonus.TRANSMUTATION.description": "${val}% de probabilidad de transformar la unidad atacada en otro tipo",
|
||||
"core.bonus.UNDEAD.name": "No muerto",
|
||||
"core.bonus.UNDEAD.description": "La criatura es un no muerto",
|
||||
"core.bonus.UNLIMITED_RETALIATIONS.name": "Contraataques ilimitados",
|
||||
"core.bonus.UNLIMITED_RETALIATIONS.description": "Puede realizar un número ilimitado de contraataques",
|
||||
"core.bonus.UNLIMITED_RETALIATIONS.name": "Contrataques ilimitados",
|
||||
"core.bonus.UNLIMITED_RETALIATIONS.description": "Puede realizar un número ilimitado de contrataques",
|
||||
"core.bonus.WATER_IMMUNITY.name": "Inmunidad al agua",
|
||||
"core.bonus.WATER_IMMUNITY.description": "Inmune a todos los hechizos de la escuela del agua",
|
||||
"core.bonus.WIDE_BREATH.name": "Aliento amplio",
|
||||
|
@@ -10,7 +10,7 @@ android {
|
||||
applicationId "is.xyz.vcmi"
|
||||
minSdk 19
|
||||
targetSdk 33
|
||||
versionCode 1511
|
||||
versionCode 1513
|
||||
versionName "1.5.1"
|
||||
setProperty("archivesBaseName", "vcmi")
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
[](https://github.com/vcmi/vcmi/actions/workflows/github.yml?query=branch%3Adevelop+event%3Apush)
|
||||
[](https://github.com/vcmi/vcmi/releases/tag/1.5.0)
|
||||
[](https://github.com/vcmi/vcmi/releases/tag/1.5.1)
|
||||
[](https://github.com/vcmi/vcmi/releases)
|
||||
|
||||
# VCMI Project
|
||||
|
@@ -392,9 +392,15 @@ void CGameStateCampaign::transferMissingArtifacts(const CampaignTravel & travelO
|
||||
|
||||
auto * donorHero = campaignHeroReplacement.hero;
|
||||
|
||||
if (!donorHero)
|
||||
throw std::runtime_error("Failed to find hero to take artifacts from! Scenario: " + gameState->map->name.toString());
|
||||
|
||||
for (auto const & artLocation : campaignHeroReplacement.transferrableArtifacts)
|
||||
{
|
||||
auto * artifact = donorHero->getArt(artLocation);
|
||||
if (!donorHero)
|
||||
throw std::runtime_error("Failed to find artifacts to transfer to travelling hero! Scenario: " + gameState->map->name.toString());
|
||||
|
||||
artifact->removeFrom(*donorHero, artLocation);
|
||||
|
||||
if (receiver)
|
||||
|
@@ -40,26 +40,26 @@ void GlobalLobbyProcessor::onDisconnected(const std::shared_ptr<INetworkConnecti
|
||||
}
|
||||
else
|
||||
{
|
||||
if (owner.getState() == EServerState::LOBBY)
|
||||
for (auto const & proxy : proxyConnections)
|
||||
{
|
||||
for (auto const & proxy : proxyConnections)
|
||||
if (proxy.second != connection)
|
||||
continue;
|
||||
|
||||
if (owner.getState() == EServerState::LOBBY)
|
||||
{
|
||||
if (proxy.second == connection)
|
||||
{
|
||||
JsonNode message;
|
||||
message["type"].String() = "leaveGameRoom";
|
||||
message["accountID"].String() = proxy.first;
|
||||
JsonNode message;
|
||||
message["type"].String() = "leaveGameRoom";
|
||||
message["accountID"].String() = proxy.first;
|
||||
|
||||
sendMessage(controlConnection, message);
|
||||
|
||||
proxyConnections.erase(proxy.first);
|
||||
break;
|
||||
}
|
||||
sendMessage(controlConnection, message);
|
||||
}
|
||||
}
|
||||
|
||||
// player disconnected
|
||||
owner.onDisconnected(connection, errorMessage);
|
||||
proxyConnections.erase(proxy.first);
|
||||
|
||||
// player disconnected
|
||||
owner.onDisconnected(connection, errorMessage);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user