1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-25 22:42:04 +02:00

refactor types

This commit is contained in:
Laserlicht
2025-10-25 23:08:08 +02:00
parent 05ea43438e
commit 189acf9be4
3 changed files with 40 additions and 42 deletions

View File

@@ -139,12 +139,12 @@ BattleOnlyModeWindow::BattleOnlyModeWindow()
startInfo->selectedTerrain = TerrainId::DIRT; startInfo->selectedTerrain = TerrainId::DIRT;
startInfo->selectedTown = std::nullopt; startInfo->selectedTown = std::nullopt;
startInfo->selectedHero[0] = std::nullopt; startInfo->selectedHero[0] = std::nullopt;
startInfo->selectedArmy[0]->clearSlots(); startInfo->selectedArmy[0].fill(std::nullopt);
for(size_t i=0; i<GameConstants::ARMY_SIZE; i++) for(size_t i=0; i<GameConstants::ARMY_SIZE; i++)
heroSelector1->selectedArmyInput.at(i)->setText("1"); heroSelector1->selectedArmyInput.at(i)->setText("1");
} }
startInfo->selectedHero[1] = std::nullopt; startInfo->selectedHero[1] = std::nullopt;
startInfo->selectedArmy[1]->clearSlots(); startInfo->selectedArmy[1].fill(std::nullopt);
for(size_t i=0; i<GameConstants::ARMY_SIZE; i++) for(size_t i=0; i<GameConstants::ARMY_SIZE; i++)
heroSelector2->selectedArmyInput.at(i)->setText("1"); heroSelector2->selectedArmyInput.at(i)->setText("1");
onChange(); onChange();
@@ -203,8 +203,10 @@ void BattleOnlyModeWindow::setTerrainButtonText()
void BattleOnlyModeWindow::setOkButtonEnabled() void BattleOnlyModeWindow::setOkButtonEnabled()
{ {
bool army2Empty = std::all_of(startInfo->selectedArmy[1].begin(), startInfo->selectedArmy[1].end(), [](const auto x) { return !x; });
bool canStart = (startInfo->selectedTerrain || startInfo->selectedTown); bool canStart = (startInfo->selectedTerrain || startInfo->selectedTown);
canStart &= (startInfo->selectedHero[0] && ((startInfo->selectedHero[1]) || (startInfo->selectedTown && startInfo->selectedArmy[1]->stacksCount()))); canStart &= (startInfo->selectedHero[0] && ((startInfo->selectedHero[1]) || (startInfo->selectedTown && !army2Empty)));
buttonOk->block(!canStart || GAME->server().isGuest()); buttonOk->block(!canStart || GAME->server().isGuest());
buttonAbort->block(GAME->server().isGuest()); buttonAbort->block(GAME->server().isGuest());
} }
@@ -251,9 +253,9 @@ BattleOnlyModeHeroSelector::BattleOnlyModeHeroSelector(int id, BattleOnlyModeWin
selectedArmyInput.back()->setFilterNumber(1, 10000000, 3); selectedArmyInput.back()->setFilterNumber(1, 10000000, 3);
selectedArmyInput.back()->setText("1"); selectedArmyInput.back()->setText("1");
selectedArmyInput.back()->setCallback([this, i, id](const std::string & text){ selectedArmyInput.back()->setCallback([this, i, id](const std::string & text){
if(!parent.startInfo->selectedArmy[id]->slotEmpty(SlotID(i))) if(!parent.startInfo->selectedArmy[id][i])
{ {
parent.startInfo->selectedArmy[id]->setCreature(SlotID(i), parent.startInfo->selectedArmy[id]->getCreature(SlotID(i))->getId(), TextOperations::parseMetric<int>(text)); (*parent.startInfo->selectedArmy[id][i]).second = TextOperations::parseMetric<int>(text);
parent.onChange(); parent.onChange();
} }
}); });
@@ -276,8 +278,8 @@ void BattleOnlyModeHeroSelector::setHeroIcon()
} }
else else
{ {
heroImage = std::make_shared<CPicture>(ENGINE->renderHandler().loadAnimation(AnimationPath::builtin("PortraitsLarge"), EImageBlitMode::COLORKEY)->getImage(parent.startInfo->selectedHero[id]->getHeroType()->imageIndex), Point(6, 7)); 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, Colors::WHITE, parent.startInfo->selectedHero[id]->getNameTranslated()); heroLabel = std::make_shared<CLabel>(160, 16, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, (*parent.startInfo->selectedHero[id]).toHeroType()->getNameTranslated());
for(size_t i=0; i<GameConstants::PRIMARY_SKILLS; i++) for(size_t i=0; i<GameConstants::PRIMARY_SKILLS; i++)
primSkillsInput[i]->setText("0"); primSkillsInput[i]->setText("0");
} }
@@ -296,7 +298,7 @@ void BattleOnlyModeHeroSelector::setHeroIcon()
}); });
int selectedIndex = !parent.startInfo->selectedHero[id] ? 0 : (1 + std::distance(heroes.begin(), std::find_if(heroes.begin(), heroes.end(), [this](auto heroID) { int selectedIndex = !parent.startInfo->selectedHero[id] ? 0 : (1 + std::distance(heroes.begin(), std::find_if(heroes.begin(), heroes.end(), [this](auto heroID) {
return heroID == parent.startInfo->selectedHero[id]->getHeroType()->getId(); return heroID == (*parent.startInfo->selectedHero[id]);
}))); })));
std::vector<std::string> texts; std::vector<std::string> texts;
@@ -315,19 +317,13 @@ void BattleOnlyModeHeroSelector::setHeroIcon()
auto window = std::make_shared<CObjectListWindow>(texts, nullptr, LIBRARY->generaltexth->translate("object.core.hero.name"), LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeHeroSelect"), [this, heroes](int index){ auto window = std::make_shared<CObjectListWindow>(texts, nullptr, LIBRARY->generaltexth->translate("object.core.hero.name"), LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeHeroSelect"), [this, heroes](int index){
if(index == 0) if(index == 0)
{ {
parent.startInfo->selectedHero[id].reset(); parent.startInfo->selectedHero[id] = std::nullopt;
parent.onChange(); parent.onChange();
return; return;
} }
index--; index--;
auto hero = heroes[index];
auto factory = LIBRARY->objtypeh->getHandlerFor(Obj::HERO, hero.toHeroType()->heroClass->getId()); parent.startInfo->selectedHero[id] = heroes[index];
auto templates = factory->getTemplates();
auto obj = std::dynamic_pointer_cast<CGHeroInstance>(factory->create(parent.cb.get(), templates.front()));
obj->setHeroType(hero);
parent.startInfo->selectedHero[id] = obj;
for(size_t i=0; i<GameConstants::PRIMARY_SKILLS; i++) for(size_t i=0; i<GameConstants::PRIMARY_SKILLS; i++)
parent.startInfo->primSkillLevel[id][i] = 0; parent.startInfo->primSkillLevel[id][i] = 0;
@@ -347,7 +343,7 @@ void BattleOnlyModeHeroSelector::setHeroIcon()
if(!parent.startInfo->selectedHero[id]) if(!parent.startInfo->selectedHero[id])
return; return;
ENGINE->windows().createAndPushWindow<CHeroOverview>(parent.startInfo->selectedHero[id]->getHeroType()->getId()); ENGINE->windows().createAndPushWindow<CHeroOverview>(parent.startInfo->selectedHero[id]->toHeroType()->getId());
}); });
} }
@@ -357,11 +353,11 @@ void BattleOnlyModeHeroSelector::setCreatureIcons()
for(int i = 0; i < creatureImage.size(); i++) for(int i = 0; i < creatureImage.size(); i++)
{ {
if(parent.startInfo->selectedArmy[id]->slotEmpty(SlotID(i))) if(!parent.startInfo->selectedArmy[id][i])
creatureImage[i] = std::make_shared<CPicture>(drawBlackBox(Point(32, 32), LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeSelect")), Point(6 + i * 36, 78)); creatureImage[i] = std::make_shared<CPicture>(drawBlackBox(Point(32, 32), LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeSelect")), Point(6 + i * 36, 78));
else else
{ {
auto creatureID = parent.startInfo->selectedArmy[id]->Slots().at(SlotID(i))->getCreatureID(); auto creatureID = (*parent.startInfo->selectedArmy[id][i]).first;
creatureImage[i] = std::make_shared<CPicture>(ENGINE->renderHandler().loadAnimation(AnimationPath::builtin("CPRSMALL"), EImageBlitMode::COLORKEY)->getImage(LIBRARY->creh->objects.at(creatureID)->getIconIndex()), Point(6 + i * 36, 78)); creatureImage[i] = std::make_shared<CPicture>(ENGINE->renderHandler().loadAnimation(AnimationPath::builtin("CPRSMALL"), EImageBlitMode::COLORKEY)->getImage(LIBRARY->creh->objects.at(creatureID)->getIconIndex()), Point(6 + i * 36, 78));
} }
@@ -378,8 +374,8 @@ void BattleOnlyModeHeroSelector::setCreatureIcons()
return creatureA->getFactionID() < creatureB->getFactionID(); return creatureA->getFactionID() < creatureB->getFactionID();
}); });
int selectedIndex = parent.startInfo->selectedArmy[id]->slotEmpty(SlotID(i)) ? 0 : (1 + std::distance(creatures.begin(), std::find_if(creatures.begin(), creatures.end(), [this, i](auto creatureID) { 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]->Slots().at(SlotID(i))->getId(); return creatureID == (*parent.startInfo->selectedArmy[id][i]).first;
}))); })));
std::vector<std::string> texts; std::vector<std::string> texts;
@@ -398,15 +394,15 @@ void BattleOnlyModeHeroSelector::setCreatureIcons()
auto window = std::make_shared<CObjectListWindow>(texts, nullptr, LIBRARY->generaltexth->translate("core.genrltxt.42"), LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeCreatureSelect"), [this, creatures, i](int index){ auto window = std::make_shared<CObjectListWindow>(texts, nullptr, LIBRARY->generaltexth->translate("core.genrltxt.42"), LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeCreatureSelect"), [this, creatures, i](int index){
if(index == 0) if(index == 0)
{ {
if(!parent.startInfo->selectedArmy[id]->slotEmpty(SlotID(i))) if(parent.startInfo->selectedArmy[id][i])
parent.startInfo->selectedArmy[id]->eraseStack(SlotID(i)); parent.startInfo->selectedArmy[id][i] = std::nullopt;
parent.onChange(); parent.onChange();
return; return;
} }
index--; index--;
auto creature = creatures.at(index).toCreature(); auto creature = creatures.at(index).toCreature();
parent.startInfo->selectedArmy[id]->setCreature(SlotID(i), creature->getId(), 100); parent.startInfo->selectedArmy[id][i] = std::make_pair(creature->getId(), 100);
selectedArmyInput[SlotID(i)]->setText("100"); selectedArmyInput[SlotID(i)]->setText("100");
parent.onChange(); parent.onChange();
}, selectedIndex, images, true, true); }, selectedIndex, images, true, true);
@@ -421,10 +417,10 @@ void BattleOnlyModeHeroSelector::setCreatureIcons()
}); });
creatureImage[i]->addRClickCallback([this, i](){ creatureImage[i]->addRClickCallback([this, i](){
if(parent.startInfo->selectedArmy[id]->slotEmpty(SlotID(i))) if(!parent.startInfo->selectedArmy[id][i])
return; return;
ENGINE->windows().createAndPushWindow<CStackWindow>(LIBRARY->creh->objects.at(parent.startInfo->selectedArmy[id]->Slots().at(SlotID(i))->getCreatureID()).get(), true); ENGINE->windows().createAndPushWindow<CStackWindow>(LIBRARY->creh->objects.at(parent.startInfo->selectedArmy[id][i].first).get(), true);
}); });
} }
} }
@@ -445,17 +441,22 @@ void BattleOnlyModeWindow::startBattle()
auto knownHeroes = LIBRARY->objtypeh->knownSubObjects(Obj::HERO); auto knownHeroes = LIBRARY->objtypeh->knownSubObjects(Obj::HERO);
auto addHero = [&](int sel, PlayerColor color, const int3 & position) auto addHero = [&, this](int sel, PlayerColor color, const int3 & position)
{ {
startInfo->selectedHero[sel]->setOwner(color); auto factory = LIBRARY->objtypeh->getHandlerFor(Obj::HERO, (*startInfo->selectedHero[sel]).toHeroType()->heroClass->getId());
startInfo->selectedHero[sel]->pos = position; auto templates = factory->getTemplates();
auto obj = std::dynamic_pointer_cast<CGHeroInstance>(factory->create(cb.get(), templates.front()));
obj->setHeroType(*startInfo->selectedHero[sel]);
obj->setOwner(color);
obj->pos = position;
for(size_t i=0; i<GameConstants::PRIMARY_SKILLS; i++) for(size_t i=0; i<GameConstants::PRIMARY_SKILLS; i++)
startInfo->selectedHero[sel]->pushPrimSkill(PrimarySkill(i), startInfo->primSkillLevel[sel][i]); obj->pushPrimSkill(PrimarySkill(i), startInfo->primSkillLevel[sel][i]);
startInfo->selectedHero[sel]->clearSlots(); obj->clearSlots();
for(int slot = 0; slot < GameConstants::ARMY_SIZE; slot++) for(int slot = 0; slot < GameConstants::ARMY_SIZE; slot++)
if(!startInfo->selectedArmy[sel]->slotEmpty(SlotID(slot))) if(startInfo->selectedArmy[sel][slot])
startInfo->selectedHero[sel]->putStack(SlotID(slot), startInfo->selectedArmy[sel]->detachStack(SlotID(slot))); obj->setCreature(SlotID(slot), (*startInfo->selectedArmy[sel][slot]).first, (*startInfo->selectedArmy[sel][slot]).second);
map->getEditManager()->insertObject(startInfo->selectedHero[sel]); map->getEditManager()->insertObject(obj);
}; };
addHero(0, PlayerColor(0), int3(5, 6, 0)); addHero(0, PlayerColor(0), int3(5, 6, 0));
@@ -474,8 +475,8 @@ void BattleOnlyModeWindow::startBattle()
if(!startInfo->selectedHero[1]) if(!startInfo->selectedHero[1])
{ {
for(int slot = 0; slot < GameConstants::ARMY_SIZE; slot++) for(int slot = 0; slot < GameConstants::ARMY_SIZE; slot++)
if(!startInfo->selectedArmy[1]->slotEmpty(SlotID(slot))) if(startInfo->selectedArmy[1][slot])
townObj->getArmy()->putStack(SlotID(slot), startInfo->selectedArmy[1]->detachStack(SlotID(slot))); townObj->getArmy()->setCreature(SlotID(slot), (*startInfo->selectedArmy[1][slot]).first, (*startInfo->selectedArmy[1][slot]).second);
} }
else else
addHero(1, PlayerColor(1), int3(5, 5, 0)); addHero(1, PlayerColor(1), int3(5, 5, 0));

View File

@@ -246,8 +246,6 @@ BattleOnlyModeStartInfo::BattleOnlyModeStartInfo()
: selectedTerrain(TerrainId::DIRT) : selectedTerrain(TerrainId::DIRT)
, selectedTown(std::nullopt) , selectedTown(std::nullopt)
{ {
for(auto & element : selectedArmy)
element = std::make_shared<CCreatureSet>();
for(auto & element : primSkillLevel) for(auto & element : primSkillLevel)
for(size_t i=0; i<GameConstants::PRIMARY_SKILLS; i++) for(size_t i=0; i<GameConstants::PRIMARY_SKILLS; i++)
element[i] = 0; element[i] = 0;

View File

@@ -15,6 +15,7 @@
#include "TurnTimerInfo.h" #include "TurnTimerInfo.h"
#include "ExtraOptionsInfo.h" #include "ExtraOptionsInfo.h"
#include "campaign/CampaignConstants.h" #include "campaign/CampaignConstants.h"
#include "mapObjects/army/CCreatureSet.h"
#include "serializer/GameConnectionID.h" #include "serializer/GameConnectionID.h"
#include "serializer/Serializeable.h" #include "serializer/Serializeable.h"
#include "serializer/PlayerConnectionID.h" #include "serializer/PlayerConnectionID.h"
@@ -25,8 +26,6 @@ VCMI_LIB_NAMESPACE_BEGIN
class CMapGenOptions; class CMapGenOptions;
class CampaignState; class CampaignState;
class CMapInfo; class CMapInfo;
class CGHeroInstance;
class CCreatureSet;
struct PlayerInfo; struct PlayerInfo;
class PlayerColor; class PlayerColor;
@@ -247,8 +246,8 @@ public:
std::optional<TerrainId> selectedTerrain; std::optional<TerrainId> selectedTerrain;
std::optional<FactionID> selectedTown; std::optional<FactionID> selectedTown;
std::array<std::shared_ptr<CGHeroInstance>, 2> selectedHero; std::array<std::optional<HeroTypeID>, 2> selectedHero;
std::array<std::shared_ptr<CCreatureSet>, 2> selectedArmy; std::array<std::array<std::optional<std::pair<CreatureID, int>>, 7>, 2> selectedArmy;
std::array<std::array<int, GameConstants::PRIMARY_SKILLS>, 2> primSkillLevel; std::array<std::array<int, GameConstants::PRIMARY_SKILLS>, 2> primSkillLevel;