mirror of
https://github.com/vcmi/vcmi.git
synced 2025-06-06 23:26:26 +02:00
Merge pull request #2554 from IvanSavenko/crashfixes
Fixes for crashes from Android crash reporter
This commit is contained in:
commit
5dc735494c
@ -189,7 +189,7 @@ void DefenceBehavior::evaluateDefence(Goals::TGoalVec & tasks, const CGTownInsta
|
|||||||
town->getNameTranslated(),
|
town->getNameTranslated(),
|
||||||
treat.danger,
|
treat.danger,
|
||||||
std::to_string(treat.turn),
|
std::to_string(treat.turn),
|
||||||
treat.hero->getNameTranslated());
|
treat.hero ? treat.hero->getNameTranslated() : std::string("<no hero>"));
|
||||||
|
|
||||||
handleCounterAttack(town, treat, treatNode.maximumDanger, tasks);
|
handleCounterAttack(town, treat, treatNode.maximumDanger, tasks);
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ android {
|
|||||||
applicationId "is.xyz.vcmi"
|
applicationId "is.xyz.vcmi"
|
||||||
minSdk 19
|
minSdk 19
|
||||||
targetSdk 31
|
targetSdk 31
|
||||||
versionCode 1304
|
versionCode 1305
|
||||||
versionName "1.3.0"
|
versionName "1.3.0"
|
||||||
setProperty("archivesBaseName", "vcmi")
|
setProperty("archivesBaseName", "vcmi")
|
||||||
}
|
}
|
||||||
|
@ -636,7 +636,9 @@ void BattleResultWindow::show(Canvas & to)
|
|||||||
|
|
||||||
void BattleResultWindow::buttonPressed(int button)
|
void BattleResultWindow::buttonPressed(int button)
|
||||||
{
|
{
|
||||||
|
if (resultCallback)
|
||||||
resultCallback(button);
|
resultCallback(button);
|
||||||
|
|
||||||
CPlayerInterface &intTmp = owner; //copy reference because "this" will be destructed soon
|
CPlayerInterface &intTmp = owner; //copy reference because "this" will be destructed soon
|
||||||
|
|
||||||
close();
|
close();
|
||||||
|
@ -88,6 +88,8 @@ void CGuiHandler::handleEvents()
|
|||||||
void CGuiHandler::fakeMouseMove()
|
void CGuiHandler::fakeMouseMove()
|
||||||
{
|
{
|
||||||
dispatchMainThread([](){
|
dispatchMainThread([](){
|
||||||
|
assert(CPlayerInterface::pim);
|
||||||
|
boost::unique_lock lock(*CPlayerInterface::pim);
|
||||||
GH.events().dispatchMouseMoved(Point(0, 0), GH.getCursorPosition());
|
GH.events().dispatchMouseMoved(Point(0, 0), GH.getCursorPosition());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -147,7 +147,6 @@ void RandomMapTab::updateMapInfoByHost()
|
|||||||
mapInfo->mapHeader->twoLevel = mapGenOptions->getHasTwoLevels();
|
mapInfo->mapHeader->twoLevel = mapGenOptions->getHasTwoLevels();
|
||||||
|
|
||||||
// Generate player information
|
// Generate player information
|
||||||
mapInfo->mapHeader->players.clear();
|
|
||||||
int playersToGen = PlayerColor::PLAYER_LIMIT_I;
|
int playersToGen = PlayerColor::PLAYER_LIMIT_I;
|
||||||
if(mapGenOptions->getPlayerCount() != CMapGenOptions::RANDOM_SIZE)
|
if(mapGenOptions->getPlayerCount() != CMapGenOptions::RANDOM_SIZE)
|
||||||
{
|
{
|
||||||
@ -157,10 +156,15 @@ void RandomMapTab::updateMapInfoByHost()
|
|||||||
playersToGen = mapGenOptions->getPlayerCount();
|
playersToGen = mapGenOptions->getPlayerCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
mapInfo->mapHeader->howManyTeams = playersToGen;
|
mapInfo->mapHeader->howManyTeams = playersToGen;
|
||||||
|
|
||||||
std::set<TeamID> occupiedTeams;
|
std::set<TeamID> occupiedTeams;
|
||||||
|
for(int i = 0; i < PlayerColor::PLAYER_LIMIT_I; ++i)
|
||||||
|
{
|
||||||
|
mapInfo->mapHeader->players[i].canComputerPlay = false;
|
||||||
|
mapInfo->mapHeader->players[i].canHumanPlay = false;
|
||||||
|
}
|
||||||
|
|
||||||
for(int i = 0; i < playersToGen; ++i)
|
for(int i = 0; i < playersToGen; ++i)
|
||||||
{
|
{
|
||||||
PlayerInfo player;
|
PlayerInfo player;
|
||||||
@ -179,7 +183,7 @@ void RandomMapTab::updateMapInfoByHost()
|
|||||||
occupiedTeams.insert(team);
|
occupiedTeams.insert(team);
|
||||||
player.hasMainTown = true;
|
player.hasMainTown = true;
|
||||||
player.generateHeroAtMainTown = true;
|
player.generateHeroAtMainTown = true;
|
||||||
mapInfo->mapHeader->players.push_back(player);
|
mapInfo->mapHeader->players[i] = player;
|
||||||
}
|
}
|
||||||
for(auto & player : mapInfo->mapHeader->players)
|
for(auto & player : mapInfo->mapHeader->players)
|
||||||
{
|
{
|
||||||
|
@ -1451,7 +1451,11 @@ CBuildWindow::CBuildWindow(const CGTownInstance *Town, const CBuilding * Buildin
|
|||||||
auto statusbarBackground = std::make_shared<CPicture>(background->getSurface(), Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26);
|
auto statusbarBackground = std::make_shared<CPicture>(background->getSurface(), Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26);
|
||||||
statusbar = CGStatusBar::create(statusbarBackground);
|
statusbar = CGStatusBar::create(statusbarBackground);
|
||||||
|
|
||||||
name = std::make_shared<CLabel>(197, 30, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, boost::str(boost::format(CGI->generaltexth->hcommands[7]) % building->getNameTranslated()));
|
MetaString nameString;
|
||||||
|
nameString.appendTextID("core.hallinfo.7");
|
||||||
|
nameString.replaceTextID(building->getNameTextID());
|
||||||
|
|
||||||
|
name = std::make_shared<CLabel>(197, 30, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, nameString.toString());
|
||||||
description = std::make_shared<CTextBox>(building->getDescriptionTranslated(), Rect(33, 135, 329, 67), 0, FONT_MEDIUM, ETextAlignment::CENTER);
|
description = std::make_shared<CTextBox>(building->getDescriptionTranslated(), Rect(33, 135, 329, 67), 0, FONT_MEDIUM, ETextAlignment::CENTER);
|
||||||
stateText = std::make_shared<CTextBox>(getTextForState(state), Rect(33, 216, 329, 67), 0, FONT_SMALL, ETextAlignment::CENTER);
|
stateText = std::make_shared<CTextBox>(getTextForState(state), Rect(33, 216, 329, 67), 0, FONT_SMALL, ETextAlignment::CENTER);
|
||||||
|
|
||||||
@ -1468,14 +1472,20 @@ CBuildWindow::CBuildWindow(const CGTownInstance *Town, const CBuilding * Buildin
|
|||||||
|
|
||||||
if(!rightClick)
|
if(!rightClick)
|
||||||
{ //normal window
|
{ //normal window
|
||||||
std::string tooltipYes = boost::str(boost::format(CGI->generaltexth->allTexts[595]) % building->getNameTranslated());
|
|
||||||
std::string tooltipNo = boost::str(boost::format(CGI->generaltexth->allTexts[596]) % building->getNameTranslated());
|
|
||||||
|
|
||||||
buy = std::make_shared<CButton>(Point(45, 446), "IBUY30", CButton::tooltip(tooltipYes), [&](){ buyFunc(); }, EShortcut::GLOBAL_ACCEPT);
|
MetaString tooltipYes;
|
||||||
|
tooltipYes.appendTextID("core.genrltxt.595");
|
||||||
|
tooltipYes.replaceTextID(building->getNameTextID());
|
||||||
|
|
||||||
|
MetaString tooltipNo;
|
||||||
|
tooltipNo.appendTextID("core.genrltxt.596");
|
||||||
|
tooltipNo.replaceTextID(building->getNameTextID());
|
||||||
|
|
||||||
|
buy = std::make_shared<CButton>(Point(45, 446), "IBUY30", CButton::tooltip(tooltipYes.toString()), [&](){ buyFunc(); }, EShortcut::GLOBAL_ACCEPT);
|
||||||
buy->setBorderColor(Colors::METALLIC_GOLD);
|
buy->setBorderColor(Colors::METALLIC_GOLD);
|
||||||
buy->block(state!=7 || LOCPLINT->playerID != town->tempOwner);
|
buy->block(state!=7 || LOCPLINT->playerID != town->tempOwner);
|
||||||
|
|
||||||
cancel = std::make_shared<CButton>(Point(290, 445), "ICANCEL", CButton::tooltip(tooltipNo), [&](){ close();}, EShortcut::GLOBAL_CANCEL);
|
cancel = std::make_shared<CButton>(Point(290, 445), "ICANCEL", CButton::tooltip(tooltipNo.toString()), [&](){ close();}, EShortcut::GLOBAL_CANCEL);
|
||||||
cancel->setBorderColor(Colors::METALLIC_GOLD);
|
cancel->setBorderColor(Colors::METALLIC_GOLD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1841,17 +1851,25 @@ CBlacksmithDialog::CBlacksmithDialog(bool possible, CreatureID creMachineID, Art
|
|||||||
anim = std::make_shared<CCreatureAnim>(64, 50, creature->animDefName);
|
anim = std::make_shared<CCreatureAnim>(64, 50, creature->animDefName);
|
||||||
anim->clipRect(113,125,200,150);
|
anim->clipRect(113,125,200,150);
|
||||||
|
|
||||||
title = std::make_shared<CLabel>(165, 28, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW,
|
MetaString titleString;
|
||||||
boost::str(boost::format(CGI->generaltexth->allTexts[274]) % creature->getNameSingularTranslated()));
|
titleString.appendTextID("core.genrltxt.274");
|
||||||
|
titleString.replaceTextID(creature->getNameSingularTextID());
|
||||||
|
|
||||||
|
MetaString buyText;
|
||||||
|
buyText.appendTextID("core.genrltxt.595");
|
||||||
|
buyText.replaceTextID(creature->getNameSingularTextID());
|
||||||
|
|
||||||
|
MetaString cancelText;
|
||||||
|
cancelText.appendTextID("core.genrltxt.596");
|
||||||
|
cancelText.replaceTextID(creature->getNameSingularTextID());
|
||||||
|
|
||||||
|
std::string costString = std::to_string(aid.toArtifact(CGI->artifacts())->getPrice());
|
||||||
|
|
||||||
|
title = std::make_shared<CLabel>(165, 28, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, titleString.toString());
|
||||||
costText = std::make_shared<CLabel>(165, 218, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->jktexts[43]);
|
costText = std::make_shared<CLabel>(165, 218, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->jktexts[43]);
|
||||||
costValue = std::make_shared<CLabel>(165, 292, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE,
|
costValue = std::make_shared<CLabel>(165, 292, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, costString);
|
||||||
std::to_string(aid.toArtifact(CGI->artifacts())->getPrice()));
|
buy = std::make_shared<CButton>(Point(42, 312), "IBUY30.DEF", CButton::tooltip(buyText.toString()), [&](){ close(); }, EShortcut::GLOBAL_ACCEPT);
|
||||||
|
cancel = std::make_shared<CButton>(Point(224, 312), "ICANCEL.DEF", CButton::tooltip(cancelText.toString()), [&](){ close(); }, EShortcut::GLOBAL_CANCEL);
|
||||||
std::string text = boost::str(boost::format(CGI->generaltexth->allTexts[595]) % creature->getNameSingularTranslated());
|
|
||||||
buy = std::make_shared<CButton>(Point(42, 312), "IBUY30.DEF", CButton::tooltip(text), [&](){ close(); }, EShortcut::GLOBAL_ACCEPT);
|
|
||||||
|
|
||||||
text = boost::str(boost::format(CGI->generaltexth->allTexts[596]) % creature->getNameSingularTranslated());
|
|
||||||
cancel = std::make_shared<CButton>(Point(224, 312), "ICANCEL.DEF", CButton::tooltip(text), [&](){ close(); }, EShortcut::GLOBAL_CANCEL);
|
|
||||||
|
|
||||||
if(possible)
|
if(possible)
|
||||||
buy->addCallback([=](){ LOCPLINT->cb->buyArtifact(LOCPLINT->cb->getHero(hid),aid); });
|
buy->addCallback([=](){ LOCPLINT->cb->buyArtifact(LOCPLINT->cb->getHero(hid),aid); });
|
||||||
|
@ -1262,11 +1262,14 @@ void CAltarWindow::SacrificeAll()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for(const auto & aw : arts->visibleArtSet.artifactsWorn)
|
std::vector<ConstTransitivePtr<CArtifactInstance>> artsForMove;
|
||||||
|
for(const auto& slotInfo : arts->visibleArtSet.artifactsWorn)
|
||||||
{
|
{
|
||||||
if(!aw.second.locked)
|
if(!slotInfo.second.locked && slotInfo.second.artifact->artType->isTradable())
|
||||||
moveArtToAltar(nullptr, aw.second.artifact);
|
artsForMove.push_back(slotInfo.second.artifact);
|
||||||
}
|
}
|
||||||
|
for(auto artInst : artsForMove)
|
||||||
|
moveArtToAltar(nullptr, artInst);
|
||||||
arts->updateWornSlots();
|
arts->updateWornSlots();
|
||||||
SacrificeBackpack();
|
SacrificeBackpack();
|
||||||
}
|
}
|
||||||
|
@ -996,6 +996,12 @@ CBuilding::TRequired CGTownInstance::genBuildingRequirements(const BuildingID &
|
|||||||
std::function<CBuilding::TRequired::Variant(const BuildingID &)> dependTest =
|
std::function<CBuilding::TRequired::Variant(const BuildingID &)> dependTest =
|
||||||
[&](const BuildingID & id) -> CBuilding::TRequired::Variant
|
[&](const BuildingID & id) -> CBuilding::TRequired::Variant
|
||||||
{
|
{
|
||||||
|
if (town->buildings.count(id) == 0)
|
||||||
|
{
|
||||||
|
logMod->error("Invalid building ID %d in building dependencies!", id.getNum());
|
||||||
|
return CBuilding::TRequired::OperatorAll();
|
||||||
|
}
|
||||||
|
|
||||||
const CBuilding * build = town->buildings.at(id);
|
const CBuilding * build = town->buildings.at(id);
|
||||||
CBuilding::TRequired::OperatorAll requirements;
|
CBuilding::TRequired::OperatorAll requirements;
|
||||||
|
|
||||||
|
@ -6464,6 +6464,8 @@ void CGameHandler::runBattle()
|
|||||||
|
|
||||||
bool CGameHandler::makeAutomaticAction(const CStack *stack, BattleAction &ba)
|
bool CGameHandler::makeAutomaticAction(const CStack *stack, BattleAction &ba)
|
||||||
{
|
{
|
||||||
|
boost::unique_lock lock(battleActionMutex);
|
||||||
|
|
||||||
BattleSetActiveStack bsa;
|
BattleSetActiveStack bsa;
|
||||||
bsa.stack = stack->unitId();
|
bsa.stack = stack->unitId();
|
||||||
bsa.askPlayerInterface = false;
|
bsa.askPlayerInterface = false;
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
#include "../lib/spells/ISpellMechanics.h"
|
#include "../lib/spells/ISpellMechanics.h"
|
||||||
#include "../lib/serializer/Cast.h"
|
#include "../lib/serializer/Cast.h"
|
||||||
|
|
||||||
|
extern boost::recursive_mutex battleActionMutex;
|
||||||
|
|
||||||
void ApplyGhNetPackVisitor::visitSaveGame(SaveGame & pack)
|
void ApplyGhNetPackVisitor::visitSaveGame(SaveGame & pack)
|
||||||
{
|
{
|
||||||
gh.save(pack.fname);
|
gh.save(pack.fname);
|
||||||
@ -280,6 +282,8 @@ void ApplyGhNetPackVisitor::visitQueryReply(QueryReply & pack)
|
|||||||
|
|
||||||
void ApplyGhNetPackVisitor::visitMakeAction(MakeAction & pack)
|
void ApplyGhNetPackVisitor::visitMakeAction(MakeAction & pack)
|
||||||
{
|
{
|
||||||
|
boost::unique_lock lock(battleActionMutex);
|
||||||
|
|
||||||
const BattleInfo * b = gs.curB;
|
const BattleInfo * b = gs.curB;
|
||||||
if(!b)
|
if(!b)
|
||||||
gh.throwAndComplain(&pack, "Can not make action - there is no battle ongoing!");
|
gh.throwAndComplain(&pack, "Can not make action - there is no battle ongoing!");
|
||||||
@ -307,6 +311,8 @@ void ApplyGhNetPackVisitor::visitMakeAction(MakeAction & pack)
|
|||||||
|
|
||||||
void ApplyGhNetPackVisitor::visitMakeCustomAction(MakeCustomAction & pack)
|
void ApplyGhNetPackVisitor::visitMakeCustomAction(MakeCustomAction & pack)
|
||||||
{
|
{
|
||||||
|
boost::unique_lock lock(battleActionMutex);
|
||||||
|
|
||||||
const BattleInfo * b = gs.curB;
|
const BattleInfo * b = gs.curB;
|
||||||
if(!b)
|
if(!b)
|
||||||
gh.throwNotAllowedAction(&pack);
|
gh.throwNotAllowedAction(&pack);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user