mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-25 22:42:04 +02:00
code review: big lambdas to function & simplify sort
This commit is contained in:
@@ -97,7 +97,51 @@ BattleOnlyModeTab::BattleOnlyModeTab()
|
||||
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"));
|
||||
|
||||
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(); });
|
||||
battlefieldSelector->block(GAME->server().isGuest());
|
||||
buttonReset = std::make_shared<CButton>(Point(259, 552), AnimationPath::builtin("GSPBUT2"), CButton::tooltip(), [this](){ reset(); });
|
||||
buttonReset->setTextOverlay(LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeReset"), EFonts::FONT_SMALL, Colors::WHITE);
|
||||
|
||||
heroSelector1 = std::make_shared<BattleOnlyModeHeroSelector>(0, *this, Point(55, 90));
|
||||
heroSelector2 = std::make_shared<BattleOnlyModeHeroSelector>(1, *this, Point(55, 320));
|
||||
|
||||
heroSelector1->setInputEnabled(GAME->server().isHost());
|
||||
|
||||
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;
|
||||
|
||||
@@ -142,44 +186,6 @@ BattleOnlyModeTab::BattleOnlyModeTab()
|
||||
}
|
||||
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());
|
||||
buttonReset = std::make_shared<CButton>(Point(259, 552), AnimationPath::builtin("GSPBUT2"), CButton::tooltip(), [this](){
|
||||
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);
|
||||
|
||||
heroSelector1 = std::make_shared<BattleOnlyModeHeroSelector>(0, *this, Point(55, 90));
|
||||
heroSelector2 = std::make_shared<BattleOnlyModeHeroSelector>(1, *this, Point(55, 320));
|
||||
|
||||
heroSelector1->setInputEnabled(GAME->server().isHost());
|
||||
|
||||
onChange();
|
||||
}
|
||||
|
||||
void BattleOnlyModeTab::init()
|
||||
@@ -389,10 +395,8 @@ void BattleOnlyModeHeroSelector::manageSpells()
|
||||
std::sort(allSpells.begin(), allSpells.end(), [](auto a, auto b) {
|
||||
auto A = a.toSpell();
|
||||
auto B = b.toSpell();
|
||||
if(A->getLevel() < B->getLevel())
|
||||
return true;
|
||||
if(A->getLevel() > B->getLevel())
|
||||
return false;
|
||||
if(A->getLevel() != B->getLevel())
|
||||
return A->getLevel() < B->getLevel();
|
||||
for (const auto schoolId : LIBRARY->spellSchoolHandler->getAllObjects())
|
||||
{
|
||||
if(A->schools.count(schoolId) && !B->schools.count(schoolId))
|
||||
@@ -458,26 +462,8 @@ void BattleOnlyModeHeroSelector::manageSpells()
|
||||
ENGINE->windows().pushWindow(temp);
|
||||
}
|
||||
|
||||
void BattleOnlyModeHeroSelector::setHeroIcon()
|
||||
void BattleOnlyModeHeroSelector::selectHero()
|
||||
{
|
||||
OBJECT_CONSTRUCTION;
|
||||
|
||||
if(parent.startInfo->selectedHero[id] == HeroTypeID::NONE)
|
||||
{
|
||||
heroImage = std::make_shared<CPicture>(drawBlackBox(Point(58, 64), LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeSelectHero"), id == 1 ? parent.boxColor : parent.disabledBoxColor), Point(6, 7));
|
||||
heroLabel = std::make_shared<CLabel>(160, 16, FONT_SMALL, ETextAlignment::CENTER, id == 1 ? Colors::WHITE : parent.disabledColor, LIBRARY->generaltexth->translate("core.genrltxt.507"));
|
||||
for(size_t i=0; i<GameConstants::PRIMARY_SKILLS; i++)
|
||||
primSkillsInput[i]->setText("0");
|
||||
}
|
||||
else
|
||||
{
|
||||
heroImage = std::make_shared<CPicture>(ENGINE->renderHandler().loadAnimation(AnimationPath::builtin("PortraitsLarge"), EImageBlitMode::COLORKEY)->getImage(parent.startInfo->selectedHero[id].toHeroType()->imageIndex), Point(6, 7));
|
||||
heroLabel = std::make_shared<CLabel>(160, 16, FONT_SMALL, ETextAlignment::CENTER, id == 1 ? Colors::WHITE : parent.disabledColor, parent.startInfo->selectedHero[id].toHeroType()->getNameTranslated());
|
||||
for(size_t i=0; i<GameConstants::PRIMARY_SKILLS; i++)
|
||||
primSkillsInput[i]->setText(std::to_string(parent.startInfo->primSkillLevel[id][i]));
|
||||
}
|
||||
|
||||
heroImage->addLClickCallback([this](){
|
||||
auto allowedSet = LIBRARY->heroh->getDefaultAllowed();
|
||||
std::vector<HeroTypeID> heroes(allowedSet.begin(), allowedSet.end());
|
||||
std::sort(heroes.begin(), heroes.end(), [](auto a, auto b) {
|
||||
@@ -539,7 +525,28 @@ void BattleOnlyModeHeroSelector::setHeroIcon()
|
||||
ENGINE->windows().createAndPushWindow<CHeroOverview>(heroes.at(index));
|
||||
};
|
||||
ENGINE->windows().pushWindow(window);
|
||||
});
|
||||
}
|
||||
|
||||
void BattleOnlyModeHeroSelector::setHeroIcon()
|
||||
{
|
||||
OBJECT_CONSTRUCTION;
|
||||
|
||||
if(parent.startInfo->selectedHero[id] == HeroTypeID::NONE)
|
||||
{
|
||||
heroImage = std::make_shared<CPicture>(drawBlackBox(Point(58, 64), LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeSelectHero"), id == 1 ? parent.boxColor : parent.disabledBoxColor), Point(6, 7));
|
||||
heroLabel = std::make_shared<CLabel>(160, 16, FONT_SMALL, ETextAlignment::CENTER, id == 1 ? Colors::WHITE : parent.disabledColor, LIBRARY->generaltexth->translate("core.genrltxt.507"));
|
||||
for(size_t i=0; i<GameConstants::PRIMARY_SKILLS; i++)
|
||||
primSkillsInput[i]->setText("0");
|
||||
}
|
||||
else
|
||||
{
|
||||
heroImage = std::make_shared<CPicture>(ENGINE->renderHandler().loadAnimation(AnimationPath::builtin("PortraitsLarge"), EImageBlitMode::COLORKEY)->getImage(parent.startInfo->selectedHero[id].toHeroType()->imageIndex), Point(6, 7));
|
||||
heroLabel = std::make_shared<CLabel>(160, 16, FONT_SMALL, ETextAlignment::CENTER, id == 1 ? Colors::WHITE : parent.disabledColor, parent.startInfo->selectedHero[id].toHeroType()->getNameTranslated());
|
||||
for(size_t i=0; i<GameConstants::PRIMARY_SKILLS; i++)
|
||||
primSkillsInput[i]->setText(std::to_string(parent.startInfo->primSkillLevel[id][i]));
|
||||
}
|
||||
|
||||
heroImage->addLClickCallback([this](){ selectHero(); });
|
||||
|
||||
heroImage->addRClickCallback([this](){
|
||||
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()
|
||||
{
|
||||
OBJECT_CONSTRUCTION;
|
||||
@@ -572,62 +637,7 @@ void BattleOnlyModeHeroSelector::setCreatureIcons()
|
||||
selectedArmyInput[i]->enable();
|
||||
}
|
||||
|
||||
creatureImage[i]->addLClickCallback([this, 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]->addLClickCallback([this, i](){ selectCreature(i); });
|
||||
|
||||
creatureImage[i]->addRClickCallback([this, i](){
|
||||
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()
|
||||
{
|
||||
OBJECT_CONSTRUCTION;
|
||||
@@ -663,69 +738,7 @@ void BattleOnlyModeHeroSelector::setSecSkillIcons()
|
||||
selectedSecSkillInput[i]->enable();
|
||||
}
|
||||
|
||||
secSkillImage[i]->addLClickCallback([this, 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]->addLClickCallback([this, i](){ selectSecSkill(i); });
|
||||
|
||||
secSkillImage[i]->addRClickCallback([this, i](){
|
||||
auto skillId = parent.startInfo->secSkillLevel[id][i].first;
|
||||
@@ -740,52 +753,34 @@ void BattleOnlyModeHeroSelector::setSecSkillIcons()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BattleOnlyModeHeroSelector::setArtifactIcons()
|
||||
std::vector<ArtifactPosition> getArtPos()
|
||||
{
|
||||
OBJECT_CONSTRUCTION;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
for(int i = 0; i < artifactImage.size(); i++)
|
||||
{
|
||||
int xPos = i % 7;
|
||||
int yPos = i / 7;
|
||||
Point imgPos(6 + xPos * 36, 137 + yPos * 36);
|
||||
auto artifactId = parent.startInfo->artifacts[id][artPos[i]];
|
||||
if(artifactId == ArtifactID::NONE)
|
||||
{
|
||||
MetaString str;
|
||||
str.appendTextID("vcmi.lobby.battleOnlyModeSelectArtifact");
|
||||
str.replaceTextID("vcmi.lobby.battleOnlyModeSelectArtifact." + std::to_string(artPos[i]));
|
||||
artifactImage[i] = std::make_shared<CPicture>(drawBlackBox(Point(32, 32), str.toString(), id == 1 ? parent.boxColor : parent.disabledBoxColor), imgPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto image = ENGINE->renderHandler().loadImage(AnimationPath::builtin("Artifact"), artifactId.toArtifact()->getIconIndex(), 0, EImageBlitMode::OPAQUE);
|
||||
image->scaleTo(Point(32, 32), EScalingAlgorithm::NEAREST);
|
||||
artifactImage[i] = std::make_shared<CPicture>(image, imgPos);
|
||||
}
|
||||
void BattleOnlyModeHeroSelector::selectArtifact(int slot, ArtifactID artifactId)
|
||||
{
|
||||
auto artPos = getArtPos();
|
||||
|
||||
artifactImage[i]->addLClickCallback([this, i, artPos, 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) {
|
||||
[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[i]] != artifact)
|
||||
|| !std::any_of(allowedSlots.begin(), allowedSlots.end(),[i, artPos](auto & p){ return p == artPos[i]; });
|
||||
&& parent.startInfo->artifacts[id][artPos[slot]] != artifact)
|
||||
|| !std::any_of(allowedSlots.begin(), allowedSlots.end(), [slot, artPos](auto & p){ return p == artPos[slot]; });
|
||||
}
|
||||
),
|
||||
artifacts.end()
|
||||
@@ -813,17 +808,17 @@ void BattleOnlyModeHeroSelector::setArtifactIcons()
|
||||
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){
|
||||
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[i]] = ArtifactID::NONE;
|
||||
parent.startInfo->artifacts[id][artPos[slot]] = ArtifactID::NONE;
|
||||
parent.onChange();
|
||||
return;
|
||||
}
|
||||
index--;
|
||||
|
||||
auto artifact = artifacts.at(index);
|
||||
parent.startInfo->artifacts[id][artPos[i]] = artifact;
|
||||
parent.startInfo->artifacts[id][artPos[slot]] = artifact;
|
||||
parent.onChange();
|
||||
}, selectedIndex, images, true, true);
|
||||
window->onPopup = [artifacts](int index) {
|
||||
@@ -836,7 +831,35 @@ void BattleOnlyModeHeroSelector::setArtifactIcons()
|
||||
CRClickPopup::createAndPush(artifactId.toArtifact()->getDescriptionTranslated(), CInfoWindow::TCompsInfo(1, comp));
|
||||
};
|
||||
ENGINE->windows().pushWindow(window);
|
||||
});
|
||||
}
|
||||
|
||||
void BattleOnlyModeHeroSelector::setArtifactIcons()
|
||||
{
|
||||
OBJECT_CONSTRUCTION;
|
||||
|
||||
auto artPos = getArtPos();
|
||||
|
||||
for(int i = 0; i < artifactImage.size(); i++)
|
||||
{
|
||||
int xPos = i % 7;
|
||||
int yPos = i / 7;
|
||||
Point imgPos(6 + xPos * 36, 137 + yPos * 36);
|
||||
auto artifactId = parent.startInfo->artifacts[id][artPos[i]];
|
||||
if(artifactId == ArtifactID::NONE)
|
||||
{
|
||||
MetaString str;
|
||||
str.appendTextID("vcmi.lobby.battleOnlyModeSelectArtifact");
|
||||
str.replaceTextID("vcmi.lobby.battleOnlyModeSelectArtifact." + std::to_string(artPos[i]));
|
||||
artifactImage[i] = std::make_shared<CPicture>(drawBlackBox(Point(32, 32), str.toString(), id == 1 ? parent.boxColor : parent.disabledBoxColor), imgPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto image = ENGINE->renderHandler().loadImage(AnimationPath::builtin("Artifact"), artifactId.toArtifact()->getIconIndex(), 0, EImageBlitMode::OPAQUE);
|
||||
image->scaleTo(Point(32, 32), EScalingAlgorithm::NEAREST);
|
||||
artifactImage[i] = std::make_shared<CPicture>(image, imgPos);
|
||||
}
|
||||
|
||||
artifactImage[i]->addLClickCallback([this, i, artifactId](){ selectArtifact(i, artifactId); });
|
||||
|
||||
artifactImage[i]->addRClickCallback([this, i, artPos](){
|
||||
auto artId = parent.startInfo->artifacts[id][artPos[i]];
|
||||
|
||||
@@ -48,6 +48,11 @@ private:
|
||||
|
||||
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;
|
||||
public:
|
||||
std::vector<std::shared_ptr<CAnimImage>> primSkills;
|
||||
@@ -93,6 +98,8 @@ private:
|
||||
void onChange();
|
||||
void update();
|
||||
void setTerrainButtonText();
|
||||
void selectTerrain();
|
||||
void reset();
|
||||
public:
|
||||
BattleOnlyModeTab();
|
||||
void applyStartInfo(std::shared_ptr<BattleOnlyModeStartInfo> si);
|
||||
|
||||
Reference in New Issue
Block a user