mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-23 22:37:55 +02:00
code review: big lambdas to function & simplify sort
This commit is contained in:
@@ -97,81 +97,9 @@ BattleOnlyModeTab::BattleOnlyModeTab()
|
|||||||
title = std::make_shared<CLabel>(220, 35, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyMode"));
|
title = std::make_shared<CLabel>(220, 35, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyMode"));
|
||||||
subTitle = std::make_shared<CMultiLineLabel>(Rect(55, 40, 333, 40), FONT_SMALL, ETextAlignment::BOTTOMCENTER, Colors::WHITE, LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeSubTitle"));
|
subTitle = std::make_shared<CMultiLineLabel>(Rect(55, 40, 333, 40), FONT_SMALL, ETextAlignment::BOTTOMCENTER, Colors::WHITE, LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeSubTitle"));
|
||||||
|
|
||||||
battlefieldSelector = std::make_shared<CButton>(Point(57, 552), AnimationPath::builtin("GSPButtonClear"), CButton::tooltip(), [this](){
|
battlefieldSelector = std::make_shared<CButton>(Point(57, 552), AnimationPath::builtin("GSPButtonClear"), CButton::tooltip(), [this](){ selectTerrain(); });
|
||||||
std::vector<std::string> texts;
|
|
||||||
std::vector<std::shared_ptr<IImage>> images;
|
|
||||||
|
|
||||||
std::vector<std::shared_ptr<TerrainType>> terrains;
|
|
||||||
std::copy_if(LIBRARY->terrainTypeHandler->objects.begin(), LIBRARY->terrainTypeHandler->objects.end(), std::back_inserter(terrains), [](auto terrain) { return terrain->isPassable(); });
|
|
||||||
for (const auto & terrain : terrains)
|
|
||||||
{
|
|
||||||
texts.push_back(terrain->getNameTranslated());
|
|
||||||
|
|
||||||
const auto & patterns = LIBRARY->terviewh->getTerrainViewPatterns(terrain->getId());
|
|
||||||
TerrainViewPattern pattern;
|
|
||||||
for(auto & p : patterns)
|
|
||||||
if(p[0].id == "n1")
|
|
||||||
pattern = p[0];
|
|
||||||
auto image = ENGINE->renderHandler().loadImage(terrain->tilesFilename, pattern.mapping[0].first, 0, EImageBlitMode::OPAQUE);
|
|
||||||
image->scaleTo(Point(23, 23), EScalingAlgorithm::NEAREST);
|
|
||||||
images.push_back(image);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto factions = LIBRARY->townh->getDefaultAllowed();
|
|
||||||
for (const auto & faction : factions)
|
|
||||||
{
|
|
||||||
texts.push_back(faction.toFaction()->getNameTranslated());
|
|
||||||
|
|
||||||
auto image = ENGINE->renderHandler().loadImage(AnimationPath::builtin("ITPA"), faction.toFaction()->town->clientInfo.icons[true][false] + 2, 0, EImageBlitMode::OPAQUE);
|
|
||||||
image->scaleTo(Point(35, 23), EScalingAlgorithm::NEAREST);
|
|
||||||
images.push_back(image);
|
|
||||||
}
|
|
||||||
|
|
||||||
ENGINE->windows().createAndPushWindow<CObjectListWindow>(texts, nullptr, LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeBattlefield"), LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeBattlefieldSelect"), [this, terrains, factions](int index){
|
|
||||||
if(terrains.size() > index)
|
|
||||||
{
|
|
||||||
startInfo->selectedTerrain = terrains[index]->getId();
|
|
||||||
startInfo->selectedTown = FactionID::ANY;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
startInfo->selectedTerrain = TerrainId::NONE;
|
|
||||||
auto it = std::next(factions.begin(), index - terrains.size());
|
|
||||||
if (it != factions.end())
|
|
||||||
startInfo->selectedTown = *it;
|
|
||||||
}
|
|
||||||
onChange();
|
|
||||||
}, (startInfo->selectedTerrain != TerrainId::NONE ? static_cast<int>(startInfo->selectedTerrain) : static_cast<int>(startInfo->selectedTown + terrains.size())), images, true, true);
|
|
||||||
});
|
|
||||||
battlefieldSelector->block(GAME->server().isGuest());
|
battlefieldSelector->block(GAME->server().isGuest());
|
||||||
buttonReset = std::make_shared<CButton>(Point(259, 552), AnimationPath::builtin("GSPBUT2"), CButton::tooltip(), [this](){
|
buttonReset = std::make_shared<CButton>(Point(259, 552), AnimationPath::builtin("GSPBUT2"), CButton::tooltip(), [this](){ reset(); });
|
||||||
if(GAME->server().isHost())
|
|
||||||
{
|
|
||||||
startInfo->selectedTerrain = TerrainId::DIRT;
|
|
||||||
startInfo->selectedTown = FactionID::ANY;
|
|
||||||
startInfo->selectedHero[0] = HeroTypeID::NONE;
|
|
||||||
startInfo->selectedArmy[0].fill(CStackBasicDescriptor(CreatureID::NONE, 1));
|
|
||||||
startInfo->secSkillLevel[0].fill(std::make_pair(SecondarySkill::NONE, MasteryLevel::NONE));
|
|
||||||
startInfo->artifacts[0].clear();
|
|
||||||
startInfo->spellBook[0] = true;
|
|
||||||
startInfo->warMachines[0] = false;
|
|
||||||
startInfo->spells[0].clear();
|
|
||||||
for(size_t i=0; i<GameConstants::ARMY_SIZE; i++)
|
|
||||||
heroSelector1->selectedArmyInput.at(i)->disable();
|
|
||||||
for(size_t i=0; i<8; i++)
|
|
||||||
heroSelector1->selectedSecSkillInput.at(i)->disable();
|
|
||||||
}
|
|
||||||
startInfo->selectedHero[1] = HeroTypeID::NONE;
|
|
||||||
startInfo->selectedArmy[1].fill(CStackBasicDescriptor(CreatureID::NONE, 1));
|
|
||||||
startInfo->secSkillLevel[1].fill(std::make_pair(SecondarySkill::NONE, MasteryLevel::NONE));
|
|
||||||
startInfo->artifacts[1].clear();
|
|
||||||
startInfo->spellBook[1] = true;
|
|
||||||
startInfo->warMachines[1] = false;
|
|
||||||
startInfo->spells[1].clear();
|
|
||||||
for(size_t i=0; i<8; i++)
|
|
||||||
heroSelector2->selectedSecSkillInput.at(i)->disable();
|
|
||||||
onChange();
|
|
||||||
});
|
|
||||||
buttonReset->setTextOverlay(LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeReset"), EFonts::FONT_SMALL, Colors::WHITE);
|
buttonReset->setTextOverlay(LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeReset"), EFonts::FONT_SMALL, Colors::WHITE);
|
||||||
|
|
||||||
heroSelector1 = std::make_shared<BattleOnlyModeHeroSelector>(0, *this, Point(55, 90));
|
heroSelector1 = std::make_shared<BattleOnlyModeHeroSelector>(0, *this, Point(55, 90));
|
||||||
@@ -182,6 +110,84 @@ BattleOnlyModeTab::BattleOnlyModeTab()
|
|||||||
onChange();
|
onChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BattleOnlyModeTab::reset()
|
||||||
|
{
|
||||||
|
if(GAME->server().isHost())
|
||||||
|
{
|
||||||
|
startInfo->selectedTerrain = TerrainId::DIRT;
|
||||||
|
startInfo->selectedTown = FactionID::ANY;
|
||||||
|
startInfo->selectedHero[0] = HeroTypeID::NONE;
|
||||||
|
startInfo->selectedArmy[0].fill(CStackBasicDescriptor(CreatureID::NONE, 1));
|
||||||
|
startInfo->secSkillLevel[0].fill(std::make_pair(SecondarySkill::NONE, MasteryLevel::NONE));
|
||||||
|
startInfo->artifacts[0].clear();
|
||||||
|
startInfo->spellBook[0] = true;
|
||||||
|
startInfo->warMachines[0] = false;
|
||||||
|
startInfo->spells[0].clear();
|
||||||
|
for(size_t i=0; i<GameConstants::ARMY_SIZE; i++)
|
||||||
|
heroSelector1->selectedArmyInput.at(i)->disable();
|
||||||
|
for(size_t i=0; i<8; i++)
|
||||||
|
heroSelector1->selectedSecSkillInput.at(i)->disable();
|
||||||
|
}
|
||||||
|
startInfo->selectedHero[1] = HeroTypeID::NONE;
|
||||||
|
startInfo->selectedArmy[1].fill(CStackBasicDescriptor(CreatureID::NONE, 1));
|
||||||
|
startInfo->secSkillLevel[1].fill(std::make_pair(SecondarySkill::NONE, MasteryLevel::NONE));
|
||||||
|
startInfo->artifacts[1].clear();
|
||||||
|
startInfo->spellBook[1] = true;
|
||||||
|
startInfo->warMachines[1] = false;
|
||||||
|
startInfo->spells[1].clear();
|
||||||
|
for(size_t i=0; i<8; i++)
|
||||||
|
heroSelector2->selectedSecSkillInput.at(i)->disable();
|
||||||
|
onChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BattleOnlyModeTab::selectTerrain()
|
||||||
|
{
|
||||||
|
std::vector<std::string> texts;
|
||||||
|
std::vector<std::shared_ptr<IImage>> images;
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<TerrainType>> terrains;
|
||||||
|
std::copy_if(LIBRARY->terrainTypeHandler->objects.begin(), LIBRARY->terrainTypeHandler->objects.end(), std::back_inserter(terrains), [](auto terrain) { return terrain->isPassable(); });
|
||||||
|
for (const auto & terrain : terrains)
|
||||||
|
{
|
||||||
|
texts.push_back(terrain->getNameTranslated());
|
||||||
|
|
||||||
|
const auto & patterns = LIBRARY->terviewh->getTerrainViewPatterns(terrain->getId());
|
||||||
|
TerrainViewPattern pattern;
|
||||||
|
for(auto & p : patterns)
|
||||||
|
if(p[0].id == "n1")
|
||||||
|
pattern = p[0];
|
||||||
|
auto image = ENGINE->renderHandler().loadImage(terrain->tilesFilename, pattern.mapping[0].first, 0, EImageBlitMode::OPAQUE);
|
||||||
|
image->scaleTo(Point(23, 23), EScalingAlgorithm::NEAREST);
|
||||||
|
images.push_back(image);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto factions = LIBRARY->townh->getDefaultAllowed();
|
||||||
|
for (const auto & faction : factions)
|
||||||
|
{
|
||||||
|
texts.push_back(faction.toFaction()->getNameTranslated());
|
||||||
|
|
||||||
|
auto image = ENGINE->renderHandler().loadImage(AnimationPath::builtin("ITPA"), faction.toFaction()->town->clientInfo.icons[true][false] + 2, 0, EImageBlitMode::OPAQUE);
|
||||||
|
image->scaleTo(Point(35, 23), EScalingAlgorithm::NEAREST);
|
||||||
|
images.push_back(image);
|
||||||
|
}
|
||||||
|
|
||||||
|
ENGINE->windows().createAndPushWindow<CObjectListWindow>(texts, nullptr, LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeBattlefield"), LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeBattlefieldSelect"), [this, terrains, factions](int index){
|
||||||
|
if(terrains.size() > index)
|
||||||
|
{
|
||||||
|
startInfo->selectedTerrain = terrains[index]->getId();
|
||||||
|
startInfo->selectedTown = FactionID::ANY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
startInfo->selectedTerrain = TerrainId::NONE;
|
||||||
|
auto it = std::next(factions.begin(), index - terrains.size());
|
||||||
|
if (it != factions.end())
|
||||||
|
startInfo->selectedTown = *it;
|
||||||
|
}
|
||||||
|
onChange();
|
||||||
|
}, (startInfo->selectedTerrain != TerrainId::NONE ? static_cast<int>(startInfo->selectedTerrain) : static_cast<int>(startInfo->selectedTown + terrains.size())), images, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
void BattleOnlyModeTab::init()
|
void BattleOnlyModeTab::init()
|
||||||
{
|
{
|
||||||
map = std::make_unique<CMap>(nullptr);
|
map = std::make_unique<CMap>(nullptr);
|
||||||
@@ -389,10 +395,8 @@ void BattleOnlyModeHeroSelector::manageSpells()
|
|||||||
std::sort(allSpells.begin(), allSpells.end(), [](auto a, auto b) {
|
std::sort(allSpells.begin(), allSpells.end(), [](auto a, auto b) {
|
||||||
auto A = a.toSpell();
|
auto A = a.toSpell();
|
||||||
auto B = b.toSpell();
|
auto B = b.toSpell();
|
||||||
if(A->getLevel() < B->getLevel())
|
if(A->getLevel() != B->getLevel())
|
||||||
return true;
|
return A->getLevel() < B->getLevel();
|
||||||
if(A->getLevel() > B->getLevel())
|
|
||||||
return false;
|
|
||||||
for (const auto schoolId : LIBRARY->spellSchoolHandler->getAllObjects())
|
for (const auto schoolId : LIBRARY->spellSchoolHandler->getAllObjects())
|
||||||
{
|
{
|
||||||
if(A->schools.count(schoolId) && !B->schools.count(schoolId))
|
if(A->schools.count(schoolId) && !B->schools.count(schoolId))
|
||||||
@@ -458,6 +462,71 @@ void BattleOnlyModeHeroSelector::manageSpells()
|
|||||||
ENGINE->windows().pushWindow(temp);
|
ENGINE->windows().pushWindow(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BattleOnlyModeHeroSelector::selectHero()
|
||||||
|
{
|
||||||
|
auto allowedSet = LIBRARY->heroh->getDefaultAllowed();
|
||||||
|
std::vector<HeroTypeID> heroes(allowedSet.begin(), allowedSet.end());
|
||||||
|
std::sort(heroes.begin(), heroes.end(), [](auto a, auto b) {
|
||||||
|
auto heroA = a.toHeroType();
|
||||||
|
auto heroB = b.toHeroType();
|
||||||
|
if(heroA->heroClass->faction != heroB->heroClass->faction)
|
||||||
|
return heroA->heroClass->faction < heroB->heroClass->faction;
|
||||||
|
if(heroA->heroClass->getId() != heroB->heroClass->getId())
|
||||||
|
return heroA->heroClass->getId() < heroB->heroClass->getId();
|
||||||
|
return heroA->getNameTranslated() < heroB->getNameTranslated();
|
||||||
|
});
|
||||||
|
|
||||||
|
int selectedIndex = parent.startInfo->selectedHero[id] == HeroTypeID::NONE ? 0 : (1 + std::distance(heroes.begin(), std::find_if(heroes.begin(), heroes.end(), [this](auto heroID) {
|
||||||
|
return heroID == parent.startInfo->selectedHero[id];
|
||||||
|
})));
|
||||||
|
|
||||||
|
std::vector<std::string> texts;
|
||||||
|
std::vector<std::shared_ptr<IImage>> images;
|
||||||
|
// Add "no hero" option
|
||||||
|
texts.push_back(LIBRARY->generaltexth->translate("core.genrltxt.507"));
|
||||||
|
images.push_back(nullptr);
|
||||||
|
for (const auto & h : heroes)
|
||||||
|
{
|
||||||
|
texts.push_back(h.toHeroType()->getNameTranslated());
|
||||||
|
|
||||||
|
auto image = ENGINE->renderHandler().loadImage(AnimationPath::builtin("PortraitsSmall"), h.toHeroType()->imageIndex, 0, EImageBlitMode::OPAQUE);
|
||||||
|
image->scaleTo(Point(35, 23), EScalingAlgorithm::NEAREST);
|
||||||
|
images.push_back(image);
|
||||||
|
}
|
||||||
|
auto window = std::make_shared<CObjectListWindow>(texts, nullptr, LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeHeroSelect"), LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeHeroSelect"), [this, heroes](int index){
|
||||||
|
if(index == 0)
|
||||||
|
{
|
||||||
|
parent.startInfo->selectedHero[id] = HeroTypeID::NONE;
|
||||||
|
parent.onChange();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
index--;
|
||||||
|
|
||||||
|
parent.startInfo->selectedHero[id] = heroes[index];
|
||||||
|
|
||||||
|
for(size_t i=0; i<GameConstants::PRIMARY_SKILLS; i++)
|
||||||
|
parent.startInfo->primSkillLevel[id][i] = heroes[index].toHeroType()->heroClass->primarySkillInitial[i];
|
||||||
|
|
||||||
|
for(size_t i=0; i<8; i++)
|
||||||
|
if(heroes[index].toHeroType()->secSkillsInit.size() > i)
|
||||||
|
parent.startInfo->secSkillLevel[id][i] = std::make_pair(heroes[index].toHeroType()->secSkillsInit[i].first, MasteryLevel::Type(heroes[index].toHeroType()->secSkillsInit[i].second));
|
||||||
|
else
|
||||||
|
parent.startInfo->secSkillLevel[id][i] = std::make_pair(SecondarySkill::NONE, MasteryLevel::NONE);
|
||||||
|
|
||||||
|
parent.startInfo->spellBook[id] = heroes[index].toHeroType()->haveSpellBook;
|
||||||
|
|
||||||
|
parent.onChange();
|
||||||
|
}, selectedIndex, images, true, true);
|
||||||
|
window->onPopup = [heroes](int index) {
|
||||||
|
if(index == 0)
|
||||||
|
return;
|
||||||
|
index--;
|
||||||
|
|
||||||
|
ENGINE->windows().createAndPushWindow<CHeroOverview>(heroes.at(index));
|
||||||
|
};
|
||||||
|
ENGINE->windows().pushWindow(window);
|
||||||
|
}
|
||||||
|
|
||||||
void BattleOnlyModeHeroSelector::setHeroIcon()
|
void BattleOnlyModeHeroSelector::setHeroIcon()
|
||||||
{
|
{
|
||||||
OBJECT_CONSTRUCTION;
|
OBJECT_CONSTRUCTION;
|
||||||
@@ -477,69 +546,7 @@ void BattleOnlyModeHeroSelector::setHeroIcon()
|
|||||||
primSkillsInput[i]->setText(std::to_string(parent.startInfo->primSkillLevel[id][i]));
|
primSkillsInput[i]->setText(std::to_string(parent.startInfo->primSkillLevel[id][i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
heroImage->addLClickCallback([this](){
|
heroImage->addLClickCallback([this](){ selectHero(); });
|
||||||
auto allowedSet = LIBRARY->heroh->getDefaultAllowed();
|
|
||||||
std::vector<HeroTypeID> heroes(allowedSet.begin(), allowedSet.end());
|
|
||||||
std::sort(heroes.begin(), heroes.end(), [](auto a, auto b) {
|
|
||||||
auto heroA = a.toHeroType();
|
|
||||||
auto heroB = b.toHeroType();
|
|
||||||
if(heroA->heroClass->faction != heroB->heroClass->faction)
|
|
||||||
return heroA->heroClass->faction < heroB->heroClass->faction;
|
|
||||||
if(heroA->heroClass->getId() != heroB->heroClass->getId())
|
|
||||||
return heroA->heroClass->getId() < heroB->heroClass->getId();
|
|
||||||
return heroA->getNameTranslated() < heroB->getNameTranslated();
|
|
||||||
});
|
|
||||||
|
|
||||||
int selectedIndex = parent.startInfo->selectedHero[id] == HeroTypeID::NONE ? 0 : (1 + std::distance(heroes.begin(), std::find_if(heroes.begin(), heroes.end(), [this](auto heroID) {
|
|
||||||
return heroID == parent.startInfo->selectedHero[id];
|
|
||||||
})));
|
|
||||||
|
|
||||||
std::vector<std::string> texts;
|
|
||||||
std::vector<std::shared_ptr<IImage>> images;
|
|
||||||
// Add "no hero" option
|
|
||||||
texts.push_back(LIBRARY->generaltexth->translate("core.genrltxt.507"));
|
|
||||||
images.push_back(nullptr);
|
|
||||||
for (const auto & h : heroes)
|
|
||||||
{
|
|
||||||
texts.push_back(h.toHeroType()->getNameTranslated());
|
|
||||||
|
|
||||||
auto image = ENGINE->renderHandler().loadImage(AnimationPath::builtin("PortraitsSmall"), h.toHeroType()->imageIndex, 0, EImageBlitMode::OPAQUE);
|
|
||||||
image->scaleTo(Point(35, 23), EScalingAlgorithm::NEAREST);
|
|
||||||
images.push_back(image);
|
|
||||||
}
|
|
||||||
auto window = std::make_shared<CObjectListWindow>(texts, nullptr, LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeHeroSelect"), LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeHeroSelect"), [this, heroes](int index){
|
|
||||||
if(index == 0)
|
|
||||||
{
|
|
||||||
parent.startInfo->selectedHero[id] = HeroTypeID::NONE;
|
|
||||||
parent.onChange();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
index--;
|
|
||||||
|
|
||||||
parent.startInfo->selectedHero[id] = heroes[index];
|
|
||||||
|
|
||||||
for(size_t i=0; i<GameConstants::PRIMARY_SKILLS; i++)
|
|
||||||
parent.startInfo->primSkillLevel[id][i] = heroes[index].toHeroType()->heroClass->primarySkillInitial[i];
|
|
||||||
|
|
||||||
for(size_t i=0; i<8; i++)
|
|
||||||
if(heroes[index].toHeroType()->secSkillsInit.size() > i)
|
|
||||||
parent.startInfo->secSkillLevel[id][i] = std::make_pair(heroes[index].toHeroType()->secSkillsInit[i].first, MasteryLevel::Type(heroes[index].toHeroType()->secSkillsInit[i].second));
|
|
||||||
else
|
|
||||||
parent.startInfo->secSkillLevel[id][i] = std::make_pair(SecondarySkill::NONE, MasteryLevel::NONE);
|
|
||||||
|
|
||||||
parent.startInfo->spellBook[id] = heroes[index].toHeroType()->haveSpellBook;
|
|
||||||
|
|
||||||
parent.onChange();
|
|
||||||
}, selectedIndex, images, true, true);
|
|
||||||
window->onPopup = [heroes](int index) {
|
|
||||||
if(index == 0)
|
|
||||||
return;
|
|
||||||
index--;
|
|
||||||
|
|
||||||
ENGINE->windows().createAndPushWindow<CHeroOverview>(heroes.at(index));
|
|
||||||
};
|
|
||||||
ENGINE->windows().pushWindow(window);
|
|
||||||
});
|
|
||||||
|
|
||||||
heroImage->addRClickCallback([this](){
|
heroImage->addRClickCallback([this](){
|
||||||
if(parent.startInfo->selectedHero[id] == HeroTypeID::NONE)
|
if(parent.startInfo->selectedHero[id] == HeroTypeID::NONE)
|
||||||
@@ -549,6 +556,64 @@ void BattleOnlyModeHeroSelector::setHeroIcon()
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BattleOnlyModeHeroSelector::selectCreature(int slot)
|
||||||
|
{
|
||||||
|
auto allowedSet = LIBRARY->creh->getDefaultAllowed();
|
||||||
|
std::vector<CreatureID> creatures(allowedSet.begin(), allowedSet.end());
|
||||||
|
std::sort(creatures.begin(), creatures.end(), [](auto a, auto b) {
|
||||||
|
auto creatureA = a.toCreature();
|
||||||
|
auto creatureB = b.toCreature();
|
||||||
|
if ((creatureA->getFactionID() == FactionID::NEUTRAL) != (creatureB->getFactionID() == FactionID::NEUTRAL))
|
||||||
|
return creatureA->getFactionID() != FactionID::NEUTRAL;
|
||||||
|
if(creatureA->getFactionID() != creatureB->getFactionID())
|
||||||
|
return creatureA->getFactionID() < creatureB->getFactionID();
|
||||||
|
if(creatureA->getLevel() != creatureB->getLevel())
|
||||||
|
return creatureA->getLevel() < creatureB->getLevel();
|
||||||
|
if(creatureA->upgrades.size() != creatureB->upgrades.size())
|
||||||
|
return creatureA->upgrades.size() > creatureB->upgrades.size();
|
||||||
|
return creatureA->getNameSingularTranslated() < creatureB->getNameSingularTranslated();
|
||||||
|
});
|
||||||
|
|
||||||
|
int selectedIndex = parent.startInfo->selectedArmy[id][slot].getId() == CreatureID::NONE ? 0 : (1 + std::distance(creatures.begin(), std::find_if(creatures.begin(), creatures.end(), [this, slot](auto creatureID) {
|
||||||
|
return creatureID == parent.startInfo->selectedArmy[id][slot].getId();
|
||||||
|
})));
|
||||||
|
|
||||||
|
std::vector<std::string> texts;
|
||||||
|
std::vector<std::shared_ptr<IImage>> images;
|
||||||
|
// Add "no creature" option
|
||||||
|
texts.push_back(LIBRARY->generaltexth->translate("core.genrltxt.507"));
|
||||||
|
images.push_back(nullptr);
|
||||||
|
for (const auto & c : creatures)
|
||||||
|
{
|
||||||
|
texts.push_back(c.toCreature()->getNameSingularTranslated());
|
||||||
|
|
||||||
|
auto image = ENGINE->renderHandler().loadImage(AnimationPath::builtin("CPRSMALL"), c.toCreature()->getIconIndex(), 0, EImageBlitMode::OPAQUE);
|
||||||
|
image->scaleTo(Point(23, 23), EScalingAlgorithm::NEAREST);
|
||||||
|
images.push_back(image);
|
||||||
|
}
|
||||||
|
auto window = std::make_shared<CObjectListWindow>(texts, nullptr, LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeCreatureSelect"), LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeCreatureSelect"), [this, creatures, slot](int index){
|
||||||
|
if(index == 0)
|
||||||
|
{
|
||||||
|
parent.startInfo->selectedArmy[id][slot] = CStackBasicDescriptor(CreatureID::NONE, 1);
|
||||||
|
parent.onChange();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
index--;
|
||||||
|
|
||||||
|
auto creature = creatures.at(index).toCreature();
|
||||||
|
parent.startInfo->selectedArmy[id][slot] = CStackBasicDescriptor(creature->getId(), 100);
|
||||||
|
parent.onChange();
|
||||||
|
}, selectedIndex, images, true, true);
|
||||||
|
window->onPopup = [creatures](int index) {
|
||||||
|
if(index == 0)
|
||||||
|
return;
|
||||||
|
index--;
|
||||||
|
|
||||||
|
ENGINE->windows().createAndPushWindow<CStackWindow>(creatures.at(index).toCreature(), true);
|
||||||
|
};
|
||||||
|
ENGINE->windows().pushWindow(window);
|
||||||
|
}
|
||||||
|
|
||||||
void BattleOnlyModeHeroSelector::setCreatureIcons()
|
void BattleOnlyModeHeroSelector::setCreatureIcons()
|
||||||
{
|
{
|
||||||
OBJECT_CONSTRUCTION;
|
OBJECT_CONSTRUCTION;
|
||||||
@@ -572,62 +637,7 @@ void BattleOnlyModeHeroSelector::setCreatureIcons()
|
|||||||
selectedArmyInput[i]->enable();
|
selectedArmyInput[i]->enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
creatureImage[i]->addLClickCallback([this, i](){
|
creatureImage[i]->addLClickCallback([this, i](){ selectCreature(i); });
|
||||||
auto allowedSet = LIBRARY->creh->getDefaultAllowed();
|
|
||||||
std::vector<CreatureID> creatures(allowedSet.begin(), allowedSet.end());
|
|
||||||
std::sort(creatures.begin(), creatures.end(), [](auto a, auto b) {
|
|
||||||
auto creatureA = a.toCreature();
|
|
||||||
auto creatureB = b.toCreature();
|
|
||||||
if ((creatureA->getFactionID() == FactionID::NEUTRAL) != (creatureB->getFactionID() == FactionID::NEUTRAL))
|
|
||||||
return creatureA->getFactionID() != FactionID::NEUTRAL;
|
|
||||||
if(creatureA->getFactionID() != creatureB->getFactionID())
|
|
||||||
return creatureA->getFactionID() < creatureB->getFactionID();
|
|
||||||
if(creatureA->getLevel() != creatureB->getLevel())
|
|
||||||
return creatureA->getLevel() < creatureB->getLevel();
|
|
||||||
if(creatureA->upgrades.size() != creatureB->upgrades.size())
|
|
||||||
return creatureA->upgrades.size() > creatureB->upgrades.size();
|
|
||||||
return creatureA->getNameSingularTranslated() < creatureB->getNameSingularTranslated();
|
|
||||||
});
|
|
||||||
|
|
||||||
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<std::string> texts;
|
|
||||||
std::vector<std::shared_ptr<IImage>> images;
|
|
||||||
// Add "no creature" option
|
|
||||||
texts.push_back(LIBRARY->generaltexth->translate("core.genrltxt.507"));
|
|
||||||
images.push_back(nullptr);
|
|
||||||
for (const auto & c : creatures)
|
|
||||||
{
|
|
||||||
texts.push_back(c.toCreature()->getNameSingularTranslated());
|
|
||||||
|
|
||||||
auto image = ENGINE->renderHandler().loadImage(AnimationPath::builtin("CPRSMALL"), c.toCreature()->getIconIndex(), 0, EImageBlitMode::OPAQUE);
|
|
||||||
image->scaleTo(Point(23, 23), EScalingAlgorithm::NEAREST);
|
|
||||||
images.push_back(image);
|
|
||||||
}
|
|
||||||
auto window = std::make_shared<CObjectListWindow>(texts, nullptr, LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeCreatureSelect"), LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeCreatureSelect"), [this, creatures, i](int index){
|
|
||||||
if(index == 0)
|
|
||||||
{
|
|
||||||
parent.startInfo->selectedArmy[id][i] = CStackBasicDescriptor(CreatureID::NONE, 1);
|
|
||||||
parent.onChange();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
index--;
|
|
||||||
|
|
||||||
auto creature = creatures.at(index).toCreature();
|
|
||||||
parent.startInfo->selectedArmy[id][i] = CStackBasicDescriptor(creature->getId(), 100);
|
|
||||||
parent.onChange();
|
|
||||||
}, selectedIndex, images, true, true);
|
|
||||||
window->onPopup = [creatures](int index) {
|
|
||||||
if(index == 0)
|
|
||||||
return;
|
|
||||||
index--;
|
|
||||||
|
|
||||||
ENGINE->windows().createAndPushWindow<CStackWindow>(creatures.at(index).toCreature(), true);
|
|
||||||
};
|
|
||||||
ENGINE->windows().pushWindow(window);
|
|
||||||
});
|
|
||||||
|
|
||||||
creatureImage[i]->addRClickCallback([this, i](){
|
creatureImage[i]->addRClickCallback([this, i](){
|
||||||
if(parent.startInfo->selectedArmy[id][i].getId() == CreatureID::NONE)
|
if(parent.startInfo->selectedArmy[id][i].getId() == CreatureID::NONE)
|
||||||
@@ -638,6 +648,71 @@ void BattleOnlyModeHeroSelector::setCreatureIcons()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BattleOnlyModeHeroSelector::selectSecSkill(int slot)
|
||||||
|
{
|
||||||
|
auto allowedSet = LIBRARY->skillh->getDefaultAllowed();
|
||||||
|
std::vector<SecondarySkill> skills(allowedSet.begin(), allowedSet.end());
|
||||||
|
skills.erase( // remove already added skills from selection
|
||||||
|
std::remove_if(
|
||||||
|
skills.begin(),
|
||||||
|
skills.end(),
|
||||||
|
[this, slot](auto & skill) {
|
||||||
|
return std::any_of(
|
||||||
|
parent.startInfo->secSkillLevel[id].begin(), parent.startInfo->secSkillLevel[id].end(),
|
||||||
|
[&skill](auto & s) { return s.first == skill; }
|
||||||
|
) && parent.startInfo->secSkillLevel[id][slot].first != skill;
|
||||||
|
}
|
||||||
|
),
|
||||||
|
skills.end()
|
||||||
|
);
|
||||||
|
std::sort(skills.begin(), skills.end(), [](auto a, auto b) {
|
||||||
|
auto skillA = a.toSkill();
|
||||||
|
auto skillB = b.toSkill();
|
||||||
|
return skillA->getNameTranslated() < skillB->getNameTranslated();
|
||||||
|
});
|
||||||
|
|
||||||
|
int selectedIndex = parent.startInfo->secSkillLevel[id][slot].second == MasteryLevel::NONE ? 0 : (1 + std::distance(skills.begin(), std::find_if(skills.begin(), skills.end(), [this, slot](auto skillID) {
|
||||||
|
return skillID == parent.startInfo->secSkillLevel[id][slot].first;
|
||||||
|
})));
|
||||||
|
|
||||||
|
std::vector<std::string> texts;
|
||||||
|
std::vector<std::shared_ptr<IImage>> images;
|
||||||
|
// Add "no skill" option
|
||||||
|
texts.push_back(LIBRARY->generaltexth->translate("core.genrltxt.507"));
|
||||||
|
images.push_back(nullptr);
|
||||||
|
for (const auto & c : skills)
|
||||||
|
{
|
||||||
|
texts.push_back(c.toSkill()->getNameTranslated());
|
||||||
|
|
||||||
|
auto image = ENGINE->renderHandler().loadImage(AnimationPath::builtin("SECSK32"), c.toSkill()->getIconIndex(0), 0, EImageBlitMode::OPAQUE);
|
||||||
|
image->scaleTo(Point(23, 23), EScalingAlgorithm::NEAREST);
|
||||||
|
images.push_back(image);
|
||||||
|
}
|
||||||
|
auto window = std::make_shared<CObjectListWindow>(texts, nullptr, LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeSecSkillSelect"), LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeSecSkillSelect"), [this, skills, slot](int index){
|
||||||
|
if(index == 0)
|
||||||
|
{
|
||||||
|
parent.startInfo->secSkillLevel[id][slot] = std::make_pair(SecondarySkill::NONE, MasteryLevel::NONE);
|
||||||
|
parent.onChange();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
index--;
|
||||||
|
|
||||||
|
auto skill = skills.at(index).toSkill();
|
||||||
|
parent.startInfo->secSkillLevel[id][slot] = std::make_pair(skill->getId(), MasteryLevel::EXPERT);
|
||||||
|
parent.onChange();
|
||||||
|
}, selectedIndex, images, true, true);
|
||||||
|
window->onPopup = [skills](int index) {
|
||||||
|
if(index == 0)
|
||||||
|
return;
|
||||||
|
index--;
|
||||||
|
|
||||||
|
auto skillId = skills.at(index);
|
||||||
|
std::shared_ptr<CComponent> comp = std::make_shared<CComponent>(ComponentType::SEC_SKILL, skillId, MasteryLevel::EXPERT);
|
||||||
|
CRClickPopup::createAndPush(skillId.toSkill()->getDescriptionTranslated(MasteryLevel::EXPERT), CInfoWindow::TCompsInfo(1, comp));
|
||||||
|
};
|
||||||
|
ENGINE->windows().pushWindow(window);
|
||||||
|
}
|
||||||
|
|
||||||
void BattleOnlyModeHeroSelector::setSecSkillIcons()
|
void BattleOnlyModeHeroSelector::setSecSkillIcons()
|
||||||
{
|
{
|
||||||
OBJECT_CONSTRUCTION;
|
OBJECT_CONSTRUCTION;
|
||||||
@@ -663,69 +738,7 @@ void BattleOnlyModeHeroSelector::setSecSkillIcons()
|
|||||||
selectedSecSkillInput[i]->enable();
|
selectedSecSkillInput[i]->enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
secSkillImage[i]->addLClickCallback([this, i](){
|
secSkillImage[i]->addLClickCallback([this, i](){ selectSecSkill(i); });
|
||||||
auto allowedSet = LIBRARY->skillh->getDefaultAllowed();
|
|
||||||
std::vector<SecondarySkill> skills(allowedSet.begin(), allowedSet.end());
|
|
||||||
skills.erase( // remove already added skills from selection
|
|
||||||
std::remove_if(
|
|
||||||
skills.begin(),
|
|
||||||
skills.end(),
|
|
||||||
[this, i](auto & skill) {
|
|
||||||
return std::any_of(
|
|
||||||
parent.startInfo->secSkillLevel[id].begin(), parent.startInfo->secSkillLevel[id].end(),
|
|
||||||
[&skill](auto & s) { return s.first == skill; }
|
|
||||||
) && parent.startInfo->secSkillLevel[id][i].first != skill;
|
|
||||||
}
|
|
||||||
),
|
|
||||||
skills.end()
|
|
||||||
);
|
|
||||||
std::sort(skills.begin(), skills.end(), [](auto a, auto b) {
|
|
||||||
auto skillA = a.toSkill();
|
|
||||||
auto skillB = b.toSkill();
|
|
||||||
return skillA->getNameTranslated() < skillB->getNameTranslated();
|
|
||||||
});
|
|
||||||
|
|
||||||
int selectedIndex = parent.startInfo->secSkillLevel[id][i].second == MasteryLevel::NONE ? 0 : (1 + std::distance(skills.begin(), std::find_if(skills.begin(), skills.end(), [this, i](auto skillID) {
|
|
||||||
return skillID == parent.startInfo->secSkillLevel[id][i].first;
|
|
||||||
})));
|
|
||||||
|
|
||||||
std::vector<std::string> texts;
|
|
||||||
std::vector<std::shared_ptr<IImage>> images;
|
|
||||||
// Add "no skill" option
|
|
||||||
texts.push_back(LIBRARY->generaltexth->translate("core.genrltxt.507"));
|
|
||||||
images.push_back(nullptr);
|
|
||||||
for (const auto & c : skills)
|
|
||||||
{
|
|
||||||
texts.push_back(c.toSkill()->getNameTranslated());
|
|
||||||
|
|
||||||
auto image = ENGINE->renderHandler().loadImage(AnimationPath::builtin("SECSK32"), c.toSkill()->getIconIndex(0), 0, EImageBlitMode::OPAQUE);
|
|
||||||
image->scaleTo(Point(23, 23), EScalingAlgorithm::NEAREST);
|
|
||||||
images.push_back(image);
|
|
||||||
}
|
|
||||||
auto window = std::make_shared<CObjectListWindow>(texts, nullptr, LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeSecSkillSelect"), LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeSecSkillSelect"), [this, skills, i](int index){
|
|
||||||
if(index == 0)
|
|
||||||
{
|
|
||||||
parent.startInfo->secSkillLevel[id][i] = std::make_pair(SecondarySkill::NONE, MasteryLevel::NONE);
|
|
||||||
parent.onChange();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
index--;
|
|
||||||
|
|
||||||
auto skill = skills.at(index).toSkill();
|
|
||||||
parent.startInfo->secSkillLevel[id][i] = std::make_pair(skill->getId(), MasteryLevel::EXPERT);
|
|
||||||
parent.onChange();
|
|
||||||
}, selectedIndex, images, true, true);
|
|
||||||
window->onPopup = [skills](int index) {
|
|
||||||
if(index == 0)
|
|
||||||
return;
|
|
||||||
index--;
|
|
||||||
|
|
||||||
auto skillId = skills.at(index);
|
|
||||||
std::shared_ptr<CComponent> comp = std::make_shared<CComponent>(ComponentType::SEC_SKILL, skillId, MasteryLevel::EXPERT);
|
|
||||||
CRClickPopup::createAndPush(skillId.toSkill()->getDescriptionTranslated(MasteryLevel::EXPERT), CInfoWindow::TCompsInfo(1, comp));
|
|
||||||
};
|
|
||||||
ENGINE->windows().pushWindow(window);
|
|
||||||
});
|
|
||||||
|
|
||||||
secSkillImage[i]->addRClickCallback([this, i](){
|
secSkillImage[i]->addRClickCallback([this, i](){
|
||||||
auto skillId = parent.startInfo->secSkillLevel[id][i].first;
|
auto skillId = parent.startInfo->secSkillLevel[id][i].first;
|
||||||
@@ -740,15 +753,91 @@ void BattleOnlyModeHeroSelector::setSecSkillIcons()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<ArtifactPosition> getArtPos()
|
||||||
|
{
|
||||||
|
std::vector<ArtifactPosition> artPos = {
|
||||||
|
ArtifactPosition::HEAD, ArtifactPosition::SHOULDERS, ArtifactPosition::NECK, ArtifactPosition::RIGHT_HAND, ArtifactPosition::LEFT_HAND, ArtifactPosition::TORSO, ArtifactPosition::FEET,
|
||||||
|
ArtifactPosition::RIGHT_RING, ArtifactPosition::LEFT_RING, ArtifactPosition::MISC1, ArtifactPosition::MISC2, ArtifactPosition::MISC3, ArtifactPosition::MISC4, ArtifactPosition::MISC5
|
||||||
|
};
|
||||||
|
return artPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BattleOnlyModeHeroSelector::selectArtifact(int slot, ArtifactID artifactId)
|
||||||
|
{
|
||||||
|
auto artPos = getArtPos();
|
||||||
|
|
||||||
|
auto allowedSet = LIBRARY->arth->getDefaultAllowed();
|
||||||
|
std::vector<ArtifactID> artifacts(allowedSet.begin(), allowedSet.end());
|
||||||
|
artifacts.erase( // remove already added and not for that slot allowed artifacts from selection
|
||||||
|
std::remove_if(
|
||||||
|
artifacts.begin(),
|
||||||
|
artifacts.end(),
|
||||||
|
[this, slot, artPos](auto & artifact) {
|
||||||
|
auto possibleSlots = artifact.toArtifact()->getPossibleSlots();
|
||||||
|
std::vector<ArtifactPosition> allowedSlots;
|
||||||
|
if(possibleSlots.find(ArtBearer::HERO) != possibleSlots.end() && !possibleSlots.at(ArtBearer::HERO).empty())
|
||||||
|
allowedSlots = possibleSlots.at(ArtBearer::HERO);
|
||||||
|
|
||||||
|
return (std::any_of(parent.startInfo->artifacts[id].begin(), parent.startInfo->artifacts[id].end(), [&artifact](auto & a) {return a.second == artifact;})
|
||||||
|
&& parent.startInfo->artifacts[id][artPos[slot]] != artifact)
|
||||||
|
|| !std::any_of(allowedSlots.begin(), allowedSlots.end(), [slot, artPos](auto & p){ return p == artPos[slot]; });
|
||||||
|
}
|
||||||
|
),
|
||||||
|
artifacts.end()
|
||||||
|
);
|
||||||
|
std::sort(artifacts.begin(), artifacts.end(), [](auto a, auto b) {
|
||||||
|
auto artifactA = a.toArtifact();
|
||||||
|
auto artifactB = b.toArtifact();
|
||||||
|
return artifactA->getNameTranslated() < artifactB->getNameTranslated();
|
||||||
|
});
|
||||||
|
|
||||||
|
int selectedIndex = artifactId == ArtifactID::NONE ? 0 : (1 + std::distance(artifacts.begin(), std::find_if(artifacts.begin(), artifacts.end(), [artifactId](auto artID) {
|
||||||
|
return artID == artifactId;
|
||||||
|
})));
|
||||||
|
|
||||||
|
std::vector<std::string> texts;
|
||||||
|
std::vector<std::shared_ptr<IImage>> images;
|
||||||
|
// Add "no artifact" option
|
||||||
|
texts.push_back(LIBRARY->generaltexth->translate("core.genrltxt.507"));
|
||||||
|
images.push_back(nullptr);
|
||||||
|
for (const auto & a : artifacts)
|
||||||
|
{
|
||||||
|
texts.push_back(a.toArtifact()->getNameTranslated());
|
||||||
|
|
||||||
|
auto image = ENGINE->renderHandler().loadImage(AnimationPath::builtin("Artifact"), a.toArtifact()->getIconIndex(), 0, EImageBlitMode::OPAQUE);
|
||||||
|
image->scaleTo(Point(23, 23), EScalingAlgorithm::NEAREST);
|
||||||
|
images.push_back(image);
|
||||||
|
}
|
||||||
|
auto window = std::make_shared<CObjectListWindow>(texts, nullptr, LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeArtifactSelect"), LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeArtifactSelect"), [this, artifacts, slot, artPos](int index){
|
||||||
|
if(index == 0)
|
||||||
|
{
|
||||||
|
parent.startInfo->artifacts[id][artPos[slot]] = ArtifactID::NONE;
|
||||||
|
parent.onChange();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
index--;
|
||||||
|
|
||||||
|
auto artifact = artifacts.at(index);
|
||||||
|
parent.startInfo->artifacts[id][artPos[slot]] = artifact;
|
||||||
|
parent.onChange();
|
||||||
|
}, selectedIndex, images, true, true);
|
||||||
|
window->onPopup = [artifacts](int index) {
|
||||||
|
if(index == 0)
|
||||||
|
return;
|
||||||
|
index--;
|
||||||
|
|
||||||
|
auto artifactId = artifacts.at(index);
|
||||||
|
std::shared_ptr<CComponent> comp = std::make_shared<CComponent>(ComponentType::ARTIFACT, artifactId);
|
||||||
|
CRClickPopup::createAndPush(artifactId.toArtifact()->getDescriptionTranslated(), CInfoWindow::TCompsInfo(1, comp));
|
||||||
|
};
|
||||||
|
ENGINE->windows().pushWindow(window);
|
||||||
|
}
|
||||||
|
|
||||||
void BattleOnlyModeHeroSelector::setArtifactIcons()
|
void BattleOnlyModeHeroSelector::setArtifactIcons()
|
||||||
{
|
{
|
||||||
OBJECT_CONSTRUCTION;
|
OBJECT_CONSTRUCTION;
|
||||||
|
|
||||||
std::vector<ArtifactPosition> artPos = {
|
auto artPos = getArtPos();
|
||||||
ArtifactPosition::HEAD, ArtifactPosition::SHOULDERS, ArtifactPosition::NECK, ArtifactPosition::RIGHT_HAND, ArtifactPosition::LEFT_HAND, ArtifactPosition::TORSO, ArtifactPosition::FEET,
|
|
||||||
ArtifactPosition::RIGHT_RING, ArtifactPosition::LEFT_RING, ArtifactPosition::MISC1, ArtifactPosition::MISC2, ArtifactPosition::MISC3, ArtifactPosition::MISC4, ArtifactPosition::MISC5
|
|
||||||
};
|
|
||||||
|
|
||||||
for(int i = 0; i < artifactImage.size(); i++)
|
for(int i = 0; i < artifactImage.size(); i++)
|
||||||
{
|
{
|
||||||
@@ -770,73 +859,7 @@ void BattleOnlyModeHeroSelector::setArtifactIcons()
|
|||||||
artifactImage[i] = std::make_shared<CPicture>(image, imgPos);
|
artifactImage[i] = std::make_shared<CPicture>(image, imgPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
artifactImage[i]->addLClickCallback([this, i, artPos, artifactId](){
|
artifactImage[i]->addLClickCallback([this, i, artifactId](){ selectArtifact(i, artifactId); });
|
||||||
auto allowedSet = LIBRARY->arth->getDefaultAllowed();
|
|
||||||
std::vector<ArtifactID> artifacts(allowedSet.begin(), allowedSet.end());
|
|
||||||
artifacts.erase( // remove already added and not for that slot allowed artifacts from selection
|
|
||||||
std::remove_if(
|
|
||||||
artifacts.begin(),
|
|
||||||
artifacts.end(),
|
|
||||||
[this, i, artPos](auto & artifact) {
|
|
||||||
auto possibleSlots = artifact.toArtifact()->getPossibleSlots();
|
|
||||||
std::vector<ArtifactPosition> allowedSlots;
|
|
||||||
if(possibleSlots.find(ArtBearer::HERO) != possibleSlots.end() && !possibleSlots.at(ArtBearer::HERO).empty())
|
|
||||||
allowedSlots = possibleSlots.at(ArtBearer::HERO);
|
|
||||||
|
|
||||||
return (std::any_of(parent.startInfo->artifacts[id].begin(), parent.startInfo->artifacts[id].end(), [&artifact](auto & a) {return a.second == artifact;})
|
|
||||||
&& parent.startInfo->artifacts[id][artPos[i]] != artifact)
|
|
||||||
|| !std::any_of(allowedSlots.begin(), allowedSlots.end(),[i, artPos](auto & p){ return p == artPos[i]; });
|
|
||||||
}
|
|
||||||
),
|
|
||||||
artifacts.end()
|
|
||||||
);
|
|
||||||
std::sort(artifacts.begin(), artifacts.end(), [](auto a, auto b) {
|
|
||||||
auto artifactA = a.toArtifact();
|
|
||||||
auto artifactB = b.toArtifact();
|
|
||||||
return artifactA->getNameTranslated() < artifactB->getNameTranslated();
|
|
||||||
});
|
|
||||||
|
|
||||||
int selectedIndex = artifactId == ArtifactID::NONE ? 0 : (1 + std::distance(artifacts.begin(), std::find_if(artifacts.begin(), artifacts.end(), [artifactId](auto artID) {
|
|
||||||
return artID == artifactId;
|
|
||||||
})));
|
|
||||||
|
|
||||||
std::vector<std::string> texts;
|
|
||||||
std::vector<std::shared_ptr<IImage>> images;
|
|
||||||
// Add "no artifact" option
|
|
||||||
texts.push_back(LIBRARY->generaltexth->translate("core.genrltxt.507"));
|
|
||||||
images.push_back(nullptr);
|
|
||||||
for (const auto & a : artifacts)
|
|
||||||
{
|
|
||||||
texts.push_back(a.toArtifact()->getNameTranslated());
|
|
||||||
|
|
||||||
auto image = ENGINE->renderHandler().loadImage(AnimationPath::builtin("Artifact"), a.toArtifact()->getIconIndex(), 0, EImageBlitMode::OPAQUE);
|
|
||||||
image->scaleTo(Point(23, 23), EScalingAlgorithm::NEAREST);
|
|
||||||
images.push_back(image);
|
|
||||||
}
|
|
||||||
auto window = std::make_shared<CObjectListWindow>(texts, nullptr, LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeArtifactSelect"), LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeArtifactSelect"), [this, artifacts, i, artPos](int index){
|
|
||||||
if(index == 0)
|
|
||||||
{
|
|
||||||
parent.startInfo->artifacts[id][artPos[i]] = ArtifactID::NONE;
|
|
||||||
parent.onChange();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
index--;
|
|
||||||
|
|
||||||
auto artifact = artifacts.at(index);
|
|
||||||
parent.startInfo->artifacts[id][artPos[i]] = artifact;
|
|
||||||
parent.onChange();
|
|
||||||
}, selectedIndex, images, true, true);
|
|
||||||
window->onPopup = [artifacts](int index) {
|
|
||||||
if(index == 0)
|
|
||||||
return;
|
|
||||||
index--;
|
|
||||||
|
|
||||||
auto artifactId = artifacts.at(index);
|
|
||||||
std::shared_ptr<CComponent> comp = std::make_shared<CComponent>(ComponentType::ARTIFACT, artifactId);
|
|
||||||
CRClickPopup::createAndPush(artifactId.toArtifact()->getDescriptionTranslated(), CInfoWindow::TCompsInfo(1, comp));
|
|
||||||
};
|
|
||||||
ENGINE->windows().pushWindow(window);
|
|
||||||
});
|
|
||||||
|
|
||||||
artifactImage[i]->addRClickCallback([this, i, artPos](){
|
artifactImage[i]->addRClickCallback([this, i, artPos](){
|
||||||
auto artId = parent.startInfo->artifacts[id][artPos[i]];
|
auto artId = parent.startInfo->artifacts[id][artPos[i]];
|
||||||
|
|||||||
@@ -48,6 +48,11 @@ private:
|
|||||||
|
|
||||||
std::vector<std::shared_ptr<CPicture>> addIcon;
|
std::vector<std::shared_ptr<CPicture>> addIcon;
|
||||||
|
|
||||||
|
void selectHero();
|
||||||
|
void selectCreature(int slot);
|
||||||
|
void selectSecSkill(int slot);
|
||||||
|
void selectArtifact(int slot, ArtifactID artifactId);
|
||||||
|
|
||||||
int id;
|
int id;
|
||||||
public:
|
public:
|
||||||
std::vector<std::shared_ptr<CAnimImage>> primSkills;
|
std::vector<std::shared_ptr<CAnimImage>> primSkills;
|
||||||
@@ -93,6 +98,8 @@ private:
|
|||||||
void onChange();
|
void onChange();
|
||||||
void update();
|
void update();
|
||||||
void setTerrainButtonText();
|
void setTerrainButtonText();
|
||||||
|
void selectTerrain();
|
||||||
|
void reset();
|
||||||
public:
|
public:
|
||||||
BattleOnlyModeTab();
|
BattleOnlyModeTab();
|
||||||
void applyStartInfo(std::shared_ptr<BattleOnlyModeStartInfo> si);
|
void applyStartInfo(std::shared_ptr<BattleOnlyModeStartInfo> si);
|
||||||
|
|||||||
Reference in New Issue
Block a user