diff --git a/client/windows/CCastleInterface.cpp b/client/windows/CCastleInterface.cpp index 9a475c6f3..2fad5e67c 100644 --- a/client/windows/CCastleInterface.cpp +++ b/client/windows/CCastleInterface.cpp @@ -115,7 +115,7 @@ void CBuildingRect::clickLeft(tribool down, bool previousState) if (!CSDL_Ext::isTransparent(area, GH.current->motion.x - pos.x, GH.current->motion.y - pos.y)) //inside building image { auto building = getBuilding(); - parent->buildingClicked(building->bid, building->subId); + parent->buildingClicked(building->bid, building->subId, building->upgrade); } } @@ -653,7 +653,7 @@ const CGHeroInstance * CCastleBuildings::getHero() return town->garrisonHero; } -void CCastleBuildings::buildingClicked(BuildingID building, BuildingSubID::EBuildingSubID subID) +void CCastleBuildings::buildingClicked(BuildingID building, BuildingSubID::EBuildingSubID subID, BuildingID::EBuildingID upgrades) { logGlobal->trace("You've clicked on %d", (int)building.toEnum()); const CBuilding *b = town->town->buildings.find(building)->second; @@ -719,7 +719,7 @@ void CCastleBuildings::buildingClicked(BuildingID building, BuildingSubID::EBuil break; case BuildingSubID::MYSTIC_POND: - enterFountain(building); + enterFountain(building, subID, upgrades); break; case BuildingSubID::ARTIFACT_MERCHANT: @@ -730,7 +730,7 @@ void CCastleBuildings::buildingClicked(BuildingID building, BuildingSubID::EBuil break; case BuildingSubID::FOUNTAIN_OF_FORTUNE: - enterFountain(building); + enterFountain(building, subID, upgrades); break; case BuildingSubID::FREELANCERS_GUILD: @@ -748,7 +748,10 @@ void CCastleBuildings::buildingClicked(BuildingID building, BuildingSubID::EBuil break; case BuildingSubID::BROTHERHOOD_OF_SWORD: - LOCPLINT->showTavernWindow(town); + if(upgrades == BuildingID::TAVERN) + LOCPLINT->showTavernWindow(town); + else + enterBuilding(building); break; case BuildingSubID::CASTLE_GATE: @@ -839,22 +842,28 @@ void CCastleBuildings::enterToTheQuickRecruitmentWindow() GH.pushIntT(town, pos); } -void CCastleBuildings::enterFountain(BuildingID building) +void CCastleBuildings::enterFountain(const BuildingID & building, BuildingSubID::EBuildingSubID subID, BuildingID::EBuildingID upgrades) { - std::vector> comps(1, std::make_shared(CComponent::building,town->subID,building)); - + std::vector> comps(1, std::make_shared(CComponent::building,town->subID, building)); std::string descr = town->town->buildings.find(building)->second->Description(); - if ( building == BuildingID::FOUNTAIN_OF_FORTUNE) - descr += "\n\n"+town->town->buildings.find(BuildingID::MYSTIC_POND)->second->Description(); + bool isMysticPondOrItsUpgrade = subID == BuildingSubID::MYSTIC_POND + || (upgrades != BuildingID::NONE + && town->town->buildings.find(BuildingID(upgrades))->second->subId == BuildingSubID::MYSTIC_POND); - if (town->bonusValue.first == 0)//fountain was builded this week - descr += "\n\n"+ CGI->generaltexth->allTexts[677]; - else//fountain produced something; + if(upgrades != BuildingID::NONE) + descr += "\n\n"+town->town->buildings.find(BuildingID(upgrades))->second->Description(); + + if(isMysticPondOrItsUpgrade) //for vanila Rampart like towns { - descr+= "\n\n"+ CGI->generaltexth->allTexts[678]; - boost::algorithm::replace_first(descr,"%s",CGI->generaltexth->restypes[town->bonusValue.first]); - boost::algorithm::replace_first(descr,"%d",boost::lexical_cast(town->bonusValue.second)); + if(town->bonusValue.first == 0) //Mystic Pond produced nothing; + descr += "\n\n" + CGI->generaltexth->allTexts[677]; + else //Mystic Pond produced something; + { + descr += "\n\n" + CGI->generaltexth->allTexts[678]; + boost::algorithm::replace_first(descr, "%s", CGI->generaltexth->restypes[town->bonusValue.first]); + boost::algorithm::replace_first(descr, "%d", boost::lexical_cast(town->bonusValue.second)); + } } LOCPLINT->showInfoDialog(descr, comps); } @@ -1627,7 +1636,7 @@ const CBuilding * CFortScreen::RecruitArea::getMyBuilding() BuildingID myID = BuildingID(BuildingID::DWELL_FIRST).advance(level); if (level == GameConstants::CREATURES_PER_TOWN) - return town->town->buildings.at(BuildingID::PORTAL_OF_SUMMON); + return town->town->getSpecialBuilding(BuildingSubID::PORTAL_OF_SUMMONING); if (!town->town->buildings.count(myID)) return nullptr; diff --git a/client/windows/CCastleInterface.h b/client/windows/CCastleInterface.h index 303af627c..07dfe2d86 100644 --- a/client/windows/CCastleInterface.h +++ b/client/windows/CCastleInterface.h @@ -136,7 +136,7 @@ class CCastleBuildings : public CIntObject void enterBlacksmith(ArtifactID artifactID);//support for blacksmith + ballista yard void enterBuilding(BuildingID building);//for buildings with simple description + pic left-click messages void enterCastleGate(); - void enterFountain(BuildingID building);//Rampart's fountains + void enterFountain(const BuildingID & building, BuildingSubID::EBuildingSubID subID, BuildingID::EBuildingID upgrades);//Rampart's fountains void enterMagesGuild(); void enterTownHall(); @@ -153,7 +153,7 @@ public: void enterDwelling(int level); void enterToTheQuickRecruitmentWindow(); - void buildingClicked(BuildingID building, BuildingSubID::EBuildingSubID subID = BuildingSubID::NONE); + void buildingClicked(BuildingID building, BuildingSubID::EBuildingSubID subID = BuildingSubID::NONE, BuildingID::EBuildingID upgrades = BuildingID::NONE); void addBuilding(BuildingID building); void removeBuilding(BuildingID building);//FIXME: not tested!!! }; diff --git a/config/factions/rampart.json b/config/factions/rampart.json index 680498dc8..d08f15757 100644 --- a/config/factions/rampart.json +++ b/config/factions/rampart.json @@ -177,7 +177,7 @@ "special1": { "type" : "mysticPond" }, "horde1": { "id" : 18, "upgrades" : "dwellingLvl2" }, "horde1Upgr": { "id" : 19, "upgrades" : "dwellingUpLvl2", "requires" : [ "horde1" ], "mode" : "auto" }, - "special2": { "type" : "fountainOfFortune", "requires" : [ "special1" ] }, + "special2": { "type" : "fountainOfFortune", "upgrades" : "special1" }, "special3": { "requires" : [ "horde1" ] }, "horde2": { "id" : 24, "upgrades" : "dwellingLvl5" }, "horde2Upgr": { "id" : 25, "upgrades" : "dwellingUpLvl5", "requires" : [ "horde2" ], "mode" : "auto" }, diff --git a/lib/CTownHandler.cpp b/lib/CTownHandler.cpp index 2d609a9c9..7e7ebb68b 100644 --- a/lib/CTownHandler.cpp +++ b/lib/CTownHandler.cpp @@ -201,6 +201,21 @@ std::set CTown::getAllBuildings() const return res; } +const CBuilding * CTown::getSpecialBuilding(BuildingSubID::EBuildingSubID subID) const +{ + for(const auto & kvp : buildings) + { + if(kvp.second->subId == subID) + return buildings.at(kvp.first); + } + return nullptr; +} + +BuildingID::EBuildingID CTown::getBuildingType(BuildingSubID::EBuildingSubID subID) const +{ + auto building = getSpecialBuilding(subID); + return building == nullptr ? BuildingID::NONE : building->bid.num; +} CTownHandler::CTownHandler() { diff --git a/lib/CTownHandler.h b/lib/CTownHandler.h index 660f185a7..2944f3c8f 100644 --- a/lib/CTownHandler.h +++ b/lib/CTownHandler.h @@ -78,6 +78,13 @@ public: // returns how many times build has to be upgraded to become build si32 getDistance(BuildingID build) const; + + STRONG_INLINE + bool IsTradeBuilding() const + { + return bid == BuildingID::MARKETPLACE || subId == BuildingSubID::ARTIFACT_MERCHANT || subId == BuildingSubID::FREELANCERS_GUILD; + } + /// input: faction, bid; output: subId, height; void update792(const BuildingID & bid, BuildingSubID::EBuildingSubID & subId, ETowerHeight & height); @@ -204,6 +211,8 @@ public: std::string getFactionName() const; std::string getBuildingScope() const; std::set getAllBuildings() const; + const CBuilding * getSpecialBuilding(BuildingSubID::EBuildingSubID subID) const; + BuildingID::EBuildingID getBuildingType(BuildingSubID::EBuildingSubID subID) const; CFaction * faction; diff --git a/lib/mapObjects/CGTownInstance.cpp b/lib/mapObjects/CGTownInstance.cpp index 69c473349..6ba79fed1 100644 --- a/lib/mapObjects/CGTownInstance.cpp +++ b/lib/mapObjects/CGTownInstance.cpp @@ -739,23 +739,29 @@ std::string CGTownInstance::getObjectName() const return name + ", " + town->faction->name; } -bool CGTownInstance::townEnvisagesSpecialBuilding(BuildingSubID::EBuildingSubID bid) const +bool CGTownInstance::townEnvisagesBuilding(BuildingSubID::EBuildingSubID subId) const { - for(const auto & it : town->buildings) - { - if(it.second->subId == bid) - return true; - } - return false; + return town->getBuildingType(subId) != BuildingID::NONE; } -void CGTownInstance::initObj(CRandomGenerator & rand) -///initialize town structures +//it does not check hasBuilt(...) because this check is in the OnHeroVisit handler +bool CGTownInstance::tryAddOnePerWeekBonus(BuildingSubID::EBuildingSubID subID) +{ + auto bid = town->getBuildingType(subID); + + if(bid == BuildingID::NONE) + return false; + + bonusingBuildings.push_back(new COPWBonus(bid, subID, this)); + return true; +} + +void CGTownInstance::initObj(CRandomGenerator & rand) ///initialize town structures { blockVisit = true; - if(townEnvisagesSpecialBuilding(BuildingSubID::PORTAL_OF_SUMMONING)) //Dungeon for example - creatures.resize(GameConstants::CREATURES_PER_TOWN+1); + if(townEnvisagesBuilding(BuildingSubID::PORTAL_OF_SUMMONING)) //Dungeon for example + creatures.resize(GameConstants::CREATURES_PER_TOWN + 1); else creatures.resize(GameConstants::CREATURES_PER_TOWN); @@ -770,11 +776,8 @@ void CGTownInstance::initObj(CRandomGenerator & rand) creatures[level].second.push_back(town->creatures[level][upgradeNum]); } } - if(townEnvisagesSpecialBuilding(BuildingSubID::STABLES)) - bonusingBuildings.push_back(new COPWBonus(BuildingID::STABLES, BuildingSubID::STABLES, this)); - - if(townEnvisagesSpecialBuilding(BuildingSubID::MANA_VORTEX)) - bonusingBuildings.push_back(new COPWBonus(BuildingID::MANA_VORTEX, BuildingSubID::MANA_VORTEX, this)); + tryAddOnePerWeekBonus(BuildingSubID::STABLES); + tryAddOnePerWeekBonus(BuildingSubID::MANA_VORTEX); switch (subID) { @@ -824,45 +827,22 @@ void CGTownInstance::updateBonusingBuildings() switch (building->subId) { case BuildingSubID::PORTAL_OF_SUMMONING: - creatures.resize(GameConstants::CREATURES_PER_TOWN + 1); + if(!hasBuiltInOldWay(ETownType::DUNGEON, BuildingID::PORTAL_OF_SUMMON)) + creatures.resize(GameConstants::CREATURES_PER_TOWN + 1); break; ///'hasBuilt' checking for COPW bonuses is in the COPWBonus::onHeroVisit case BuildingSubID::STABLES: if(getBonusingBuilding(building->subId) == nullptr) - bonusingBuildings.push_back(new COPWBonus(BuildingID::STABLES, BuildingSubID::STABLES, this)); + tryAddOnePerWeekBonus(BuildingSubID::STABLES); break; case BuildingSubID::MANA_VORTEX: if(getBonusingBuilding(building->subId) == nullptr) - bonusingBuildings.push_back(new COPWBonus(BuildingID::MANA_VORTEX, BuildingSubID::MANA_VORTEX, this)); - break; - ///add new bonus if bonusing building was built in the user added towns: - case BuildingSubID::BROTHERHOOD_OF_SWORD: - if(!hasBuiltInOldWay(ETownType::CASTLE, BuildingID::BROTHERHOOD)) - addBonusIfBuilt(BuildingID::BROTHERHOOD, BuildingSubID::BROTHERHOOD_OF_SWORD, Bonus::MORALE, +2); - break; - - case BuildingSubID::FOUNTAIN_OF_FORTUNE: - if(!hasBuiltInOldWay(ETownType::RAMPART, BuildingID::FOUNTAIN_OF_FORTUNE)) - addBonusIfBuilt(BuildingID::FOUNTAIN_OF_FORTUNE, BuildingSubID::FOUNTAIN_OF_FORTUNE, Bonus::LUCK, +2); - break; - - case BuildingSubID::SPELL_POWER_GARRISON_BONUS: - if(!hasBuiltInOldWay(ETownType::INFERNO, BuildingID::STORMCLOUDS)) - addBonusIfBuilt(BuildingID::STORMCLOUDS, BuildingSubID::SPELL_POWER_GARRISON_BONUS, Bonus::PRIMARY_SKILL, +2, PrimarySkill::SPELL_POWER); - break; - - case BuildingSubID::ATTACK_GARRISON_BONUS: - if(!hasBuiltInOldWay(ETownType::FORTRESS, BuildingID::BLOOD_OBELISK)) - addBonusIfBuilt(BuildingID::BLOOD_OBELISK, BuildingSubID::ATTACK_GARRISON_BONUS, Bonus::PRIMARY_SKILL, +2, PrimarySkill::ATTACK); - break; - - case BuildingSubID::DEFENSE_GARRISON_BONUS: - if(!hasBuiltInOldWay(ETownType::FORTRESS, BuildingID::GLYPHS_OF_FEAR)) - addBonusIfBuilt(BuildingID::GLYPHS_OF_FEAR, BuildingSubID::DEFENSE_GARRISON_BONUS, Bonus::PRIMARY_SKILL, +2, PrimarySkill::DEFENSE); + tryAddOnePerWeekBonus(BuildingSubID::MANA_VORTEX); break; } } + recreateBuildingsBonuses(); ///Clear all bonuses and recreate } bool CGTownInstance::hasBuiltInOldWay(ETownType::ETownType type, BuildingID bid) const @@ -1071,7 +1051,7 @@ int CGTownInstance::getBoatType() const int CGTownInstance::getMarketEfficiency() const { - if (!hasBuilt(BuildingID::MARKETPLACE)) + if(!hasBuiltSomeTradeBuilding()) return 0; const PlayerState *p = cb->getPlayer(tempOwner); @@ -1079,7 +1059,7 @@ int CGTownInstance::getMarketEfficiency() const int marketCount = 0; for(const CGTownInstance *t : p->towns) - if(t->hasBuilt(BuildingID::MARKETPLACE)) + if(t->hasBuiltSomeTradeBuilding()) marketCount++; return marketCount; @@ -1095,18 +1075,16 @@ bool CGTownInstance::allowsTrade(EMarketMode::EMarketMode mode) const case EMarketMode::ARTIFACT_RESOURCE: case EMarketMode::RESOURCE_ARTIFACT: - return hasBuilt(BuildingID::ARTIFACT_MERCHANT, ETownType::TOWER) - || hasBuilt(BuildingID::ARTIFACT_MERCHANT, ETownType::DUNGEON) - || hasBuilt(BuildingID::ARTIFACT_MERCHANT, ETownType::CONFLUX); + return hasBuilt(BuildingSubID::ARTIFACT_MERCHANT); case EMarketMode::CREATURE_RESOURCE: - return hasBuilt(BuildingID::FREELANCERS_GUILD, ETownType::STRONGHOLD); + return hasBuilt(BuildingSubID::FREELANCERS_GUILD); case EMarketMode::CREATURE_UNDEAD: - return hasBuilt(BuildingID::SKELETON_TRANSFORMER, ETownType::NECROPOLIS); + return hasBuilt(BuildingSubID::CREATURE_TRANSFORMER); case EMarketMode::RESOURCE_SKILL: - return hasBuilt(BuildingID::MAGIC_UNIVERSITY, ETownType::CONFLUX); + return hasBuilt(BuildingSubID::MAGIC_UNIVERSITY); default: assert(0); return false; @@ -1195,13 +1173,13 @@ void CGTownInstance::recreateBuildingsBonuses() removeBonus(b); //tricky! -> checks tavern only if no bratherhood of sword or not a castle - if(!addBonusIfBuilt(BuildingID::BROTHERHOOD, BuildingSubID::BROTHERHOOD_OF_SWORD, Bonus::MORALE, +2)) + if(!addBonusIfBuilt(BuildingSubID::BROTHERHOOD_OF_SWORD, Bonus::MORALE, +2)) addBonusIfBuilt(BuildingID::TAVERN, Bonus::MORALE, +1); - addBonusIfBuilt(BuildingID::FOUNTAIN_OF_FORTUNE, BuildingSubID::FOUNTAIN_OF_FORTUNE, Bonus::LUCK, +2); //fountain of fortune - addBonusIfBuilt(BuildingID::STORMCLOUDS, BuildingSubID::SPELL_POWER_GARRISON_BONUS, Bonus::PRIMARY_SKILL, +2, PrimarySkill::SPELL_POWER);//works as Brimstone Clouds - addBonusIfBuilt(BuildingID::BLOOD_OBELISK, BuildingSubID::ATTACK_GARRISON_BONUS, Bonus::PRIMARY_SKILL, +2, PrimarySkill::ATTACK);//works as Blood Obelisk - addBonusIfBuilt(BuildingID::GLYPHS_OF_FEAR, BuildingSubID::DEFENSE_GARRISON_BONUS, Bonus::PRIMARY_SKILL, +2, PrimarySkill::DEFENSE);//works as Glyphs of Fear + addBonusIfBuilt(BuildingSubID::FOUNTAIN_OF_FORTUNE, Bonus::LUCK, +2); //fountain of fortune + addBonusIfBuilt(BuildingSubID::SPELL_POWER_GARRISON_BONUS, Bonus::PRIMARY_SKILL, +2, PrimarySkill::SPELL_POWER);//works as Brimstone Clouds + addBonusIfBuilt(BuildingSubID::ATTACK_GARRISON_BONUS, Bonus::PRIMARY_SKILL, +2, PrimarySkill::ATTACK);//works as Blood Obelisk + addBonusIfBuilt(BuildingSubID::DEFENSE_GARRISON_BONUS, Bonus::PRIMARY_SKILL, +2, PrimarySkill::DEFENSE);//works as Glyphs of Fear if(subID == ETownType::CASTLE) //castle { @@ -1237,23 +1215,22 @@ void CGTownInstance::recreateBuildingsBonuses() } } -bool CGTownInstance::addBonusIfBuilt(BuildingID bid, BuildingSubID::EBuildingSubID subId, Bonus::BonusType type, int val, int subtype) +bool CGTownInstance::addBonusIfBuilt(BuildingSubID::EBuildingSubID subId, Bonus::BonusType type, int val, int subtype) { - bool hasBuilt = false; + BuildingID currentBid = BuildingID::NONE; std::ostringstream descr; - for (const auto & bid : builtBuildings) + for(const auto & bid : builtBuildings) { if (town->buildings.at(bid)->subId == subId) { descr << town->buildings.at(bid)->Name(); - hasBuilt = true; + currentBid = bid; break; } } - if(hasBuilt) - hasBuilt = addBonusImpl(bid, type, val, emptyPropagator, descr.str(), subtype); - return hasBuilt; + return currentBid == BuildingID::NONE ? false + : addBonusImpl(currentBid, type, val, emptyPropagator, descr.str(), subtype); } bool CGTownInstance::addBonusIfBuilt(BuildingID building, Bonus::BonusType type, int val, int subtype) @@ -1390,6 +1367,17 @@ const CGTownBuilding * CGTownInstance::getBonusingBuilding(BuildingSubID::EBuild return nullptr; } + +bool CGTownInstance::hasBuiltSomeTradeBuilding() const +{ + for (const auto & bid : builtBuildings) + { + if(town->buildings.at(bid)->IsTradeBuilding()) + return true; + } + return false; +} + bool CGTownInstance::hasBuilt(BuildingSubID::EBuildingSubID buildingID) const { for(const auto & bid : builtBuildings) diff --git a/lib/mapObjects/CGTownInstance.h b/lib/mapObjects/CGTownInstance.h index 85da7c8e2..1d3645e64 100644 --- a/lib/mapObjects/CGTownInstance.h +++ b/lib/mapObjects/CGTownInstance.h @@ -262,7 +262,7 @@ public: void deserializationFix(); void recreateBuildingsBonuses(); ///bid: param to bind a building with a bonus, subId: param to check if already built - bool addBonusIfBuilt(BuildingID bid, BuildingSubID::EBuildingSubID subId, Bonus::BonusType type, int val, int subtype = -1); + bool addBonusIfBuilt(BuildingSubID::EBuildingSubID subId, Bonus::BonusType type, int val, int subtype = -1); bool addBonusIfBuilt(BuildingID building, Bonus::BonusType type, int val, TPropagatorPtr &prop, int subtype = -1); //returns true if building is built and bonus has been added bool addBonusIfBuilt(BuildingID building, Bonus::BonusType type, int val, int subtype = -1); //convienence version of above void setVisitingHero(CGHeroInstance *h); @@ -295,6 +295,7 @@ public: bool hasFort() const; bool hasCapitol() const; const CGTownBuilding * getBonusingBuilding(BuildingSubID::EBuildingSubID subId) const; + bool hasBuiltSomeTradeBuilding() const; //checks if special building with type buildingID is constructed bool hasBuilt(BuildingSubID::EBuildingSubID buildingID) const; //checks if building is constructed and town has same subID @@ -313,7 +314,6 @@ public: void removeCapitols (PlayerColor owner) const; void clearArmy() const; void addHeroToStructureVisitors(const CGHeroInstance *h, si64 structureInstanceID) const; //hero must be visiting or garrisoned in town - bool townEnvisagesSpecialBuilding(BuildingSubID::EBuildingSubID bid) const; const CTown * getTown() const ; @@ -330,13 +330,17 @@ public: void afterAddToMap(CMap * map) override; static void reset(); + protected: static TPropagatorPtr emptyPropagator; void setPropertyDer(ui8 what, ui32 val) override; void serializeJsonOptions(JsonSerializeFormat & handler) override; + private: int getDwellingBonus(const std::vector& creatureIds, const std::vector >& dwellings) const; void updateBonusingBuildings(); bool hasBuiltInOldWay(ETownType::ETownType type, BuildingID bid) const; bool addBonusImpl(BuildingID building, Bonus::BonusType type, int val, TPropagatorPtr & prop, const std::string & description, int subtype = -1); + bool townEnvisagesBuilding(BuildingSubID::EBuildingSubID bid) const; + bool tryAddOnePerWeekBonus(BuildingSubID::EBuildingSubID subID); }; diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 7767c548d..07d3f9bf6 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -1808,7 +1808,7 @@ void CGameHandler::newTurn() handleTownEvents(t, n); if (newWeek) //first day of week { - if (t->hasBuilt(BuildingID::PORTAL_OF_SUMMON, ETownType::DUNGEON)) + if (t->hasBuilt(BuildingSubID::PORTAL_OF_SUMMONING)) setPortalDwelling(t, true, (n.specialWeek == NewTurn::PLAGUE ? true : false)); //set creatures for Portal of Summoning if (!firstTurn) @@ -2391,7 +2391,7 @@ void CGameHandler::setOwner(const CGObjectInstance * obj, PlayerColor owner) { if (owner < PlayerColor::PLAYER_LIMIT) //new owner is real player { - if (town->hasBuilt(BuildingID::PORTAL_OF_SUMMON, ETownType::DUNGEON)) + if (town->hasBuilt(BuildingSubID::PORTAL_OF_SUMMONING)) setPortalDwelling(town, true, false); } @@ -2414,7 +2414,7 @@ void CGameHandler::setOwner(const CGObjectInstance * obj, PlayerColor owner) { for (const CGTownInstance * t : getPlayer(owner)->towns) { - if (t->hasBuilt(BuildingID::PORTAL_OF_SUMMON, ETownType::DUNGEON)) + if (t->hasBuilt(BuildingSubID::PORTAL_OF_SUMMONING)) setPortalDwelling(t);//set initial creatures for all portals of summoning } } @@ -3076,7 +3076,7 @@ bool CGameHandler::buildStructure(ObjectInstanceID tid, BuildingID requestedID, ssi.creatures[level].second.push_back(crea->idNumber); sendAndApply(&ssi); } - if (t->subID == ETownType::DUNGEON && buildingID == BuildingID::PORTAL_OF_SUMMON) + if (t->town->buildings.at(buildingID)->subId == BuildingSubID::PORTAL_OF_SUMMONING) { setPortalDwelling(t); } @@ -3541,7 +3541,7 @@ bool CGameHandler::buyArtifact(ObjectInstanceID hid, ArtifactID aid) COMPLAIN_RET_FALSE_IF(getPlayer(hero->getOwner())->resources.at(Res::GOLD) < price, "Not enough gold!"); if ((town->hasBuilt(BuildingID::BLACKSMITH) && town->town->warMachine == aid) - || ((town->hasBuilt(BuildingID::BALLISTA_YARD, ETownType::STRONGHOLD)) && aid == ArtifactID::BALLISTA)) + || (town->hasBuilt(BuildingSubID::BALLISTA_YARD) && aid == ArtifactID::BALLISTA)) { giveResource(hero->getOwner(),Res::GOLD,-price); return giveHeroNewArtifact(hero, art);