mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Fix obelisks puzzle revealing
Teams and players were messed up in lib; hardcoded constants were refactored.
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)); | ||||
|   | ||||
| @@ -119,7 +119,7 @@ CPlayerInterface::CPlayerInterface(PlayerColor Player) | ||||
| 	isAutoFightOn = false; | ||||
|  | ||||
| 	duringMovement = false; | ||||
| 	ignoreEvents = false;	 | ||||
| 	ignoreEvents = false; | ||||
| } | ||||
|  | ||||
| CPlayerInterface::~CPlayerInterface() | ||||
| @@ -824,16 +824,16 @@ BattleAction CPlayerInterface::activeStack(const CStack * stack) //called when i | ||||
| 	//tidy up | ||||
| 	BattleAction ret = *(b->givenCommand->data); | ||||
| 	vstd::clear_pointer(b->givenCommand->data); | ||||
| 	 | ||||
|  | ||||
| 	if(ret.actionType == Battle::CANCEL) | ||||
| 	{ | ||||
| 		if(stackId != ret.stackNumber) | ||||
| 			logGlobal->error("Not current active stack action canceled"); | ||||
| 		logGlobal->traceStream() << "Canceled command for " << stackName;			 | ||||
| 		logGlobal->traceStream() << "Canceled command for " << stackName; | ||||
| 	} | ||||
| 	else | ||||
| 		logGlobal->traceStream() << "Giving command for " << stackName; | ||||
| 		 | ||||
|  | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| @@ -1610,11 +1610,11 @@ void CPlayerInterface::update() | ||||
| { | ||||
| 	// Make sure that gamestate won't change when GUI objects may obtain its parts on event processing or drawing request | ||||
| 	boost::shared_lock<boost::shared_mutex> gsLock(cb->getGsMutex()); | ||||
| 	 | ||||
| 	// While mutexes were locked away we may be have stopped being the active interface	 | ||||
|  | ||||
| 	// While mutexes were locked away we may be have stopped being the active interface | ||||
| 	if(LOCPLINT != this) | ||||
| 		return; | ||||
| 	 | ||||
|  | ||||
| 	//if there are any waiting dialogs, show them | ||||
| 	if((howManyPeople <= 1 || makingTurn) && !dialogs.empty() && !showingDialog->get()) | ||||
| 	{ | ||||
| @@ -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)); | ||||
| } | ||||
| @@ -2195,7 +2195,7 @@ void CPlayerInterface::advmapSpellCast(const CGHeroInstance * caster, int spellI | ||||
| 		int level = caster->getSpellSchoolLevel(spell); | ||||
| 		adventureInt->worldViewOptions.showAllTerrain = (level>2); | ||||
| 	} | ||||
| 	 | ||||
|  | ||||
| 	auto castSoundPath = spell->getCastSound(); | ||||
| 	if (!castSoundPath.empty()) | ||||
| 		CCS->soundh->playSound(castSoundPath); | ||||
| @@ -2783,8 +2783,8 @@ void CPlayerInterface::showWorldViewEx(const std::vector<ObjectPosInfo>& objectP | ||||
| { | ||||
| 	EVENT_HANDLER_CALLED_BY_CLIENT; | ||||
| 	//TODO: showWorldViewEx | ||||
| 	 | ||||
|  | ||||
| 	std::copy(objectPositions.begin(), objectPositions.end(), std::back_inserter(adventureInt->worldViewOptions.iconPositions)); | ||||
| 	 | ||||
|  | ||||
| 	viewWorldMap(); | ||||
| } | ||||
|   | ||||
| @@ -229,13 +229,13 @@ bool CGameInfoCallback::getTownInfo(const CGObjectInstance * town, InfoAboutTown | ||||
| 	{ | ||||
| 		if(!detailed && nullptr != selectedObject) | ||||
| 		{ | ||||
| 			const CGHeroInstance * selectedHero = dynamic_cast<const CGHeroInstance *>(selectedObject);		 | ||||
| 			const CGHeroInstance * selectedHero = dynamic_cast<const CGHeroInstance *>(selectedObject); | ||||
| 			if(nullptr != selectedHero) | ||||
| 				detailed = selectedHero->hasVisions(town, 1);			 | ||||
| 				detailed = selectedHero->hasVisions(town, 1); | ||||
| 		} | ||||
| 		 | ||||
|  | ||||
| 		dest.initFromTown(static_cast<const CGTownInstance *>(town), detailed); | ||||
| 	}		 | ||||
| 	} | ||||
| 	else if(town->ID == Obj::GARRISON || town->ID == Obj::GARRISON2) | ||||
| 		dest.initFromArmy(static_cast<const CArmedInstance *>(town), detailed); | ||||
| 	else | ||||
| @@ -268,28 +268,28 @@ bool CGameInfoCallback::getHeroInfo(const CGObjectInstance * hero, InfoAboutHero | ||||
| 	ERROR_RET_VAL_IF(!isVisible(h->getPosition(false)), "That hero is not visible!", false); | ||||
|  | ||||
| 	bool accessFlag = hasAccess(h->tempOwner); | ||||
| 	 | ||||
|  | ||||
| 	if(!accessFlag && nullptr != selectedObject) | ||||
| 	{ | ||||
| 		const CGHeroInstance * selectedHero = dynamic_cast<const CGHeroInstance *>(selectedObject);		 | ||||
| 		const CGHeroInstance * selectedHero = dynamic_cast<const CGHeroInstance *>(selectedObject); | ||||
| 		if(nullptr != selectedHero) | ||||
| 			accessFlag = selectedHero->hasVisions(hero, 1);			 | ||||
| 			accessFlag = selectedHero->hasVisions(hero, 1); | ||||
| 	} | ||||
| 	 | ||||
|  | ||||
| 	dest.initFromHero(h, accessFlag); | ||||
| 	 | ||||
|  | ||||
| 	//DISGUISED bonus implementation | ||||
| 	 | ||||
|  | ||||
| 	if(getPlayerRelations(getLocalPlayer(), hero->tempOwner) == PlayerRelations::ENEMIES) | ||||
| 	{ | ||||
| 		//todo: bonus cashing	 | ||||
| 		//todo: bonus cashing | ||||
| 		int disguiseLevel = h->valOfBonuses(Selector::typeSubtype(Bonus::DISGUISED, 0)); | ||||
| 		 | ||||
| 		auto doBasicDisguise = [disguiseLevel](InfoAboutHero & info)		 | ||||
|  | ||||
| 		auto doBasicDisguise = [disguiseLevel](InfoAboutHero & info) | ||||
| 		{ | ||||
| 			int maxAIValue = 0; | ||||
| 			const CCreature * mostStrong = nullptr; | ||||
| 			 | ||||
|  | ||||
| 			for(auto & elem : info.army) | ||||
| 			{ | ||||
| 				if(elem.second.type->AIValue > maxAIValue) | ||||
| @@ -298,7 +298,7 @@ bool CGameInfoCallback::getHeroInfo(const CGObjectInstance * hero, InfoAboutHero | ||||
| 					mostStrong = elem.second.type; | ||||
| 				} | ||||
| 			} | ||||
| 			 | ||||
|  | ||||
| 			if(nullptr == mostStrong)//just in case | ||||
| 				logGlobal->errorStream() << "CGameInfoCallback::getHeroInfo: Unable to select most strong stack" << disguiseLevel; | ||||
| 			else | ||||
| @@ -307,25 +307,25 @@ bool CGameInfoCallback::getHeroInfo(const CGObjectInstance * hero, InfoAboutHero | ||||
| 					elem.second.type = mostStrong; | ||||
| 				} | ||||
| 		}; | ||||
| 		 | ||||
| 		auto doAdvancedDisguise = [accessFlag, &doBasicDisguise](InfoAboutHero & info)		 | ||||
|  | ||||
| 		auto doAdvancedDisguise = [accessFlag, &doBasicDisguise](InfoAboutHero & info) | ||||
| 		{ | ||||
| 			doBasicDisguise(info); | ||||
| 			 | ||||
|  | ||||
| 			for(auto & elem : info.army) | ||||
| 				elem.second.count = 0; | ||||
| 		}; | ||||
| 		 | ||||
| 		auto doExpertDisguise = [this,h](InfoAboutHero & info)		 | ||||
|  | ||||
| 		auto doExpertDisguise = [this,h](InfoAboutHero & info) | ||||
| 		{ | ||||
| 			for(auto & elem : info.army) | ||||
| 				elem.second.count = 0; | ||||
| 			 | ||||
|  | ||||
| 			const auto factionIndex = getStartInfo(false)->playerInfos.at(h->tempOwner).castle; | ||||
| 			 | ||||
|  | ||||
| 			int maxAIValue = 0; | ||||
| 			const CCreature * mostStrong = nullptr; | ||||
| 			 | ||||
|  | ||||
| 			for(auto creature : VLC->creh->creatures) | ||||
| 			{ | ||||
| 				if(creature->faction == factionIndex && creature->AIValue > maxAIValue) | ||||
| @@ -334,35 +334,35 @@ bool CGameInfoCallback::getHeroInfo(const CGObjectInstance * hero, InfoAboutHero | ||||
| 					mostStrong = creature; | ||||
| 				} | ||||
| 			} | ||||
| 			 | ||||
|  | ||||
| 			if(nullptr != mostStrong) //possible, faction may have no creatures at all | ||||
| 				for(auto & elem : info.army) | ||||
| 					elem.second.type = mostStrong; | ||||
| 		};				 | ||||
| 		 | ||||
| 		 | ||||
| 		}; | ||||
|  | ||||
|  | ||||
| 		switch (disguiseLevel) | ||||
| 		{ | ||||
| 		case 0: | ||||
| 			//no bonus at all - do nothing | ||||
| 			break;		 | ||||
| 			break; | ||||
| 		case 1: | ||||
| 			doBasicDisguise(dest); | ||||
| 			break;		 | ||||
| 			break; | ||||
| 		case 2: | ||||
| 			doAdvancedDisguise(dest); | ||||
| 			break;		 | ||||
| 			break; | ||||
| 		case 3: | ||||
| 			doExpertDisguise(dest); | ||||
| 			break;		 | ||||
| 			break; | ||||
| 		default: | ||||
| 			//invalid value | ||||
| 			logGlobal->errorStream() << "CGameInfoCallback::getHeroInfo: Invalid DISGUISED bonus value " << disguiseLevel; | ||||
| 			break; | ||||
| 		} | ||||
| 		 | ||||
|  | ||||
| 	} | ||||
| 	 | ||||
|  | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| @@ -486,7 +486,7 @@ std::shared_ptr<boost::multi_array<TerrainTile*, 3>> CGameInfoCallback::getAllVi | ||||
|  | ||||
|  | ||||
| 	boost::multi_array<TerrainTile*, 3> tileArray(boost::extents[width][height][levels]); | ||||
| 	 | ||||
|  | ||||
| 	for (size_t x = 0; x < width; x++) | ||||
| 		for (size_t y = 0; y < height; y++) | ||||
| 			for (size_t z = 0; z < levels; z++) | ||||
| @@ -723,15 +723,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; | ||||
| } | ||||
| @@ -964,4 +965,3 @@ void IGameEventRealizer::setObjProperty(ObjectInstanceID objid, int prop, si64 v | ||||
| 	sob.val = static_cast<ui32>(val); | ||||
| 	commitPackage(&sob); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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); | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -533,7 +533,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 +550,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()); | ||||
| @@ -645,7 +645,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 | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -118,6 +118,8 @@ public: | ||||
| 		h & rewardType & rID & rVal & seerName; | ||||
| 	} | ||||
| protected: | ||||
| 	static constexpr int OBJPROP_VISITED = 10; | ||||
|  | ||||
| 	void setPropertyDer(ui8 what, ui32 val) override; | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -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)); | ||||
| } | ||||
|  | ||||
| @@ -103,16 +103,16 @@ std::string CGCreature::getHoverText(const CGHeroInstance * hero) const | ||||
| { | ||||
| 	std::string hoverName; | ||||
| 	if(hero->hasVisions(this, 0)) | ||||
| 	{		 | ||||
| 	{ | ||||
| 		MetaString ms; | ||||
| 		ms << stacks.begin()->second->count; | ||||
| 		ms << " " ; | ||||
| 		ms.addTxt(MetaString::CRE_PL_NAMES,subID); | ||||
| 		 | ||||
|  | ||||
| 		ms << "\n"; | ||||
| 		 | ||||
|  | ||||
| 		int decision = takenAction(hero, true); | ||||
| 		 | ||||
|  | ||||
| 		switch (decision) | ||||
| 		{ | ||||
| 		case FIGHT: | ||||
| @@ -123,19 +123,19 @@ std::string CGCreature::getHoverText(const CGHeroInstance * hero) const | ||||
| 			break; | ||||
| 		case JOIN_FOR_FREE: | ||||
| 			ms.addTxt(MetaString::GENERAL_TXT,243); | ||||
| 			break;					 | ||||
| 			break; | ||||
| 		default: //decision = cost in gold | ||||
| 			VLC->generaltexth->allTexts[244]; | ||||
| 			ms << boost::to_string(boost::format(VLC->generaltexth->allTexts[244]) % decision);			 | ||||
| 			ms << boost::to_string(boost::format(VLC->generaltexth->allTexts[244]) % decision); | ||||
| 			break; | ||||
| 		}		 | ||||
| 		} | ||||
|  | ||||
| 		ms.toString(hoverName);		 | ||||
| 		ms.toString(hoverName); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		hoverName = getHoverText(hero->tempOwner);	 | ||||
| 	}	 | ||||
| 		hoverName = getHoverText(hero->tempOwner); | ||||
| 	} | ||||
|  | ||||
| 	const JsonNode & texts = VLC->generaltexth->localizedTexts["adventureMap"]["monsterThreat"]; | ||||
|  | ||||
| @@ -1310,7 +1310,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 | ||||
| 	{ | ||||
| @@ -1420,7 +1420,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; | ||||
| @@ -1745,7 +1745,7 @@ void CGShipyard::getOutOffsets( std::vector<int3> &offsets ) const | ||||
| 		int3(-3,0,0), int3(1,0,0), //AB | ||||
| 		int3(-3,1,0), int3(1,1,0), int3(-2,1,0), int3(0,1,0), int3(-1,1,0), //CDEFG | ||||
| 		int3(-3,-1,0), int3(1,-1,0), int3(-2,-1,0), int3(0,-1,0), int3(-1,-1,0) //HIJKL | ||||
| 	};  | ||||
| 	}; | ||||
| } | ||||
|  | ||||
| void CGShipyard::onHeroVisit( const CGHeroInstance * h ) const | ||||
| @@ -1821,7 +1821,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()); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -1843,11 +1843,13 @@ 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 | ||||
| 		cb->setObjProperty(id, CGObelisk::OBJPROP_VISITED, h->tempOwner.getNum()); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| @@ -1869,20 +1871,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,6 +453,7 @@ 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 | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user