Browse Source

More work on configurable objects:
- maps can be started
- visiting will be registered properly

Ivan Savenko 11 years ago
parent
commit
8beea4ec6a
2 changed files with 37 additions and 18 deletions
  1. 24 12
      lib/CObjectWithReward.cpp
  2. 13 6
      lib/CObjectWithReward.h

+ 24 - 12
lib/CObjectWithReward.cpp

@@ -71,7 +71,7 @@ std::vector<ui32> CObjectWithReward::getAvailableRewards(const CGHeroInstance *
 	{
 		const CVisitInfo & visit = info[i];
 
-		if (numOfGrants[i] < visit.limiter.numOfGrants && visit.limiter.heroAllowed(hero))
+		if (visit.numOfGrants < visit.limiter.numOfGrants && visit.limiter.heroAllowed(hero))
 		{
 			ret.push_back(i);
 		}
@@ -81,7 +81,7 @@ std::vector<ui32> CObjectWithReward::getAvailableRewards(const CGHeroInstance *
 
 void CObjectWithReward::onHeroVisit(const CGHeroInstance *h) const
 {
-	if (wasVisited(h))
+	if (!wasVisited(h))
 	{
 		auto rewards = getAvailableRewards(h);
 		switch (rewards.size())
@@ -252,7 +252,11 @@ bool CObjectWithReward::wasVisited (PlayerColor player) const
 		case VISIT_UNLIMITED:
 			return false;
 		case VISIT_ONCE:
-			return numOfGrants.empty() || *boost::range::max_element(numOfGrants) == 0;
+			for (auto & visit : info)
+			{
+				if (visit.numOfGrants != 0)
+					return true;
+			}
 		case VISIT_HERO:
 			return false;
 		case VISIT_PLAYER:
@@ -324,9 +328,12 @@ const std::string & CObjectWithReward::getHoverText() const
 {
 	const CGHeroInstance *h = cb->getSelectedHero(cb->getCurrentPlayer());
 	hoverName = VLC->generaltexth->names[ID];
-	if(h && wasVisited(h))
+	if(visitMode != VISIT_UNLIMITED)
 	{
-		bool visited = h->hasBonusFrom(Bonus::OBJECT,ID);
+		bool visited = wasVisited(cb->getCurrentPlayer());
+		if (h)
+			visited |= wasVisited(h) || h->hasBonusFrom(Bonus::OBJECT,ID);
+
 		hoverName += " " + visitedTxt(visited);
 	}
 	return hoverName;
@@ -337,21 +344,27 @@ void CObjectWithReward::setPropertyDer(ui8 what, ui32 val)
 	switch (what)
 	{
 		case ObjProperty::REWARD_RESET:
-			numOfGrants.clear();
-			numOfGrants.resize(info.size(), 0);
+			for (auto & visit : info)
+				visit.numOfGrants = 0;
 			break;
 		case ObjProperty::REWARD_SELECT:
 			selectedReward = val;
 			break;
 		case ObjProperty::REWARD_ADD_VISITOR:
-			//cb->getHero(ObjectInstanceID(val))->visitedObjects.insert(ObjectInstanceID(ID));
+		{
+			//FIXME: Not sure if modifying another object here is a good idea
+			CGHeroInstance * hero = cb->gameState()->getHero(ObjectInstanceID(val));
+			assert(hero && hero->tempOwner.isValidPlayer());
+			hero->visitedObjects.insert(ObjectInstanceID(ID));
+			cb->gameState()->getPlayer(hero->tempOwner)->visitedObjects.insert(ObjectInstanceID(ID));
 			break;
+		}
 	}
 }
 
 void CObjectWithReward::newTurn() const
 {
-	if (cb->getDate(Date::DAY) % resetDuration == 0)
+	if (resetDuration != 0 && cb->getDate(Date::DAY) % resetDuration == 0)
 		cb->setObjProperty(id, ObjProperty::REWARD_RESET, 0);
 }
 
@@ -366,7 +379,6 @@ CObjectWithReward::CObjectWithReward():
 ///               END OF CODE FOR COBJECTWITHREWARD AND RELATED CLASSES                         ///
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-
 /// Helper, selects random art class based on weights
 static int selectRandomArtClass(int treasure, int minor, int major, int relic)
 {
@@ -973,7 +985,7 @@ int3 CGMagicSpring::getVisitableOffset() const
 
 	for (size_t i=0; i<visitableTiles.size(); i++)
 	{
-		if (numOfGrants[i] == 0)
+		if (info[i].numOfGrants == 0)
 			return visitableTiles[i];
 	}
 	return visitableTiles[0]; // return *something*. This is valid visitable tile but already used
@@ -984,7 +996,7 @@ std::vector<ui32> CGMagicSpring::getAvailableRewards(const CGHeroInstance * hero
 	auto tiles = getVisitableOffsets();
 	for (size_t i=0; i<tiles.size(); i++)
 	{
-		if (pos - tiles[i] == hero->getPosition() && numOfGrants[i] == 0)
+		if (pos - tiles[i] == hero->getPosition() && info[i].numOfGrants == 0)
 		{
 			return std::vector<ui32>(1, i);
 		}

+ 13 - 6
lib/CObjectWithReward.h

@@ -45,7 +45,8 @@ public:
 	CRewardLimiter():
 		numOfGrants(1),
 		dayOfWeek(0),
-		minLevel(0)
+		minLevel(0),
+		primary(4, 0)
 	{}
 
 	bool heroAllowed(const CGHeroInstance * hero) const;
@@ -102,7 +103,8 @@ public:
 		manaDiff(0),
 		manaPercentage(-1),
 		movePoints(0),
-		movePercentage(-1)
+		movePercentage(-1),
+		primary(4, 0)
 	{}
 
 	template <typename Handler> void serialize(Handler &h, const int version)
@@ -120,8 +122,16 @@ public:
 	CRewardLimiter limiter;
 	CRewardInfo reward;
 
+	/// Message that will be displayed on granting of this reward, if not empty
 	MetaString message;
 
+	/// How many times this reward has been granted since last reset
+	si32 numOfGrants;
+
+	CVisitInfo():
+		numOfGrants(0)
+	{}
+
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
 		h & limiter & reward & message;
@@ -161,9 +171,6 @@ protected:
 	/// Rewars that can be granted by an object
 	std::vector<CVisitInfo> info;
 
-	/// How many times these rewards have been granted since last reset
-	std::vector<ui32> numOfGrants;
-
 	/// MetaString's that contain text for messages for specific situations
 	MetaString onGrant;
 	MetaString onVisited;
@@ -209,7 +216,7 @@ public:
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
 		h & static_cast<CArmedInstance&>(*this);
-		h & info & numOfGrants;
+		h & info;
 		h & onGrant & onVisited & onEmpty;
 		h & soundID & selectMode & selectedReward;
 	}