diff --git a/client/lobby/BattleOnlyMode.cpp b/client/lobby/BattleOnlyMode.cpp index 77b60106b..6439f82f5 100644 --- a/client/lobby/BattleOnlyMode.cpp +++ b/client/lobby/BattleOnlyMode.cpp @@ -140,12 +140,12 @@ BattleOnlyModeWindow::BattleOnlyModeWindow() startInfo->selectedTerrain = TerrainId::DIRT; startInfo->selectedTown = std::nullopt; startInfo->selectedHero[0] = std::nullopt; - startInfo->selectedArmy[0].fill(std::nullopt); + startInfo->selectedArmy[0].fill(CStackBasicDescriptor(CreatureID::NONE, 1)); for(size_t i=0; iselectedArmyInput.at(i)->setText("1"); } startInfo->selectedHero[1] = std::nullopt; - startInfo->selectedArmy[1].fill(std::nullopt); + startInfo->selectedArmy[1].fill(CStackBasicDescriptor(CreatureID::NONE, 1)); for(size_t i=0; iselectedArmyInput.at(i)->setText("1"); onChange(); @@ -204,7 +204,7 @@ void BattleOnlyModeWindow::setTerrainButtonText() void BattleOnlyModeWindow::setOkButtonEnabled() { - bool army2Empty = std::all_of(startInfo->selectedArmy[1].begin(), startInfo->selectedArmy[1].end(), [](const auto x) { return !x; }); + bool army2Empty = std::all_of(startInfo->selectedArmy[1].begin(), startInfo->selectedArmy[1].end(), [](const auto x) { return x.getId() == CreatureID::NONE; }); bool canStart = (startInfo->selectedTerrain || startInfo->selectedTown); canStart &= (startInfo->selectedHero[0] && ((startInfo->selectedHero[1]) || (startInfo->selectedTown && !army2Empty))); @@ -256,9 +256,9 @@ BattleOnlyModeHeroSelector::BattleOnlyModeHeroSelector(int id, BattleOnlyModeWin selectedArmyInput.back()->setFilterNumber(1, 10000000, 3); selectedArmyInput.back()->setText("1"); selectedArmyInput.back()->setCallback([this, i, id](const std::string & text){ - if(parent.startInfo->selectedArmy[id][i]) + if(parent.startInfo->selectedArmy[id][i].getId() != CreatureID::NONE) { - (*parent.startInfo->selectedArmy[id][i]).second = TextOperations::parseMetric(text); + parent.startInfo->selectedArmy[id][i].setCount(TextOperations::parseMetric(text)); parent.onChange(); } else @@ -358,17 +358,17 @@ void BattleOnlyModeHeroSelector::setCreatureIcons() for(int i = 0; i < creatureImage.size(); i++) { - if(!parent.startInfo->selectedArmy[id][i]) + if(parent.startInfo->selectedArmy[id][i].getId() == CreatureID::NONE) { creatureImage[i] = std::make_shared(drawBlackBox(Point(32, 32), LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeSelect"), id == 1 ? Colors::WHITE : parent.disabledColor), Point(6 + i * 36, 78)); selectedArmyInput[i]->setText("1"); } else { - auto unit = (*parent.startInfo->selectedArmy[id][i]); - auto creatureID = unit.first; + auto unit = parent.startInfo->selectedArmy[id][i]; + auto creatureID = unit.getId(); creatureImage[i] = std::make_shared(ENGINE->renderHandler().loadAnimation(AnimationPath::builtin("CPRSMALL"), EImageBlitMode::COLORKEY)->getImage(LIBRARY->creh->objects.at(creatureID)->getIconIndex()), Point(6 + i * 36, 78)); - selectedArmyInput[i]->setText(TextOperations::formatMetric(unit.second, 3)); + selectedArmyInput[i]->setText(TextOperations::formatMetric(unit.getCount(), 3)); } creatureImage[i]->addLClickCallback([this, i](){ @@ -384,8 +384,8 @@ void BattleOnlyModeHeroSelector::setCreatureIcons() return creatureA->getFactionID() < creatureB->getFactionID(); }); - int selectedIndex = !parent.startInfo->selectedArmy[id][i] ? 0 : (1 + std::distance(creatures.begin(), std::find_if(creatures.begin(), creatures.end(), [this, i](auto creatureID) { - return creatureID == (*parent.startInfo->selectedArmy[id][i]).first; + int selectedIndex = parent.startInfo->selectedArmy[id][i].getId() == CreatureID::NONE ? 0 : (1 + std::distance(creatures.begin(), std::find_if(creatures.begin(), creatures.end(), [this, i](auto creatureID) { + return creatureID == parent.startInfo->selectedArmy[id][i].getId(); }))); std::vector texts; @@ -404,15 +404,15 @@ void BattleOnlyModeHeroSelector::setCreatureIcons() auto window = std::make_shared(texts, nullptr, LIBRARY->generaltexth->translate("core.genrltxt.42"), LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeCreatureSelect"), [this, creatures, i](int index){ if(index == 0) { - if(parent.startInfo->selectedArmy[id][i]) - parent.startInfo->selectedArmy[id][i] = std::nullopt; + if(parent.startInfo->selectedArmy[id][i].getId() == CreatureID::NONE) + parent.startInfo->selectedArmy[id][i] = CStackBasicDescriptor(CreatureID::NONE, 1); parent.onChange(); return; } index--; auto creature = creatures.at(index).toCreature(); - parent.startInfo->selectedArmy[id][i] = std::make_pair(creature->getId(), 100); + parent.startInfo->selectedArmy[id][i] = CStackBasicDescriptor(creature->getId(), 100); parent.onChange(); }, selectedIndex, images, true, true); window->onPopup = [creatures](int index) { @@ -426,10 +426,10 @@ void BattleOnlyModeHeroSelector::setCreatureIcons() }); creatureImage[i]->addRClickCallback([this, i](){ - if(!parent.startInfo->selectedArmy[id][i]) + if(parent.startInfo->selectedArmy[id][i].getId() == CreatureID::NONE) return; - ENGINE->windows().createAndPushWindow(LIBRARY->creh->objects.at((*parent.startInfo->selectedArmy[id][i]).first).get(), true); + ENGINE->windows().createAndPushWindow(LIBRARY->creh->objects.at(parent.startInfo->selectedArmy[id][i].getId()).get(), true); }); } } @@ -463,8 +463,8 @@ void BattleOnlyModeWindow::startBattle() obj->pushPrimSkill(PrimarySkill(i), startInfo->primSkillLevel[sel][i]); obj->clearSlots(); for(int slot = 0; slot < GameConstants::ARMY_SIZE; slot++) - if(startInfo->selectedArmy[sel][slot]) - obj->setCreature(SlotID(slot), (*startInfo->selectedArmy[sel][slot]).first, (*startInfo->selectedArmy[sel][slot]).second); + if(startInfo->selectedArmy[sel][slot].getId() != CreatureID::NONE) + obj->setCreature(SlotID(slot), startInfo->selectedArmy[sel][slot].getId(), startInfo->selectedArmy[sel][slot].getCount()); map->getEditManager()->insertObject(obj); }; @@ -484,8 +484,8 @@ void BattleOnlyModeWindow::startBattle() if(!startInfo->selectedHero[1]) { for(int slot = 0; slot < GameConstants::ARMY_SIZE; slot++) - if(startInfo->selectedArmy[1][slot]) - townObj->getArmy()->setCreature(SlotID(slot), (*startInfo->selectedArmy[1][slot]).first, (*startInfo->selectedArmy[1][slot]).second); + if(startInfo->selectedArmy[1][slot].getId() != CreatureID::NONE) + townObj->getArmy()->setCreature(SlotID(slot), startInfo->selectedArmy[1][slot].getId(), startInfo->selectedArmy[1][slot].getCount()); } else addHero(1, PlayerColor(1), int3(5, 5, 0)); diff --git a/lib/StartInfo.h b/lib/StartInfo.h index a80f36f33..0e5720eaa 100644 --- a/lib/StartInfo.h +++ b/lib/StartInfo.h @@ -18,6 +18,7 @@ #include "serializer/GameConnectionID.h" #include "serializer/Serializeable.h" #include "serializer/PlayerConnectionID.h" +#include "mapObjects/army/CStackBasicDescriptor.h" #include "ResourceSet.h" VCMI_LIB_NAMESPACE_BEGIN @@ -246,7 +247,7 @@ public: std::optional selectedTown; std::array, 2> selectedHero; - std::array>, 7>, 2> selectedArmy; + std::array, 2> selectedArmy; std::array, 2> primSkillLevel; diff --git a/lib/texts/TextOperations.h b/lib/texts/TextOperations.h index 34aecb7b6..710352b82 100644 --- a/lib/texts/TextOperations.h +++ b/lib/texts/TextOperations.h @@ -124,7 +124,6 @@ inline std::string TextOperations::formatMetric(Arithmetic number, int maxDigits template inline Arithmetic TextOperations::parseMetric(const std::string &text) { - static const std::string symbols = " kMGTPE"; if (text.empty()) return 0; @@ -163,7 +162,7 @@ inline Arithmetic TextOperations::parseMetric(const std::string &text) try { - Arithmetic value = boost::lexical_cast(numberPart); + Arithmetic value = std::stoll(numberPart); for (int i = 0; i < power; ++i) { @@ -178,7 +177,7 @@ inline Arithmetic TextOperations::parseMetric(const std::string &text) return value; } - catch (boost::bad_lexical_cast &) + catch (std::invalid_argument &) { return 0; }