1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-17 20:58:07 +02:00

Simplified building ID logic

- Replaced overcomplicated and broken math on dwelling ID's with fixed
enum
- Fixed broken 2nd upgrades and 8th dwelling
- Removed no longer used enumeration values from building ID's
This commit is contained in:
Ivan Savenko 2024-12-25 19:16:21 +00:00
parent 4e4135cd6d
commit 65fc50d33b
8 changed files with 60 additions and 69 deletions

View File

@ -222,7 +222,7 @@ bool BuildingManager::getBuildingOptions(const CGTownInstance * t)
std::vector<BuildingID> extraBuildings;
for (auto buildingInfo : t->getTown()->buildings)
{
if (buildingInfo.first > BuildingID::DWELL_UP2_FIRST)
if (buildingInfo.first.IsDwelling() && BuildingID::getUpgradedFromDwelling(buildingInfo.first) > 1)
extraBuildings.push_back(buildingInfo.first);
}
return tryBuildAnyStructure(t, extraBuildings);

View File

@ -109,7 +109,8 @@ TGoalVec GatherTroops::getAllPossibleSubgoals()
if(upgradeNumber < 0)
continue;
BuildingID bid(BuildingID::DWELL_FIRST + creature->getLevel() - 1 + upgradeNumber * t->getTown()->creatures.size());
BuildingID bid(BuildingID::getDwellingFromLevel(creature->getLevel(), upgradeNumber));
if(t->hasBuilt(bid) && ai->ah->freeResources().canAfford(creature->getFullRecruitCost())) //this assumes only creatures with dwellings are assigned to faction
{
solutions.push_back(sptr(BuyArmy(t, creature->getAIValue() * this->value).setobjid(objid)));

View File

@ -157,7 +157,7 @@ void CBuildingRect::showPopupWindow(const Point & cursorPosition)
BuildingID bid = getBuilding()->bid;
const CBuilding *bld = town->getTown()->buildings.at(bid);
if (bid < BuildingID::DWELL_FIRST)
if (!bid.IsDwelling())
{
CRClickPopup::createAndPush(CInfoWindow::genText(bld->getNameTranslated(), bld->getDescriptionTranslated()),
std::make_shared<CComponent>(ComponentType::BUILDING, BuildingTypeUniqueID(bld->town->faction->getId(), bld->bid)));
@ -751,7 +751,7 @@ bool CCastleBuildings::buildingTryActivateCustomUI(BuildingID buildingToTest, Bu
return true;
}
if (buildingToTest >= BuildingID::DWELL_FIRST)
if (buildingToTest.IsDwelling())
{
enterDwelling((BuildingID::getLevelFromDwelling(buildingToTest)));
return true;
@ -815,7 +815,7 @@ bool CCastleBuildings::buildingTryActivateCustomUI(BuildingID buildingToTest, Bu
case BuildingSubID::CASTLE_GATE:
if (LOCPLINT->makingTurn)
{
enterCastleGate();
enterCastleGate(buildingToTest);
return true;
}
return false;
@ -902,7 +902,7 @@ void CCastleBuildings::enterBuilding(BuildingID building)
LOCPLINT->showInfoDialog( town->getTown()->buildings.find(building)->second->getDescriptionTranslated(), comps);
}
void CCastleBuildings::enterCastleGate()
void CCastleBuildings::enterCastleGate(BuildingID building)
{
if (!town->visitingHero)
{
@ -929,7 +929,7 @@ void CCastleBuildings::enterCastleGate()
}
}
auto gateIcon = std::make_shared<CAnimImage>(town->getTown()->clientInfo.buildingsIcons, BuildingID::CASTLE_GATE);//will be deleted by selection window
auto gateIcon = std::make_shared<CAnimImage>(town->getTown()->clientInfo.buildingsIcons, building);//will be deleted by selection window
auto wnd = std::make_shared<CObjectListWindow>(availableTowns, gateIcon, CGI->generaltexth->jktexts[40],
CGI->generaltexth->jktexts[41], std::bind (&CCastleInterface::castleTeleport, LOCPLINT->castleInt, _1), 0, images);
wnd->onPopup = [availableTowns](int index) { CRClickPopup::createAndPush(LOCPLINT->cb->getObjInstance(ObjectInstanceID(availableTowns[index])), GH.getCursorPosition()); };

View File

@ -152,7 +152,7 @@ class CCastleBuildings : public CIntObject
void enterBlacksmith(BuildingID building, ArtifactID artifactID);//support for blacksmith + ballista yard
void enterBuilding(BuildingID building);//for buildings with simple description + pic left-click messages
void enterCastleGate();
void enterCastleGate(BuildingID building);
void enterFountain(const BuildingID & building, BuildingSubID::EBuildingSubID subID, BuildingID upgrades);//Rampart's fountains
void openMagesGuild();

View File

@ -295,32 +295,31 @@ public:
RESOURCE_SILO, BLACKSMITH, SPECIAL_1, HORDE_1, HORDE_1_UPGR,
SHIP, SPECIAL_2, SPECIAL_3, SPECIAL_4, HORDE_2,
HORDE_2_UPGR, GRAIL, EXTRA_TOWN_HALL, EXTRA_CITY_HALL, EXTRA_CAPITOL,
DWELL_FIRST=30, DWELL_LVL_2, DWELL_LVL_3, DWELL_LVL_4, DWELL_LVL_5, DWELL_LVL_6, DWELL_LAST=36,
DWELL_UP_FIRST=37, DWELL_LVL_2_UP, DWELL_LVL_3_UP, DWELL_LVL_4_UP, DWELL_LVL_5_UP,
DWELL_LVL_6_UP, DWELL_UP_LAST=43, DWELL_LVL_8=150, DWELL_LVL_8_UP=151, //150-154 reserved for 8. creature with potential upgrades
DWELL_LVL_1 = DWELL_FIRST,
DWELL_LVL_7 = DWELL_LAST,
DWELL_LVL_1_UP = DWELL_UP_FIRST,
DWELL_LVL_7_UP = DWELL_UP_LAST,
DWELL_UP2_FIRST = DWELL_LVL_7_UP + 1,
DWELL_LVL_1_UP2 = DWELL_UP2_FIRST, DWELL_LVL_2_UP2, DWELL_LVL_3_UP2, DWELL_LVL_4_UP2, DWELL_LVL_5_UP2, DWELL_LVL_6_UP2, DWELL_LVL_7_UP2, DWELL_LVL_8_UP2,
// //Special buildings for towns.
CASTLE_GATE = SPECIAL_3, //Inferno
FREELANCERS_GUILD = SPECIAL_2, //Stronghold
ARTIFACT_MERCHANT = SPECIAL_1,
DWELL_LVL_1=30, DWELL_LVL_2, DWELL_LVL_3, DWELL_LVL_4, DWELL_LVL_5, DWELL_LVL_6, DWELL_LVL_7=36,
DWELL_LVL_1_UP=37, DWELL_LVL_2_UP, DWELL_LVL_3_UP, DWELL_LVL_4_UP, DWELL_LVL_5_UP, DWELL_LVL_6_UP, DWELL_LVL_7_UP=43,
DWELL_LVL_1_UP2, DWELL_LVL_2_UP2, DWELL_LVL_3_UP2, DWELL_LVL_4_UP2, DWELL_LVL_5_UP2, DWELL_LVL_6_UP2, DWELL_LVL_7_UP2,
DWELL_LVL_1_UP3, DWELL_LVL_2_UP3, DWELL_LVL_3_UP3, DWELL_LVL_4_UP3, DWELL_LVL_5_UP3, DWELL_LVL_6_UP3, DWELL_LVL_7_UP3,
DWELL_LVL_1_UP4, DWELL_LVL_2_UP4, DWELL_LVL_3_UP4, DWELL_LVL_4_UP4, DWELL_LVL_5_UP4, DWELL_LVL_6_UP4, DWELL_LVL_7_UP4,
DWELL_LVL_1_UP5, DWELL_LVL_2_UP5, DWELL_LVL_3_UP5, DWELL_LVL_4_UP5, DWELL_LVL_5_UP5, DWELL_LVL_6_UP5, DWELL_LVL_7_UP5,
//150-155 reserved for 8. creature with potential upgrades
DWELL_LVL_8=150, DWELL_LVL_8_UP=151, DWELL_LVL_8_UP2 = 152, DWELL_LVL_8_UP3 = 153, DWELL_LVL_8_UP4 = 154, DWELL_LVL_8_UP5 = 155,
};
private:
static std::vector<std::vector<Type>> getDwellings()
static std::array<std::array<Type, 8>, 6> getDwellings()
{
std::vector<Type> dwellings = { DWELL_LVL_1, DWELL_LVL_2, DWELL_LVL_3, DWELL_LVL_4, DWELL_LVL_5, DWELL_LVL_6, DWELL_LVL_7, DWELL_LVL_8 };
std::vector<Type> dwellingsUp = { DWELL_LVL_1_UP, DWELL_LVL_2_UP, DWELL_LVL_3_UP, DWELL_LVL_4_UP, DWELL_LVL_5_UP, DWELL_LVL_6_UP, DWELL_LVL_7_UP, DWELL_LVL_8_UP };
std::vector<Type> dwellingsUp2 = { DWELL_UP2_FIRST, DWELL_LVL_2_UP2, DWELL_LVL_3_UP2, DWELL_LVL_4_UP2, DWELL_LVL_5_UP2 , DWELL_LVL_6_UP2 , DWELL_LVL_7_UP2, DWELL_LVL_8_UP2 };
return {dwellings, dwellingsUp, dwellingsUp2 };
static const std::array<std::array<Type, 8>, 6> allDwellings = {{
{ DWELL_LVL_1, DWELL_LVL_2, DWELL_LVL_3, DWELL_LVL_4, DWELL_LVL_5, DWELL_LVL_6, DWELL_LVL_7, DWELL_LVL_8 },
{ DWELL_LVL_1_UP, DWELL_LVL_2_UP, DWELL_LVL_3_UP, DWELL_LVL_4_UP, DWELL_LVL_5_UP, DWELL_LVL_6_UP, DWELL_LVL_7_UP, DWELL_LVL_8_UP },
{ DWELL_LVL_1_UP2, DWELL_LVL_2_UP2, DWELL_LVL_3_UP2, DWELL_LVL_4_UP2, DWELL_LVL_5_UP2, DWELL_LVL_6_UP2, DWELL_LVL_7_UP2, DWELL_LVL_8_UP2 },
{ DWELL_LVL_1_UP3, DWELL_LVL_2_UP3, DWELL_LVL_3_UP3, DWELL_LVL_4_UP3, DWELL_LVL_5_UP3, DWELL_LVL_6_UP3, DWELL_LVL_7_UP3, DWELL_LVL_8_UP3 },
{ DWELL_LVL_1_UP4, DWELL_LVL_2_UP4, DWELL_LVL_3_UP4, DWELL_LVL_4_UP4, DWELL_LVL_5_UP4, DWELL_LVL_6_UP4, DWELL_LVL_7_UP4, DWELL_LVL_8_UP4 },
{ DWELL_LVL_1_UP5, DWELL_LVL_2_UP5, DWELL_LVL_3_UP5, DWELL_LVL_4_UP5, DWELL_LVL_5_UP5, DWELL_LVL_6_UP5, DWELL_LVL_7_UP5, DWELL_LVL_8_UP5 }
}};
return allDwellings;
}
public:
@ -331,54 +330,45 @@ public:
static int getLevelFromDwelling(BuildingIDBase dwelling)
{
for(int i = 0; i < 2; i++)
for (const auto level : getDwellings())
{
auto tmp = getDwellings()[i];
auto it = std::find(tmp.begin(), tmp.end(), dwelling);
if (it != tmp.end())
return std::distance(tmp.begin(), it);
auto it = std::find(level.begin(), level.end(), dwelling);
if (it != level.end())
return std::distance(level.begin(), it);
}
if(dwelling >= BuildingIDBase::DWELL_LVL_8 && dwelling < BuildingIDBase::DWELL_LVL_8 + 5)
return 7;
else if (dwelling >= BuildingIDBase::DWELL_UP2_FIRST)
return (dwelling - DWELL_UP2_FIRST) % (GameConstants::CREATURES_PER_TOWN - 1);
else
return (dwelling - DWELL_FIRST) % (GameConstants::CREATURES_PER_TOWN - 1);
throw std::runtime_error("Call to getLevelFromDwelling with building '" + std::to_string(dwelling.num) +"' that is not dwelling!");
}
static int getUpgradedFromDwelling(BuildingIDBase dwelling)
{
for(int i = 0; i < 2; i++)
const auto & dwellings = getDwellings();
for(int i = 0; i < dwellings.size(); i++)
{
auto tmp = getDwellings()[i];
auto it = std::find(tmp.begin(), tmp.end(), dwelling);
if (it != tmp.end())
if (vstd::contains(dwellings[i], dwelling))
return i;
}
if(dwelling >= BuildingIDBase::DWELL_LVL_8 && dwelling < BuildingIDBase::DWELL_LVL_8 + 5)
return dwelling - BuildingIDBase::DWELL_LVL_8;
else if (dwelling >= BuildingIDBase::DWELL_UP2_FIRST)
return (dwelling - DWELL_UP2_FIRST) / (GameConstants::CREATURES_PER_TOWN - 1);
else
return (dwelling - DWELL_FIRST) / (GameConstants::CREATURES_PER_TOWN - 1);
throw std::runtime_error("Call to getUpgradedFromDwelling with building '" + std::to_string(dwelling.num) +"' that is not dwelling!");
}
static void advanceDwelling(BuildingIDBase & dwelling)
{
if(dwelling >= BuildingIDBase::DWELL_LVL_8 && dwelling < BuildingIDBase::DWELL_LVL_8 + 5)
dwelling.advance(1);
else
dwelling.advance(GameConstants::CREATURES_PER_TOWN - 1);
int level = getLevelFromDwelling(dwelling);
int upgrade = getUpgradedFromDwelling(dwelling);
dwelling.setNum(getDwellingFromLevel(level, upgrade + 1));
}
bool IsDwelling() const
{
return (DWELL_FIRST <= num && num <= DWELL_UP_LAST) || (DWELL_LVL_8 <= num && num <= DWELL_LVL_8_UP) || (num >= DWELL_UP2_FIRST && num < DWELL_LVL_8);
}
bool IsSpecialOrGrail() const
for (const auto level : getDwellings())
{
return num == SPECIAL_1 || num == SPECIAL_2 || num == SPECIAL_3 || num == SPECIAL_4 || num == GRAIL;
if (vstd::contains(level, num))
return true;
}
return false;
}
};

View File

@ -803,8 +803,8 @@ void CGameState::initTowns()
assert(vti->getTown());
assert(vti->getTown()->creatures.size() <= GameConstants::CREATURES_PER_TOWN);
constexpr std::array basicDwellings = { BuildingID::DWELL_FIRST, BuildingID::DWELL_LVL_2, BuildingID::DWELL_LVL_3, BuildingID::DWELL_LVL_4, BuildingID::DWELL_LVL_5, BuildingID::DWELL_LVL_6, BuildingID::DWELL_LVL_7, BuildingID::DWELL_LVL_8 };
constexpr std::array upgradedDwellings = { BuildingID::DWELL_UP_FIRST, BuildingID::DWELL_LVL_2_UP, BuildingID::DWELL_LVL_3_UP, BuildingID::DWELL_LVL_4_UP, BuildingID::DWELL_LVL_5_UP, BuildingID::DWELL_LVL_6_UP, BuildingID::DWELL_LVL_7_UP, BuildingID::DWELL_LVL_8_UP };
constexpr std::array basicDwellings = { BuildingID::DWELL_LVL_1, BuildingID::DWELL_LVL_2, BuildingID::DWELL_LVL_3, BuildingID::DWELL_LVL_4, BuildingID::DWELL_LVL_5, BuildingID::DWELL_LVL_6, BuildingID::DWELL_LVL_7, BuildingID::DWELL_LVL_8 };
constexpr std::array upgradedDwellings = { BuildingID::DWELL_LVL_1_UP, BuildingID::DWELL_LVL_2_UP, BuildingID::DWELL_LVL_3_UP, BuildingID::DWELL_LVL_4_UP, BuildingID::DWELL_LVL_5_UP, BuildingID::DWELL_LVL_6_UP, BuildingID::DWELL_LVL_7_UP, BuildingID::DWELL_LVL_8_UP };
constexpr std::array hordes = { BuildingID::HORDE_PLACEHOLDER1, BuildingID::HORDE_PLACEHOLDER2, BuildingID::HORDE_PLACEHOLDER3, BuildingID::HORDE_PLACEHOLDER4, BuildingID::HORDE_PLACEHOLDER5, BuildingID::HORDE_PLACEHOLDER6, BuildingID::HORDE_PLACEHOLDER7, BuildingID::HORDE_PLACEHOLDER8 };
//init buildings

View File

@ -267,7 +267,7 @@ TeleporterTilesVector CPathfinderHelper::getCastleGates(const PathNodeInfo & sou
for(const auto & town : getPlayerState(hero->tempOwner)->getTowns())
{
if(town->id != source.nodeObject->id && town->visitingHero == nullptr
&& town->hasBuilt(BuildingID::CASTLE_GATE, ETownType::INFERNO))
&& town->hasBuilt(BuildingSubID::CASTLE_GATE))
{
allowedExits.push_back(town->visitablePos());
}

View File

@ -2083,7 +2083,7 @@ bool CGameHandler::buildStructure(ObjectInstanceID tid, BuildingID requestedID,
//Performs stuff that has to be done before new building is built
auto processBeforeBuiltStructure = [t, this](const BuildingID buildingID)
{
if(buildingID >= BuildingID::DWELL_FIRST) //dwelling
if(buildingID.IsDwelling())
{
int level = BuildingID::getLevelFromDwelling(buildingID);
int upgradeNumber = BuildingID::getUpgradedFromDwelling(buildingID);