mirror of
https://github.com/vcmi/vcmi.git
synced 2026-05-22 09:55:17 +02:00
Fixes for crashes in 1.7.4 beta
- Fixed crash in MP between 1.7.3 and 1.7.4 on opening exchange window - Fixed crash if creature with area attack and death blow attacks empty space (Magog in WoG) - Fixed crash on formatting of spell effect preview text - Fixed crash if hero has invalid path (e.g. blocked by another hero) and player attempts to end turn - Try to fix crash on opening battle-only mode in some cases(?)
This commit is contained in:
@@ -35,7 +35,7 @@ android {
|
||||
minSdk = qtMinSdkVersion as Integer
|
||||
targetSdk = qtTargetSdkVersion as Integer // ANDROID_TARGET_SDK_VERSION in the CMake project
|
||||
|
||||
versionCode 1754
|
||||
versionCode 1757
|
||||
versionName "1.7.4"
|
||||
}
|
||||
|
||||
|
||||
@@ -261,6 +261,6 @@ void ApplyOnLobbyScreenNetPackVisitor::visitLobbyShowMessage(LobbyShowMessage &
|
||||
|
||||
void ApplyOnLobbyScreenNetPackVisitor::visitLobbySetBattleOnlyModeStartInfo(LobbySetBattleOnlyModeStartInfo & pack)
|
||||
{
|
||||
if(lobby->tabBattleOnlyMode)
|
||||
if(lobby && lobby->tabBattleOnlyMode)
|
||||
lobby->tabBattleOnlyMode->applyStartInfo(pack.startInfo);
|
||||
}
|
||||
|
||||
@@ -84,12 +84,10 @@ void PlayerLocalState::erasePath(const CGHeroInstance * h)
|
||||
synchronizeState();
|
||||
}
|
||||
|
||||
bool PlayerLocalState::verifyPath(const CGHeroInstance * h)
|
||||
void PlayerLocalState::verifyPath(const CGHeroInstance * h)
|
||||
{
|
||||
if(!hasPath(h))
|
||||
return false;
|
||||
setPath(h, getPath(h).endPos());
|
||||
return true;
|
||||
if (hasPath(h))
|
||||
setPath(h, getPath(h).endPos());
|
||||
}
|
||||
|
||||
SpellID PlayerLocalState::getCurrentSpell() const
|
||||
|
||||
@@ -84,7 +84,7 @@ public:
|
||||
|
||||
void removeLastNode(const CGHeroInstance * h);
|
||||
void erasePath(const CGHeroInstance * h);
|
||||
bool verifyPath(const CGHeroInstance * h);
|
||||
void verifyPath(const CGHeroInstance * h);
|
||||
|
||||
/// Returns currently selected object
|
||||
const CGHeroInstance * getCurrentHero() const;
|
||||
|
||||
@@ -307,11 +307,12 @@ void AdventureMapShortcuts::endTurn()
|
||||
{
|
||||
if(!GAME->interface()->localState->isHeroSleeping(hero) && hero->movementPointsRemaining() > 0)
|
||||
{
|
||||
GAME->interface()->localState->verifyPath(hero);
|
||||
|
||||
// Only show hero reminder if conditions are met:
|
||||
// - There are still movement points
|
||||
// - Hero doesn't have a path or there are no points for the first step on path
|
||||
|
||||
if(!GAME->interface()->localState->verifyPath(hero))
|
||||
// - Hero doesn't have a path or there are enough points for the first step on path
|
||||
if(!GAME->interface()->localState->hasPath(hero))
|
||||
{
|
||||
showMoveReminderDialog();
|
||||
return;
|
||||
|
||||
@@ -135,16 +135,15 @@ static std::string formatRetaliation(const DamageEstimation & estimation, bool m
|
||||
}
|
||||
|
||||
static std::string prepareSpellEffectText(int gnrlTextID, const spells::effects::SpellEffectValue & value,
|
||||
std::string_view spellName, std::string_view targetName)
|
||||
const std::string & spellName, const std::string & targetName)
|
||||
{
|
||||
auto const & templateText = LIBRARY->generaltexth->allTexts[gnrlTextID];
|
||||
std::string baseText;
|
||||
if(!targetName.empty() && !spellName.empty())
|
||||
baseText = boost::str(boost::format(templateText) % spellName % targetName);
|
||||
else if(targetName.empty())
|
||||
baseText = boost::str(boost::format(templateText) % spellName);
|
||||
else
|
||||
baseText = boost::str(boost::format(templateText) % targetName);
|
||||
auto templateText = MetaString::createFromTextID( "core.genrltxt." + std::to_string(gnrlTextID));
|
||||
if (!spellName.empty())
|
||||
templateText.replaceRawString(spellName);
|
||||
if (!targetName.empty())
|
||||
templateText.replaceRawString(targetName);
|
||||
|
||||
std::string baseText = templateText.toString();
|
||||
|
||||
if(value.unitsDelta > 0)
|
||||
{
|
||||
|
||||
@@ -614,10 +614,13 @@ void BattleStacksController::stackAttacking( const StackAttackInfo & info )
|
||||
|
||||
if(info.deathBlow)
|
||||
{
|
||||
owner.addToAnimationStage(EAnimationEvents::BEFORE_HIT, [this, defender, info]() {
|
||||
owner.appendBattleLog(info.attacker->formatGeneralMessage(365));
|
||||
owner.effectsController->displayEffect(EBattleEffect::DEATH_BLOW, AudioPath::builtin("DEATHBLO"), defender->getPosition());
|
||||
});
|
||||
if (defender)
|
||||
{
|
||||
owner.addToAnimationStage(EAnimationEvents::BEFORE_HIT, [this, defender, info]() {
|
||||
owner.appendBattleLog(info.attacker->formatGeneralMessage(365));
|
||||
owner.effectsController->displayEffect(EBattleEffect::DEATH_BLOW, AudioPath::builtin("DEATHBLO"), defender->getPosition());
|
||||
});
|
||||
}
|
||||
|
||||
for(auto elem : info.secondaryDefender)
|
||||
{
|
||||
|
||||
@@ -97,7 +97,7 @@ public:
|
||||
auto * result = std::get_if<CustomType>(&data_);
|
||||
if (result)
|
||||
return *result;
|
||||
throw std::runtime_error("Invalid addInfo type access!");
|
||||
throw std::runtime_error("Invalid addInfo type access! Stored type: " + std::to_string(data_.index()));
|
||||
}
|
||||
|
||||
template<typename CustomType>
|
||||
@@ -106,7 +106,7 @@ public:
|
||||
auto * result = std::get_if<CustomType>(&data_);
|
||||
if (result)
|
||||
return *result;
|
||||
throw std::runtime_error("Invalid addInfo type access!");
|
||||
throw std::runtime_error("Invalid addInfo type access! Stored type: " + std::to_string(data_.index()));
|
||||
}
|
||||
|
||||
template <class H>
|
||||
|
||||
@@ -1402,7 +1402,8 @@ struct DLL_LINKAGE GarrisonDialog : public Query
|
||||
h & objid;
|
||||
h & hid;
|
||||
h & removableUnits;
|
||||
h & customTitle;
|
||||
if (h.hasFeature(Handler::Version::CUSTOM_GARRISON_TITLE))
|
||||
h & customTitle;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -62,9 +62,11 @@ enum class ESerializationVersion : int32_t
|
||||
DISABLE_TACTICS, // disable tactics
|
||||
REWARDABLE_EXTENSIONS_2, // movement points limiter for rewardables
|
||||
BONUS_TRIGGER, // bonus that allows triggered effects in combat
|
||||
CUSTOM_GARRISON_TITLE, // GarrisonDialog pack now has custom title parameter
|
||||
|
||||
RELEASE_170 = HOTA_MAP_STACK_COUNT,
|
||||
CURRENT = BONUS_TRIGGER,
|
||||
RELEASE_174 = CUSTOM_GARRISON_TITLE,
|
||||
CURRENT = CUSTOM_GARRISON_TITLE,
|
||||
};
|
||||
|
||||
static_assert(ESerializationVersion::MINIMAL <= ESerializationVersion::CURRENT, "Invalid serialization version definition!");
|
||||
|
||||
Reference in New Issue
Block a user