Browse Source

Merge pull request #5156 from IvanSavenko/dwelling_fix

Simplified building ID logic
Ivan Savenko 10 tháng trước cách đây
mục cha
commit
5f2028a35c

+ 1 - 1
AI/VCAI/BuildingManager.cpp

@@ -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);

+ 2 - 1
AI/VCAI/Goals/GatherTroops.cpp

@@ -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)));

+ 5 - 5
client/windows/CCastleInterface.cpp

@@ -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()); };

+ 1 - 1
client/windows/CCastleInterface.h

@@ -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();

+ 49 - 59
lib/constants/EntityIdentifiers.h

@@ -289,38 +289,37 @@ public:
 		HORDE_PLACEHOLDER1 = -30,
 		NONE = -1,
 		FIRST_REGULAR_ID = 0,
-		MAGES_GUILD_1 = 0,  MAGES_GUILD_2, MAGES_GUILD_3,     MAGES_GUILD_4,   MAGES_GUILD_5,
-		TAVERN,         SHIPYARD,      FORT,              CITADEL,         CASTLE,
-		VILLAGE_HALL,   TOWN_HALL,     CITY_HALL,         CAPITOL,         MARKETPLACE,
-		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,
-
+		MAGES_GUILD_1 = 0,  MAGES_GUILD_2,   MAGES_GUILD_3,     MAGES_GUILD_4,   MAGES_GUILD_5,
+		TAVERN,             SHIPYARD,        FORT,              CITADEL,         CASTLE,
+		VILLAGE_HALL,       TOWN_HALL,       CITY_HALL,         CAPITOL,         MARKETPLACE,
+		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_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);
 
-	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);
+		dwelling.setNum(getDwellingFromLevel(level, upgrade + 1));
 	}
 
-	bool IsSpecialOrGrail() const
+	bool IsDwelling() const
 	{
-		return num == SPECIAL_1 || num == SPECIAL_2 || num == SPECIAL_3 || num == SPECIAL_4 || num == GRAIL;
+		for (const auto level : getDwellings())
+		{
+			if (vstd::contains(level, num))
+				return true;
+		}
+		return false;
 	}
 };
 

+ 2 - 2
lib/gameState/CGameState.cpp

@@ -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

+ 1 - 1
lib/pathfinder/CPathfinder.cpp

@@ -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());
 		}

+ 1 - 1
server/CGameHandler.cpp

@@ -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);