mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Merge branch 'develop' of https://github.com/vcmi/vcmi into develop
This commit is contained in:
		| @@ -275,7 +275,7 @@ TSubgoal Win::whatToDoToAchieve() | ||||
| 					// 0.85 -> radius now 2 tiles | ||||
| 					// 0.95 -> 1 tile radius, position is fully known | ||||
| 					// AFAIK H3 AI does something like this | ||||
| 					int3 grailPos = cb->getGrailPos(ratio); | ||||
| 					int3 grailPos = cb->getGrailPos(&ratio); | ||||
| 					if(ratio > 0.99) | ||||
| 					{ | ||||
| 						return sptr (Goals::DigAtTile(grailPos)); | ||||
|   | ||||
| @@ -2170,7 +2170,7 @@ void CPlayerInterface::showPuzzleMap() | ||||
|  | ||||
| 	//TODO: interface should not know the real position of Grail... | ||||
| 	double ratio = 0; | ||||
| 	int3 grailPos = cb->getGrailPos(ratio); | ||||
| 	int3 grailPos = cb->getGrailPos(&ratio); | ||||
|  | ||||
| 	GH.pushInt(new CPuzzleWindow(grailPos, ratio)); | ||||
| } | ||||
|   | ||||
| @@ -219,18 +219,20 @@ void CClient::endGame( bool closeConnection /*= true*/ ) | ||||
| 	GH.curInt = nullptr; | ||||
| 	{ | ||||
| 		boost::unique_lock<boost::recursive_mutex> un(*LOCPLINT->pim); | ||||
|         logNetwork->infoStream() << "Ending current game!"; | ||||
| 		logNetwork->infoStream() << "Ending current game!"; | ||||
| 		if(GH.topInt()) | ||||
| 		{ | ||||
| 			GH.topInt()->deactivate(); | ||||
| 		} | ||||
| 		GH.listInt.clear(); | ||||
| 		GH.objsToBlit.clear(); | ||||
| 		GH.statusbar = nullptr; | ||||
|         logNetwork->infoStream() << "Removed GUI."; | ||||
| 		logNetwork->infoStream() << "Removed GUI."; | ||||
|  | ||||
| 		vstd::clear_pointer(const_cast<CGameInfo*>(CGI)->mh); | ||||
| 		vstd::clear_pointer(gs); | ||||
|  | ||||
|         logNetwork->infoStream() << "Deleted mapHandler and gameState."; | ||||
| 		logNetwork->infoStream() << "Deleted mapHandler and gameState."; | ||||
| 		LOCPLINT = nullptr; | ||||
| 	} | ||||
|  | ||||
| @@ -238,9 +240,9 @@ void CClient::endGame( bool closeConnection /*= true*/ ) | ||||
| 	battleints.clear(); | ||||
| 	callbacks.clear(); | ||||
| 	battleCallbacks.clear(); | ||||
|     logNetwork->infoStream() << "Deleted playerInts."; | ||||
|  | ||||
|     logNetwork->infoStream() << "Client stopped."; | ||||
| 	CGObelisk::reset(); | ||||
| 	logNetwork->infoStream() << "Deleted playerInts."; | ||||
| 	logNetwork->infoStream() << "Client stopped."; | ||||
| } | ||||
|  | ||||
| #if 1 | ||||
|   | ||||
| @@ -727,15 +727,16 @@ int CPlayerSpecificInfoCallback::getHeroSerial(const CGHeroInstance * hero, bool | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| int3 CPlayerSpecificInfoCallback::getGrailPos( double &outKnownRatio ) | ||||
| int3 CPlayerSpecificInfoCallback::getGrailPos( double *outKnownRatio ) | ||||
| { | ||||
| 	if (!player || CGObelisk::obeliskCount == 0) | ||||
| 	{ | ||||
| 		outKnownRatio = 0.0; | ||||
| 		*outKnownRatio = 0.0; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		outKnownRatio = static_cast<double>(CGObelisk::visited[gs->getPlayerTeam(*player)->id]) / CGObelisk::obeliskCount; | ||||
| 		*outKnownRatio = static_cast<double>(CGObelisk::visited[gs->getPlayerTeam(*player)->id]) | ||||
| 			/ CGObelisk::obeliskCount; | ||||
| 	} | ||||
| 	return gs->map->grailPos; | ||||
| } | ||||
|   | ||||
| @@ -125,7 +125,7 @@ class DLL_LINKAGE CPlayerSpecificInfoCallback : public CGameInfoCallback | ||||
| public: | ||||
| 	int howManyTowns() const; | ||||
| 	int howManyHeroes(bool includeGarrisoned = true) const; | ||||
| 	int3 getGrailPos(double &outKnownRatio); | ||||
| 	int3 getGrailPos(double *outKnownRatio); | ||||
| 	boost::optional<PlayerColor> getMyColor() const; | ||||
|  | ||||
| 	std::vector <const CGTownInstance *> getTownsInfo(bool onlyOur = true) const; //true -> only owned; false -> all visible | ||||
| @@ -139,7 +139,7 @@ public: | ||||
|  | ||||
| 	int getResourceAmount(Res::ERes type) const; | ||||
| 	TResources getResourceAmount() const; | ||||
| 	const std::vector< std::vector< std::vector<ui8> > > & getVisibilityMap()const; //returns visibility map  | ||||
| 	const std::vector< std::vector< std::vector<ui8> > > & getVisibilityMap()const; //returns visibility map | ||||
| 	const PlayerSettings * getPlayerSettings(PlayerColor color) const; | ||||
| }; | ||||
|  | ||||
| @@ -154,4 +154,3 @@ public: | ||||
|  | ||||
| 	virtual void showInfoDialog(const std::string &msg, PlayerColor player); | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -554,7 +554,7 @@ void CModHandler::loadConfigFromFile (std::string name) | ||||
| 	std::string paths; | ||||
| 	for(auto& p : CResourceHandler::get()->getResourceNames(ResourceID("config/" + name))) | ||||
| 	{ | ||||
| 		paths += p + ", "; | ||||
| 		paths += p.string() + ", "; | ||||
| 	} | ||||
| 	paths = paths.substr(0, paths.size() - 2); | ||||
| 	logGlobal->debugStream() << "Loading hardcoded features settings from [" << paths << "], result:"; | ||||
|   | ||||
| @@ -27,7 +27,7 @@ | ||||
| #include "mapping/CCampaignHandler.h" //for CCampaignState | ||||
| #include "rmg/CMapGenerator.h" // for CMapGenOptions | ||||
|  | ||||
| const ui32 version = 756; | ||||
| const ui32 version = 757; | ||||
| const ui32 minSupportedVersion = 753; | ||||
|  | ||||
| class CISer; | ||||
|   | ||||
| @@ -87,9 +87,9 @@ boost::optional<boost::filesystem::path> CFilesystemList::getResourceName(const | ||||
| 	return boost::optional<boost::filesystem::path>(); | ||||
| } | ||||
|  | ||||
| std::set<std::string> CFilesystemList::getResourceNames(const ResourceID & resourceName) const | ||||
| std::set<boost::filesystem::path> CFilesystemList::getResourceNames(const ResourceID & resourceName) const | ||||
| { | ||||
| 	std::set<std::string> paths; | ||||
| 	std::set<boost::filesystem::path> paths; | ||||
| 	for(auto& loader : getResourcesWithName(resourceName)) | ||||
| 	{ | ||||
| 		auto rn = loader->getResourceName(resourceName); | ||||
|   | ||||
| @@ -1,87 +1,87 @@ | ||||
| #pragma once | ||||
|  | ||||
| /* | ||||
|  * AdapterLoaders.h, part of VCMI engine | ||||
|  * | ||||
|  * Authors: listed in file AUTHORS in main folder | ||||
|  * | ||||
|  * License: GNU General Public License v2.0 or later | ||||
|  * Full text of license available in license.txt file, in main folder | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #include "ISimpleResourceLoader.h" | ||||
| #include "ResourceID.h" | ||||
|  | ||||
| class CFileInfo; | ||||
| class CInputStream; | ||||
| class JsonNode; | ||||
|  | ||||
| /** | ||||
|  * Class that implements file mapping (aka *nix symbolic links) | ||||
|  * Uses json file as input, content is map: | ||||
|  * "fileA.txt" : "fileB.txt" | ||||
|  * Note that extension is necessary, but used only to determine type | ||||
|  * | ||||
|  * fileA - file which will be replaced | ||||
|  * fileB - file which will be used as replacement | ||||
|  */ | ||||
| class DLL_LINKAGE CMappedFileLoader : public ISimpleResourceLoader | ||||
| { | ||||
| public: | ||||
| 	/** | ||||
| 	 * Ctor. | ||||
| 	 * | ||||
| 	 * @param config Specifies filesystem configuration | ||||
| 	 */ | ||||
| 	explicit CMappedFileLoader(const std::string &mountPoint, const JsonNode & config); | ||||
|  | ||||
| 	/// Interface implementation | ||||
| 	/// @see ISimpleResourceLoader | ||||
| 	std::unique_ptr<CInputStream> load(const ResourceID & resourceName) const override; | ||||
| 	bool existsResource(const ResourceID & resourceName) const override; | ||||
| 	std::string getMountPoint() const override; | ||||
| 	boost::optional<boost::filesystem::path> getResourceName(const ResourceID & resourceName) const override; | ||||
| 	std::unordered_set<ResourceID> getFilteredFiles(std::function<bool(const ResourceID &)> filter) const override; | ||||
|  | ||||
| private: | ||||
| 	/** A list of files in this map | ||||
| 	 * key = ResourceID for resource loader | ||||
| 	 * value = ResourceID to which file this request will be redirected | ||||
| 	*/ | ||||
| 	std::unordered_map<ResourceID, ResourceID> fileList; | ||||
| }; | ||||
|  | ||||
| class DLL_LINKAGE CFilesystemList : public ISimpleResourceLoader | ||||
| { | ||||
| 	std::vector<std::unique_ptr<ISimpleResourceLoader> > loaders; | ||||
|  | ||||
| 	std::set<ISimpleResourceLoader *> writeableLoaders; | ||||
|  | ||||
| 	//FIXME: this is only compile fix, should be removed in the end | ||||
| 	CFilesystemList(CFilesystemList &) = delete; | ||||
| 	CFilesystemList &operator=(CFilesystemList &) = delete; | ||||
| #pragma once | ||||
|  | ||||
| public: | ||||
| 	CFilesystemList(); | ||||
| 	~CFilesystemList(); | ||||
| 	/// Interface implementation | ||||
| 	/// @see ISimpleResourceLoader | ||||
| 	std::unique_ptr<CInputStream> load(const ResourceID & resourceName) const override; | ||||
| 	bool existsResource(const ResourceID & resourceName) const override; | ||||
| 	std::string getMountPoint() const override; | ||||
| 	boost::optional<boost::filesystem::path> getResourceName(const ResourceID & resourceName) const override; | ||||
| 	std::set<std::string> getResourceNames(const ResourceID & resourceName) const override; | ||||
| 	std::unordered_set<ResourceID> getFilteredFiles(std::function<bool(const ResourceID &)> filter) const override; | ||||
| 	bool createResource(std::string filename, bool update = false) override; | ||||
| 	std::vector<const ISimpleResourceLoader *> getResourcesWithName(const ResourceID & resourceName) const override; | ||||
|  | ||||
| 	/** | ||||
| 	 * Adds a resource loader to the loaders list | ||||
| 	 * Passes loader ownership to this object | ||||
| 	 * | ||||
| 	 * @param loader The simple resource loader object to add | ||||
| 	 * @param writeable - resource shall be treated as writeable | ||||
| 	 */ | ||||
| 	void addLoader(ISimpleResourceLoader * loader, bool writeable); | ||||
| }; | ||||
| /* | ||||
|  * AdapterLoaders.h, part of VCMI engine | ||||
|  * | ||||
|  * Authors: listed in file AUTHORS in main folder | ||||
|  * | ||||
|  * License: GNU General Public License v2.0 or later | ||||
|  * Full text of license available in license.txt file, in main folder | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #include "ISimpleResourceLoader.h" | ||||
| #include "ResourceID.h" | ||||
|  | ||||
| class CFileInfo; | ||||
| class CInputStream; | ||||
| class JsonNode; | ||||
|  | ||||
| /** | ||||
|  * Class that implements file mapping (aka *nix symbolic links) | ||||
|  * Uses json file as input, content is map: | ||||
|  * "fileA.txt" : "fileB.txt" | ||||
|  * Note that extension is necessary, but used only to determine type | ||||
|  * | ||||
|  * fileA - file which will be replaced | ||||
|  * fileB - file which will be used as replacement | ||||
|  */ | ||||
| class DLL_LINKAGE CMappedFileLoader : public ISimpleResourceLoader | ||||
| { | ||||
| public: | ||||
| 	/** | ||||
| 	 * Ctor. | ||||
| 	 * | ||||
| 	 * @param config Specifies filesystem configuration | ||||
| 	 */ | ||||
| 	explicit CMappedFileLoader(const std::string &mountPoint, const JsonNode & config); | ||||
|  | ||||
| 	/// Interface implementation | ||||
| 	/// @see ISimpleResourceLoader | ||||
| 	std::unique_ptr<CInputStream> load(const ResourceID & resourceName) const override; | ||||
| 	bool existsResource(const ResourceID & resourceName) const override; | ||||
| 	std::string getMountPoint() const override; | ||||
| 	boost::optional<boost::filesystem::path> getResourceName(const ResourceID & resourceName) const override; | ||||
| 	std::unordered_set<ResourceID> getFilteredFiles(std::function<bool(const ResourceID &)> filter) const override; | ||||
|  | ||||
| private: | ||||
| 	/** A list of files in this map | ||||
| 	 * key = ResourceID for resource loader | ||||
| 	 * value = ResourceID to which file this request will be redirected | ||||
| 	*/ | ||||
| 	std::unordered_map<ResourceID, ResourceID> fileList; | ||||
| }; | ||||
|  | ||||
| class DLL_LINKAGE CFilesystemList : public ISimpleResourceLoader | ||||
| { | ||||
| 	std::vector<std::unique_ptr<ISimpleResourceLoader> > loaders; | ||||
|  | ||||
| 	std::set<ISimpleResourceLoader *> writeableLoaders; | ||||
|  | ||||
| 	//FIXME: this is only compile fix, should be removed in the end | ||||
| 	CFilesystemList(CFilesystemList &) = delete; | ||||
| 	CFilesystemList &operator=(CFilesystemList &) = delete; | ||||
|  | ||||
| public: | ||||
| 	CFilesystemList(); | ||||
| 	~CFilesystemList(); | ||||
| 	/// Interface implementation | ||||
| 	/// @see ISimpleResourceLoader | ||||
| 	std::unique_ptr<CInputStream> load(const ResourceID & resourceName) const override; | ||||
| 	bool existsResource(const ResourceID & resourceName) const override; | ||||
| 	std::string getMountPoint() const override; | ||||
| 	boost::optional<boost::filesystem::path> getResourceName(const ResourceID & resourceName) const override; | ||||
| 	std::set<boost::filesystem::path> getResourceNames(const ResourceID & resourceName) const override; | ||||
| 	std::unordered_set<ResourceID> getFilteredFiles(std::function<bool(const ResourceID &)> filter) const override; | ||||
| 	bool createResource(std::string filename, bool update = false) override; | ||||
| 	std::vector<const ISimpleResourceLoader *> getResourcesWithName(const ResourceID & resourceName) const override; | ||||
|  | ||||
| 	/** | ||||
| 	 * Adds a resource loader to the loaders list | ||||
| 	 * Passes loader ownership to this object | ||||
| 	 * | ||||
| 	 * @param loader The simple resource loader object to add | ||||
| 	 * @param writeable - resource shall be treated as writeable | ||||
| 	 */ | ||||
| 	void addLoader(ISimpleResourceLoader * loader, bool writeable); | ||||
| }; | ||||
|   | ||||
| @@ -58,9 +58,9 @@ public: | ||||
| 	 * | ||||
| 	 * @return std::set with names. | ||||
| 	 */ | ||||
| 	virtual std::set<std::string> getResourceNames(const ResourceID & resourceName) const | ||||
| 	virtual std::set<boost::filesystem::path> getResourceNames(const ResourceID & resourceName) const | ||||
| 	{ | ||||
| 		std::set<std::string> result; | ||||
| 		std::set<boost::filesystem::path> result; | ||||
| 		auto rn = getResourceName(resourceName); | ||||
| 		if(rn) | ||||
| 		{ | ||||
|   | ||||
| @@ -416,6 +416,7 @@ void CGSeerHut::init() | ||||
| { | ||||
| 	seerName = *RandomGeneratorUtil::nextItem(VLC->generaltexth->seerNames, cb->gameState()->getRandomGenerator()); | ||||
| 	quest->textOption = cb->gameState()->getRandomGenerator().nextInt(2); | ||||
| 	quest->completedOption = cb->gameState()->getRandomGenerator().nextInt(1, 5); | ||||
| } | ||||
|  | ||||
| void CGSeerHut::initObj() | ||||
| @@ -435,7 +436,7 @@ void CGSeerHut::initObj() | ||||
| 	else | ||||
| 	{ | ||||
| 		quest->progress = CQuest::COMPLETE; | ||||
| 		quest->firstVisitText = VLC->generaltexth->seerEmpty[quest->textOption]; | ||||
| 		quest->firstVisitText = VLC->generaltexth->seerEmpty[quest->completedOption]; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -533,7 +534,7 @@ void CGSeerHut::newTurn() const | ||||
| { | ||||
| 	if (quest->lastDay >= 0 && quest->lastDay < cb->getDate()-1) //time is up | ||||
| 	{ | ||||
| 		cb->setObjProperty (id, 10, CQuest::COMPLETE); | ||||
| 		cb->setObjProperty (id, CGSeerHut::OBJPROP_VISITED, CQuest::COMPLETE); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -550,7 +551,7 @@ void CGSeerHut::onHeroVisit( const CGHeroInstance * h ) const | ||||
| 		if (firstVisit) | ||||
| 		{ | ||||
| 			isCustom = quest->isCustomFirst; | ||||
| 			cb->setObjProperty (id, 10, CQuest::IN_PROGRESS); | ||||
| 			cb->setObjProperty (id, CGSeerHut::OBJPROP_VISITED, CQuest::IN_PROGRESS); | ||||
|  | ||||
| 			AddQuest aq; | ||||
| 			aq.quest = QuestInfo (quest, this, visitablePos()); | ||||
| @@ -582,7 +583,7 @@ void CGSeerHut::onHeroVisit( const CGHeroInstance * h ) const | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		iw.text << VLC->generaltexth->seerEmpty[quest->textOption]; | ||||
| 		iw.text << VLC->generaltexth->seerEmpty[quest->completedOption]; | ||||
| 		if (ID == Obj::SEER_HUT) | ||||
| 			iw.text.addReplacement(seerName); | ||||
| 		cb->showInfoDialog(&iw); | ||||
| @@ -657,7 +658,7 @@ void CGSeerHut::finishQuest(const CGHeroInstance * h, ui32 accept) const | ||||
| 			default: | ||||
| 				break; | ||||
| 		} | ||||
| 		cb->setObjProperty (id, 10, CQuest::COMPLETE); //mission complete | ||||
| 		cb->setObjProperty (id, CGSeerHut::OBJPROP_VISITED, CQuest::COMPLETE); //mission complete | ||||
| 		completeQuest(h); //make sure to remove QuestGuard at the very end | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -37,8 +37,11 @@ public: | ||||
| 	std::vector<CStackBasicDescriptor> m6creatures; //pair[cre id, cre count], CreatureSet info irrelevant | ||||
| 	std::vector<ui32> m7resources; //TODO: use resourceset? | ||||
|  | ||||
| 	//following field are used only for kill creature/hero missions, the original objects became inaccessible after their removal, so we need to store info needed for messages / hover text | ||||
| 	// following fields are used only for kill creature/hero missions, the original | ||||
| 	// objects became inaccessible after their removal, so we need to store info | ||||
| 	// needed for messages / hover text | ||||
| 	ui8 textOption; | ||||
| 	ui8 completedOption; | ||||
| 	CStackBasicDescriptor stackToKill; | ||||
| 	ui8 stackDirection; | ||||
| 	std::string heroName; //backup of hero name | ||||
| @@ -66,7 +69,16 @@ public: | ||||
| 	{ | ||||
| 		h & qid & missionType & progress & lastDay & m13489val & m2stats & m5arts & m6creatures & m7resources | ||||
| 			& textOption & stackToKill & stackDirection & heroName & heroPortrait | ||||
| 			& firstVisitText & nextVisitText & completedText & isCustomFirst & isCustomNext & isCustomComplete; | ||||
| 			& firstVisitText & nextVisitText & completedText & isCustomFirst | ||||
| 			& isCustomNext & isCustomComplete; | ||||
| 		if(version >= 757) | ||||
| 		{ | ||||
| 			h & completedOption; | ||||
| 		} | ||||
| 		else if(!h.saving) | ||||
| 		{ | ||||
| 			completedOption = 1; | ||||
| 		} | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| @@ -118,6 +130,8 @@ public: | ||||
| 		h & rewardType & rID & rVal & seerName; | ||||
| 	} | ||||
| protected: | ||||
| 	static constexpr int OBJPROP_VISITED = 10; | ||||
|  | ||||
| 	void setPropertyDer(ui8 what, ui32 val) override; | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -24,7 +24,7 @@ | ||||
| #include "../CPlayerState.h" | ||||
|  | ||||
| std::map <si32, std::vector<ObjectInstanceID> > CGMagi::eyelist; | ||||
| ui8 CGObelisk::obeliskCount; //how many obelisks are on map | ||||
| ui8 CGObelisk::obeliskCount = 0; //how many obelisks are on map | ||||
| std::map<TeamID, ui8> CGObelisk::visited; //map: team_id => how many obelisks has been visited | ||||
|  | ||||
| ///helpers | ||||
| @@ -60,7 +60,7 @@ static std::string & visitedTxt(const bool visited) | ||||
|  | ||||
| void CPlayersVisited::setPropertyDer( ui8 what, ui32 val ) | ||||
| { | ||||
| 	if(what == 10) | ||||
| 	if(what == CPlayersVisited::OBJPROP_VISITED) | ||||
| 		players.insert(PlayerColor(val)); | ||||
| } | ||||
|  | ||||
| @@ -1314,7 +1314,7 @@ void CGWitchHut::onHeroVisit( const CGHeroInstance * h ) const | ||||
| 	iw.soundID = soundBase::gazebo; | ||||
| 	iw.player = h->getOwner(); | ||||
| 	if(!wasVisited(h->tempOwner)) | ||||
| 		cb->setObjProperty(id, 10, h->tempOwner.getNum()); | ||||
| 		cb->setObjProperty(id, CGWitchHut::OBJPROP_VISITED, h->tempOwner.getNum()); | ||||
| 	ui32 txt_id; | ||||
| 	if(h->getSecSkillLevel(SecondarySkill(ability))) //you already know this skill | ||||
| 	{ | ||||
| @@ -1424,7 +1424,7 @@ void CGShrine::onHeroVisit( const CGHeroInstance * h ) const | ||||
| 	} | ||||
|  | ||||
| 	if(!wasVisited(h->tempOwner)) | ||||
| 		cb->setObjProperty(id, 10, h->tempOwner.getNum()); | ||||
| 		cb->setObjProperty(id, CGShrine::OBJPROP_VISITED, h->tempOwner.getNum()); | ||||
|  | ||||
| 	InfoWindow iw; | ||||
| 	iw.soundID = soundBase::temple; | ||||
| @@ -1826,7 +1826,7 @@ void CCartographer::blockingDialogAnswered(const CGHeroInstance *hero, ui32 answ | ||||
| 		//water = 0; land = 1; underground = 2; | ||||
| 		cb->getAllTiles (fw.tiles, hero->tempOwner, subID - 1, !subID + 1); //reveal appropriate tiles | ||||
| 		cb->sendAndApply (&fw); | ||||
| 		cb->setObjProperty (id, 10, hero->tempOwner.getNum()); | ||||
| 		cb->setObjProperty (id, CCartographer::OBJPROP_VISITED, hero->tempOwner.getNum()); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -1848,11 +1848,16 @@ void CGObelisk::onHeroVisit( const CGHeroInstance * h ) const | ||||
| 		iw.text.addTxt(MetaString::ADVOB_TXT, 96); | ||||
| 		cb->sendAndApply(&iw); | ||||
|  | ||||
| 		cb->setObjProperty(id, 20, h->tempOwner.getNum()); //increment general visited obelisks counter | ||||
| 		// increment general visited obelisks counter | ||||
| 		cb->setObjProperty(id, CGObelisk::OBJPROP_INC, team.getNum()); | ||||
|  | ||||
| 		openWindow(OpenWindow::PUZZLE_MAP, h->tempOwner.getNum()); | ||||
|  | ||||
| 		cb->setObjProperty(id, 10, h->tempOwner.getNum()); //mark that particular obelisk as visited | ||||
| 		// mark that particular obelisk as visited for all players in the team | ||||
| 		for (auto & color : ts->players) | ||||
| 		{ | ||||
| 			cb->setObjProperty(id, CGObelisk::OBJPROP_VISITED, color.getNum()); | ||||
| 		} | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| @@ -1867,6 +1872,12 @@ void CGObelisk::initObj() | ||||
| 	obeliskCount++; | ||||
| } | ||||
|  | ||||
| void CGObelisk::reset() | ||||
| { | ||||
| 	obeliskCount = 0; | ||||
| 	visited.clear(); | ||||
| } | ||||
|  | ||||
| std::string CGObelisk::getHoverText(PlayerColor player) const | ||||
| { | ||||
| 	return getObjectName() + " " + visitedTxt(wasVisited(player)); | ||||
| @@ -1874,20 +1885,26 @@ std::string CGObelisk::getHoverText(PlayerColor player) const | ||||
|  | ||||
| void CGObelisk::setPropertyDer( ui8 what, ui32 val ) | ||||
| { | ||||
| 	CPlayersVisited::setPropertyDer(what, val); | ||||
| 	switch(what) | ||||
| 	{ | ||||
| 	case 20: | ||||
| 		assert(val < PlayerColor::PLAYER_LIMIT_I); | ||||
| 		visited[TeamID(val)]++; | ||||
| 		case CGObelisk::OBJPROP_INC: | ||||
| 			{ | ||||
| 				assert(val < PlayerColor::PLAYER_LIMIT_I); | ||||
| 				auto progress = ++visited[TeamID(val)]; | ||||
| 				logGlobal->debugStream() << boost::format("Player %d: obelisk progress %d / %d") | ||||
| 					% val % static_cast<int>(progress) % static_cast<int>(obeliskCount); | ||||
|  | ||||
| 		if(visited[TeamID(val)] > obeliskCount) | ||||
| 		{ | ||||
|             logGlobal->errorStream() << "Error: Visited " << visited[TeamID(val)] << "\t\t" << obeliskCount; | ||||
| 			assert(0); | ||||
| 		} | ||||
| 				if(progress > obeliskCount) | ||||
| 				{ | ||||
| 					logGlobal->errorStream() << "Error: Visited " << progress << "\t\t" << obeliskCount; | ||||
| 					assert(0); | ||||
| 				} | ||||
|  | ||||
| 		break; | ||||
| 				break; | ||||
| 			} | ||||
| 		default: | ||||
| 			CPlayersVisited::setPropertyDer(what, val); | ||||
| 			break; | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -28,6 +28,8 @@ public: | ||||
| 		h & static_cast<CGObjectInstance&>(*this); | ||||
| 		h & players; | ||||
| 	} | ||||
|  | ||||
| 	static constexpr int OBJPROP_VISITED = 10; | ||||
| }; | ||||
|  | ||||
| class DLL_LINKAGE CGCreature : public CArmedInstance //creatures on map | ||||
| @@ -451,12 +453,14 @@ class DLL_LINKAGE CGDenOfthieves : public CGObjectInstance | ||||
| class DLL_LINKAGE CGObelisk : public CPlayersVisited | ||||
| { | ||||
| public: | ||||
| 	static constexpr int OBJPROP_INC = 20; | ||||
| 	static ui8 obeliskCount; //how many obelisks are on map | ||||
| 	static std::map<TeamID, ui8> visited; //map: team_id => how many obelisks has been visited | ||||
|  | ||||
| 	void onHeroVisit(const CGHeroInstance * h) const override; | ||||
| 	void initObj() override; | ||||
| 	std::string getHoverText(PlayerColor player) const override; | ||||
| 	static void reset(); | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user