mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-21 17:17:06 +02:00
Merge branch 'master' into 'develop'
This commit is contained in:
commit
3d39963a1c
5
.github/workflows/github.yml
vendored
5
.github/workflows/github.yml
vendored
@ -183,6 +183,11 @@ jobs:
|
|||||||
distribution: 'temurin'
|
distribution: 'temurin'
|
||||||
java-version: '11'
|
java-version: '11'
|
||||||
|
|
||||||
|
# a hack to build ID for x64 build in order for Google Play to allow upload of both 32 and 64 bit builds
|
||||||
|
- name: Bump Android x64 build ID
|
||||||
|
if: ${{ matrix.platform == 'android-64' }}
|
||||||
|
run: perl -i -pe 's/versionCode (\d+)/$x=$1+1; "versionCode $x"/e' android/vcmi-app/build.gradle
|
||||||
|
|
||||||
- name: Build Number
|
- name: Build Number
|
||||||
run: |
|
run: |
|
||||||
source '${{github.workspace}}/CI/get_package_name.sh'
|
source '${{github.workspace}}/CI/get_package_name.sh'
|
||||||
|
@ -921,7 +921,7 @@ std::vector<const battle::Unit *> BattleExchangeEvaluator::getOneTurnReachableUn
|
|||||||
|
|
||||||
ReachabilityInfo unitReachability = reachabilityIter != reachabilityCache.end() ? reachabilityIter->second : turnBattle.getReachability(unit);
|
ReachabilityInfo unitReachability = reachabilityIter != reachabilityCache.end() ? reachabilityIter->second : turnBattle.getReachability(unit);
|
||||||
|
|
||||||
bool reachable = unitReachability.distances[hex] <= radius;
|
bool reachable = unitReachability.distances.at(hex) <= radius;
|
||||||
|
|
||||||
if(!reachable && unitReachability.accessibility[hex] == EAccessibility::ALIVE_STACK)
|
if(!reachable && unitReachability.accessibility[hex] == EAccessibility::ALIVE_STACK)
|
||||||
{
|
{
|
||||||
@ -931,7 +931,7 @@ std::vector<const battle::Unit *> BattleExchangeEvaluator::getOneTurnReachableUn
|
|||||||
{
|
{
|
||||||
for(BattleHex neighbor : hex.neighbouringTiles())
|
for(BattleHex neighbor : hex.neighbouringTiles())
|
||||||
{
|
{
|
||||||
reachable = unitReachability.distances[neighbor] <= radius;
|
reachable = unitReachability.distances.at(neighbor) <= radius;
|
||||||
|
|
||||||
if(reachable) break;
|
if(reachable) break;
|
||||||
}
|
}
|
||||||
@ -981,7 +981,7 @@ bool BattleExchangeEvaluator::checkPositionBlocksOurStacks(HypotheticBattle & hb
|
|||||||
for(BattleHex hex = BattleHex::TOP_LEFT; hex.isValid(); hex = hex + 1)
|
for(BattleHex hex = BattleHex::TOP_LEFT; hex.isValid(); hex = hex + 1)
|
||||||
{
|
{
|
||||||
bool enemyUnit = false;
|
bool enemyUnit = false;
|
||||||
bool reachable = unitReachability.distances[hex] <= unitSpeed;
|
bool reachable = unitReachability.distances.at(hex) <= unitSpeed;
|
||||||
|
|
||||||
if(!reachable && unitReachability.accessibility[hex] == EAccessibility::ALIVE_STACK)
|
if(!reachable && unitReachability.accessibility[hex] == EAccessibility::ALIVE_STACK)
|
||||||
{
|
{
|
||||||
@ -993,7 +993,7 @@ bool BattleExchangeEvaluator::checkPositionBlocksOurStacks(HypotheticBattle & hb
|
|||||||
|
|
||||||
for(BattleHex neighbor : hex.neighbouringTiles())
|
for(BattleHex neighbor : hex.neighbouringTiles())
|
||||||
{
|
{
|
||||||
reachable = unitReachability.distances[neighbor] <= unitSpeed;
|
reachable = unitReachability.distances.at(neighbor) <= unitSpeed;
|
||||||
|
|
||||||
if(reachable) break;
|
if(reachable) break;
|
||||||
}
|
}
|
||||||
|
12
ChangeLog.md
12
ChangeLog.md
@ -70,6 +70,18 @@
|
|||||||
* Added support for HotA bank building from Factory
|
* Added support for HotA bank building from Factory
|
||||||
* Added support for HotA-style 8th creature in town
|
* Added support for HotA-style 8th creature in town
|
||||||
|
|
||||||
|
# 1.5.6 -> 1.5.7
|
||||||
|
|
||||||
|
* Fixed game freeze if player is attacked in online multiplayer game by another player when he has unread dialogs, such as new week notification
|
||||||
|
* Fixed possible game crash after being attacked by enemy with artifact that blocks spellcasting
|
||||||
|
* Fixed heroes on map limit game setting not respected when moving hero from town garrison.
|
||||||
|
* Add workaround to fix possible crash on attempt to start previously generated random map that has players without owned heroes or towns
|
||||||
|
* Fixed crash on right-clicking spell icon when receiving unlearnable spells from Pandora
|
||||||
|
* Fixed possible text overflow in match information box in online lobby
|
||||||
|
* Fixed overlapping text in lobby login window
|
||||||
|
* Fixed excessive removal of open dialogs such as new week or map events on new turn
|
||||||
|
* Fixed objects like Mystical Gardens not resetting their state on new week correctly
|
||||||
|
|
||||||
# 1.5.5 -> 1.5.6
|
# 1.5.5 -> 1.5.6
|
||||||
|
|
||||||
### Stability
|
### Stability
|
||||||
|
@ -203,6 +203,11 @@ void CPlayerInterface::playerEndsTurn(PlayerColor player)
|
|||||||
{
|
{
|
||||||
makingTurn = false;
|
makingTurn = false;
|
||||||
closeAllDialogs();
|
closeAllDialogs();
|
||||||
|
|
||||||
|
// remove all pending dialogs that do not expect query answer
|
||||||
|
vstd::erase_if(dialogs, [](const std::shared_ptr<CInfoWindow> & window){
|
||||||
|
return window->ID == QueryID::NONE;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -619,9 +624,7 @@ void CPlayerInterface::battleStartBefore(const BattleID & battleID, const CCreat
|
|||||||
{
|
{
|
||||||
movementController->onBattleStarted();
|
movementController->onBattleStarted();
|
||||||
|
|
||||||
//Don't wait for dialogs when we are non-active hot-seat player
|
waitForAllDialogs();
|
||||||
if (LOCPLINT == this)
|
|
||||||
waitForAllDialogs();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerInterface::battleStart(const BattleID & battleID, const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, BattleSide side, bool replayAllowed)
|
void CPlayerInterface::battleStart(const BattleID & battleID, const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, BattleSide side, bool replayAllowed)
|
||||||
@ -644,9 +647,7 @@ void CPlayerInterface::battleStart(const BattleID & battleID, const CCreatureSet
|
|||||||
cb->registerBattleInterface(autofightingAI);
|
cb->registerBattleInterface(autofightingAI);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Don't wait for dialogs when we are non-active hot-seat player
|
waitForAllDialogs();
|
||||||
if (LOCPLINT == this)
|
|
||||||
waitForAllDialogs();
|
|
||||||
|
|
||||||
BATTLE_EVENT_POSSIBLE_RETURN;
|
BATTLE_EVENT_POSSIBLE_RETURN;
|
||||||
}
|
}
|
||||||
@ -1760,6 +1761,9 @@ void CPlayerInterface::artifactDisassembled(const ArtifactLocation &al)
|
|||||||
|
|
||||||
void CPlayerInterface::waitForAllDialogs()
|
void CPlayerInterface::waitForAllDialogs()
|
||||||
{
|
{
|
||||||
|
if (!makingTurn)
|
||||||
|
return;
|
||||||
|
|
||||||
while(!dialogs.empty())
|
while(!dialogs.empty())
|
||||||
{
|
{
|
||||||
auto unlockInterface = vstd::makeUnlockGuard(GH.interfaceMutex);
|
auto unlockInterface = vstd::makeUnlockGuard(GH.interfaceMutex);
|
||||||
|
@ -68,7 +68,10 @@ GlobalLobbyLoginWindow::GlobalLobbyLoginWindow()
|
|||||||
onLoginModeChanged(0); // call it manually to disable widgets - toggleMode will not emit this call if this is currently selected option
|
onLoginModeChanged(0); // call it manually to disable widgets - toggleMode will not emit this call if this is currently selected option
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
toggleMode->setSelected(1);
|
toggleMode->setSelected(1);
|
||||||
|
onLoginModeChanged(1);
|
||||||
|
}
|
||||||
|
|
||||||
filledBackground->setPlayerColor(PlayerColor(1));
|
filledBackground->setPlayerColor(PlayerColor(1));
|
||||||
inputUsername->setCallback([this](const std::string & text)
|
inputUsername->setCallback([this](const std::string & text)
|
||||||
|
@ -286,5 +286,5 @@ GlobalLobbyMatchCard::GlobalLobbyMatchCard(GlobalLobbyWindow * window, const Glo
|
|||||||
opponentDescription.replaceNumber(matchDescription.participants.size());
|
opponentDescription.replaceNumber(matchDescription.participants.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
labelMatchOpponent = std::make_shared<CLabel>(5, 30, FONT_SMALL, ETextAlignment::CENTERLEFT, Colors::YELLOW, opponentDescription.toString());
|
labelMatchOpponent = std::make_shared<CLabel>(5, 30, FONT_SMALL, ETextAlignment::CENTERLEFT, Colors::YELLOW, opponentDescription.toString(), 120);
|
||||||
}
|
}
|
||||||
|
@ -233,7 +233,7 @@ std::string CComponent::getDescription() const
|
|||||||
return description;
|
return description;
|
||||||
}
|
}
|
||||||
case ComponentType::SPELL:
|
case ComponentType::SPELL:
|
||||||
return CGI->spells()->getById(data.subType.as<SpellID>())->getDescriptionTranslated(data.value.value_or(0));
|
return CGI->spells()->getById(data.subType.as<SpellID>())->getDescriptionTranslated(std::max(0, data.value.value_or(0)));
|
||||||
case ComponentType::MORALE:
|
case ComponentType::MORALE:
|
||||||
return CGI->generaltexth->heroscrn[ 4 - (data.value.value_or(0)>0) + (data.value.value_or(0)<0)];
|
return CGI->generaltexth->heroscrn[ 4 - (data.value.value_or(0)>0) + (data.value.value_or(0)<0)];
|
||||||
case ComponentType::LUCK:
|
case ComponentType::LUCK:
|
||||||
@ -293,7 +293,7 @@ std::string CComponent::getSubtitle() const
|
|||||||
return CGI->artifacts()->getById(data.subType.as<ArtifactID>())->getNameTranslated();
|
return CGI->artifacts()->getById(data.subType.as<ArtifactID>())->getNameTranslated();
|
||||||
case ComponentType::SPELL_SCROLL:
|
case ComponentType::SPELL_SCROLL:
|
||||||
case ComponentType::SPELL:
|
case ComponentType::SPELL:
|
||||||
if (data.value < 0)
|
if (data.value.value_or(0) < 0)
|
||||||
return "{#A9A9A9|" + CGI->spells()->getById(data.subType.as<SpellID>())->getNameTranslated() + "}";
|
return "{#A9A9A9|" + CGI->spells()->getById(data.subType.as<SpellID>())->getNameTranslated() + "}";
|
||||||
else
|
else
|
||||||
return CGI->spells()->getById(data.subType.as<SpellID>())->getNameTranslated();
|
return CGI->spells()->getById(data.subType.as<SpellID>())->getNameTranslated();
|
||||||
|
6
debian/changelog
vendored
6
debian/changelog
vendored
@ -4,6 +4,12 @@ vcmi (1.6.0) jammy; urgency=medium
|
|||||||
|
|
||||||
-- Ivan Savenko <saven.ivan@gmail.com> Fri, 30 Aug 2024 12:00:00 +0200
|
-- Ivan Savenko <saven.ivan@gmail.com> Fri, 30 Aug 2024 12:00:00 +0200
|
||||||
|
|
||||||
|
vcmi (1.5.7) jammy; urgency=medium
|
||||||
|
|
||||||
|
* New upstream release
|
||||||
|
|
||||||
|
-- Ivan Savenko <saven.ivan@gmail.com> Mon, 26 Aug 2024 12:00:00 +0200
|
||||||
|
|
||||||
vcmi (1.5.6) jammy; urgency=medium
|
vcmi (1.5.6) jammy; urgency=medium
|
||||||
|
|
||||||
* New upstream release
|
* New upstream release
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
[![VCMI](https://github.com/vcmi/vcmi/actions/workflows/github.yml/badge.svg?branch=develop&event=push)](https://github.com/vcmi/vcmi/actions/workflows/github.yml?query=branch%3Adevelop+event%3Apush)
|
[![VCMI](https://github.com/vcmi/vcmi/actions/workflows/github.yml/badge.svg?branch=develop&event=push)](https://github.com/vcmi/vcmi/actions/workflows/github.yml?query=branch%3Adevelop+event%3Apush)
|
||||||
[![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.0/total)](https://github.com/vcmi/vcmi/releases/tag/1.5.0)
|
||||||
[![Github Downloads](https://img.shields.io/github/downloads/vcmi/vcmi/1.5.5/total)](https://github.com/vcmi/vcmi/releases/tag/1.5.5)
|
|
||||||
[![Github Downloads](https://img.shields.io/github/downloads/vcmi/vcmi/1.5.6/total)](https://github.com/vcmi/vcmi/releases/tag/1.5.6)
|
[![Github Downloads](https://img.shields.io/github/downloads/vcmi/vcmi/1.5.6/total)](https://github.com/vcmi/vcmi/releases/tag/1.5.6)
|
||||||
|
[![Github Downloads](https://img.shields.io/github/downloads/vcmi/vcmi/1.5.7/total)](https://github.com/vcmi/vcmi/releases/tag/1.5.7)
|
||||||
[![Github Downloads](https://img.shields.io/github/downloads/vcmi/vcmi/total)](https://github.com/vcmi/vcmi/releases)
|
[![Github Downloads](https://img.shields.io/github/downloads/vcmi/vcmi/total)](https://github.com/vcmi/vcmi/releases)
|
||||||
|
|
||||||
# VCMI Project
|
# VCMI Project
|
||||||
|
@ -91,6 +91,7 @@
|
|||||||
<launchable type="desktop-id">vcmilauncher.desktop</launchable>
|
<launchable type="desktop-id">vcmilauncher.desktop</launchable>
|
||||||
<releases>
|
<releases>
|
||||||
<release version="1.6.0" date="2024-08-30" type="development"/>
|
<release version="1.6.0" date="2024-08-30" type="development"/>
|
||||||
|
<release version="1.5.7" date="2024-08-26" type="stable"/>
|
||||||
<release version="1.5.6" date="2024-08-04" type="stable"/>
|
<release version="1.5.6" date="2024-08-04" type="stable"/>
|
||||||
<release version="1.5.5" date="2024-07-17" type="stable"/>
|
<release version="1.5.5" date="2024-07-17" type="stable"/>
|
||||||
<release version="1.5.4" date="2024-07-12" type="stable"/>
|
<release version="1.5.4" date="2024-07-12" type="stable"/>
|
||||||
|
@ -1051,7 +1051,7 @@ ReachabilityInfo CBattleInfoCallback::makeBFS(const AccessibilityInfo &accessibi
|
|||||||
if(isInObstacle(curHex, obstacles, checkParams))
|
if(isInObstacle(curHex, obstacles, checkParams))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const int costToNeighbour = ret.distances[curHex.hex] + 1;
|
const int costToNeighbour = ret.distances.at(curHex.hex) + 1;
|
||||||
|
|
||||||
for(BattleHex neighbour : BattleHex::neighbouringTilesCache[curHex.hex])
|
for(BattleHex neighbour : BattleHex::neighbouringTilesCache[curHex.hex])
|
||||||
{
|
{
|
||||||
|
@ -303,6 +303,27 @@ void CGameState::initNewGame(const IMapService * mapService, bool allowSavingRan
|
|||||||
std::unique_ptr<CMap> randomMap = mapGenerator.generate();
|
std::unique_ptr<CMap> randomMap = mapGenerator.generate();
|
||||||
progressTracking.exclude(mapGenerator);
|
progressTracking.exclude(mapGenerator);
|
||||||
|
|
||||||
|
// Update starting options
|
||||||
|
for(int i = 0; i < randomMap->players.size(); ++i)
|
||||||
|
{
|
||||||
|
const auto & playerInfo = randomMap->players[i];
|
||||||
|
if(playerInfo.canAnyonePlay())
|
||||||
|
{
|
||||||
|
PlayerSettings & playerSettings = scenarioOps->playerInfos[PlayerColor(i)];
|
||||||
|
playerSettings.compOnly = !playerInfo.canHumanPlay;
|
||||||
|
playerSettings.castle = playerInfo.defaultCastle();
|
||||||
|
if(playerSettings.isControlledByAI() && playerSettings.name.empty())
|
||||||
|
{
|
||||||
|
playerSettings.name = VLC->generaltexth->allTexts[468];
|
||||||
|
}
|
||||||
|
playerSettings.color = PlayerColor(i);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
scenarioOps->playerInfos.erase(PlayerColor(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(allowSavingRandomMap)
|
if(allowSavingRandomMap)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -332,26 +353,6 @@ void CGameState::initNewGame(const IMapService * mapService, bool allowSavingRan
|
|||||||
}
|
}
|
||||||
|
|
||||||
map = randomMap.release();
|
map = randomMap.release();
|
||||||
// Update starting options
|
|
||||||
for(int i = 0; i < map->players.size(); ++i)
|
|
||||||
{
|
|
||||||
const auto & playerInfo = map->players[i];
|
|
||||||
if(playerInfo.canAnyonePlay())
|
|
||||||
{
|
|
||||||
PlayerSettings & playerSettings = scenarioOps->playerInfos[PlayerColor(i)];
|
|
||||||
playerSettings.compOnly = !playerInfo.canHumanPlay;
|
|
||||||
playerSettings.castle = playerInfo.defaultCastle();
|
|
||||||
if(playerSettings.isControlledByAI() && playerSettings.name.empty())
|
|
||||||
{
|
|
||||||
playerSettings.name = VLC->generaltexth->allTexts[468];
|
|
||||||
}
|
|
||||||
playerSettings.color = PlayerColor(i);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
scenarioOps->playerInfos.erase(PlayerColor(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
logGlobal->info("Generated random map in %i ms.", sw.getDiff());
|
logGlobal->info("Generated random map in %i ms.", sw.getDiff());
|
||||||
}
|
}
|
||||||
|
@ -339,6 +339,7 @@ void Rewardable::Info::configureRewards(
|
|||||||
void Rewardable::Info::configureObject(Rewardable::Configuration & object, vstd::RNG & rng, IGameCallback * cb) const
|
void Rewardable::Info::configureObject(Rewardable::Configuration & object, vstd::RNG & rng, IGameCallback * cb) const
|
||||||
{
|
{
|
||||||
object.info.clear();
|
object.info.clear();
|
||||||
|
object.variables.values.clear();
|
||||||
|
|
||||||
configureVariables(object, rng, cb, parameters["variables"]);
|
configureVariables(object, rng, cb, parameters["variables"]);
|
||||||
|
|
||||||
|
@ -2759,10 +2759,11 @@ bool CGameHandler::garrisonSwap(ObjectInstanceID tid)
|
|||||||
}
|
}
|
||||||
else if (town->garrisonHero && !town->visitingHero) //move hero out of the garrison
|
else if (town->garrisonHero && !town->visitingHero) //move hero out of the garrison
|
||||||
{
|
{
|
||||||
//check if moving hero out of town will break 8 wandering heroes limit
|
int mapCap = VLC->settings()->getInteger(EGameSettings::HEROES_PER_PLAYER_ON_MAP_CAP);
|
||||||
if (getHeroCount(town->garrisonHero->tempOwner,false) >= 8)
|
//check if moving hero out of town will break wandering heroes limit
|
||||||
|
if (getHeroCount(town->garrisonHero->tempOwner,false) >= mapCap)
|
||||||
{
|
{
|
||||||
complain("Cannot move hero out of the garrison, there are already 8 wandering heroes!");
|
complain("Cannot move hero out of the garrison, there are already " + std::to_string(mapCap) + " wandering heroes!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user