Browse Source

Implemented playerGlobal visit mode for objects like cartographer

Ivan Savenko 7 tháng trước cách đây
mục cha
commit
4b77140f4a

+ 4 - 4
config/objects/cartographer.json

@@ -18,7 +18,7 @@
 					"rarity" : 20
 				},
 				"compatibilityIdentifiers" : [ "water" ],
-				"visitMode" : "unlimited",
+				"visitMode" : "playerGlobal",
 				"canRefuse" : true,
 				"rewards" : [
 					{
@@ -44,7 +44,7 @@
 					"rarity" : 2
 				},
 				"compatibilityIdentifiers" : [ "land" ],
-				"visitMode" : "unlimited",
+				"visitMode" : "playerGlobal",
 				"canRefuse" : true,
 				"rewards" : [
 					{
@@ -72,7 +72,7 @@
 					"rarity" : 20
 				},
 				"compatibilityIdentifiers" : [ "subterra" ],
-				"visitMode" : "unlimited",
+				"visitMode" : "playerGlobal",
 				"canRefuse" : true,
 				"rewards" : [
 					{
@@ -94,4 +94,4 @@
 			}
 		}
 	}
-}
+}

+ 1 - 1
lib/mapObjects/CQuest.cpp

@@ -815,7 +815,7 @@ void CGKeymasterTent::onHeroVisit( const CGHeroInstance * h ) const
 	if (!wasMyColorVisited (h->getOwner()) )
 	{
 		ChangeObjectVisitors cow;
-		cow.mode = ChangeObjectVisitors::VISITOR_GLOBAL;
+		cow.mode = ChangeObjectVisitors::VISITOR_ADD_PLAYER;
 		cow.hero = h->id;
 		cow.object = id;
 		cb->sendAndApply(cow);

+ 7 - 3
lib/mapObjects/CRewardableObject.cpp

@@ -137,7 +137,9 @@ bool CRewardableObject::wasVisitedBefore(const CGHeroInstance * contextHero) con
 		case Rewardable::VISIT_ONCE:
 			return onceVisitableObjectCleared;
 		case Rewardable::VISIT_PLAYER:
-			return vstd::contains(cb->getPlayerState(contextHero->getOwner())->visitedObjects, ObjectInstanceID(id));
+			return cb->getPlayerState(contextHero->getOwner())->visitedObjects.count(ObjectInstanceID(id)) != 0;
+		case Rewardable::VISIT_PLAYER_GLOBAL:
+			return cb->getPlayerState(contextHero->getOwner())->visitedObjectsGlobal.count({ID, subID}) != 0;
 		case Rewardable::VISIT_BONUS:
 			return contextHero->hasBonusFrom(BonusSource::OBJECT_TYPE, BonusSourceID(ID));
 		case Rewardable::VISIT_HERO:
@@ -160,7 +162,9 @@ bool CRewardableObject::wasVisited(PlayerColor player) const
 			return false;
 		case Rewardable::VISIT_ONCE:
 		case Rewardable::VISIT_PLAYER:
-			return vstd::contains(cb->getPlayerState(player)->visitedObjects, ObjectInstanceID(id));
+			return cb->getPlayerState(player)->visitedObjects.count(ObjectInstanceID(id)) != 0;
+		case Rewardable::VISIT_PLAYER_GLOBAL:
+			return cb->getPlayerState(player)->visitedObjectsGlobal.count({ID, subID}) != 0;
 		default:
 			return false;
 	}
@@ -205,7 +209,7 @@ std::string CRewardableObject::getDisplayTextImpl(PlayerColor player, const CGHe
 	}
 	else
 	{
-		if(configuration.visitMode == Rewardable::VISIT_PLAYER || configuration.visitMode == Rewardable::VISIT_ONCE)
+		if(configuration.visitMode == Rewardable::VISIT_PLAYER || configuration.visitMode == Rewardable::VISIT_ONCE || configuration.visitMode == Rewardable::VISIT_PLAYER_GLOBAL)
 		{
 			if (wasVisited(player))
 				result += "\n" + configuration.visitedTooltip.toString();

+ 2 - 0
lib/mapObjects/TownBuildingInstance.cpp

@@ -172,6 +172,7 @@ bool TownRewardableBuildingInstance::wasVisitedBefore(const CGHeroInstance * con
 		case Rewardable::VISIT_ONCE:
 			return !visitors.empty();
 		case Rewardable::VISIT_PLAYER:
+		case Rewardable::VISIT_PLAYER_GLOBAL:
 			return false; //not supported
 		case Rewardable::VISIT_BONUS:
 		{
@@ -211,6 +212,7 @@ bool TownRewardableBuildingInstance::wasVisited(PlayerColor player) const
 		case Rewardable::VISIT_BONUS:
 		case Rewardable::VISIT_HERO:
 		case Rewardable::VISIT_LIMITER:
+		case Rewardable::VISIT_PLAYER_GLOBAL:
 			return false;
 		case Rewardable::VISIT_ONCE:
 		case Rewardable::VISIT_PLAYER:

+ 5 - 11
lib/networkPacks/NetPacksLib.cpp

@@ -1045,16 +1045,16 @@ void ChangeObjPos::applyGs(CGameState *gs)
 
 void ChangeObjectVisitors::applyGs(CGameState *gs)
 {
+	auto objectPtr = gs->getObjInstance(object);
+
 	switch (mode) {
 		case VISITOR_ADD_HERO:
-			gs->getPlayerTeam(gs->getHero(hero)->tempOwner)->scoutedObjects.insert(object);
 			gs->getHero(hero)->visitedObjects.insert(object);
-			gs->getPlayerState(gs->getHero(hero)->tempOwner)->visitedObjects.insert(object);
-			break;
+			[[fallthrough]];
 		case VISITOR_ADD_PLAYER:
 			gs->getPlayerTeam(gs->getHero(hero)->tempOwner)->scoutedObjects.insert(object);
-			for(const auto & color : gs->getPlayerTeam(gs->getHero(hero)->tempOwner)->players)
-				gs->getPlayerState(color)->visitedObjects.insert(object);
+			gs->getPlayerState(gs->getHero(hero)->tempOwner)->visitedObjects.insert(object);
+			gs->getPlayerState(gs->getHero(hero)->tempOwner)->visitedObjectsGlobal.insert({objectPtr->ID, objectPtr->subID});
 
 			break;
 		case VISITOR_CLEAR:
@@ -1076,12 +1076,6 @@ void ChangeObjectVisitors::applyGs(CGameState *gs)
 			gs->getPlayerTeam(gs->getHero(hero)->tempOwner)->scoutedObjects.insert(object);
 
 			break;
-		case VISITOR_GLOBAL:
-			{
-				CGObjectInstance * objectPtr = gs->getObjInstance(object);
-				gs->getPlayerState(gs->getHero(hero)->tempOwner)->visitedObjectsGlobal.insert({objectPtr->ID, objectPtr->subID});
-				break;
-			}
 	}
 }
 

+ 0 - 1
lib/networkPacks/PacksForClient.h

@@ -1215,7 +1215,6 @@ struct DLL_LINKAGE ChangeObjectVisitors : public CPackForClient
 	{
 		VISITOR_ADD_HERO,   // mark hero as one that have visited this object
 		VISITOR_ADD_PLAYER, // mark player as one that have visited this object instance
-		VISITOR_GLOBAL,     // mark player as one that have visited object of this type
 		VISITOR_SCOUTED,    // marks targeted team as having scouted this object
 		VISITOR_CLEAR,      // clear all visitors from this object (object reset)
 	};

+ 6 - 6
lib/rewardable/Configuration.h

@@ -22,7 +22,7 @@ VCMI_LIB_NAMESPACE_BEGIN
 namespace Rewardable
 {
 
-enum EVisitMode
+enum EVisitMode : uint8_t
 {
 	VISIT_UNLIMITED, // any number of times. Side effect - object hover text won't contain visited/not visited text
 	VISIT_ONCE,      // only once, first to visit get all the rewards
@@ -34,7 +34,7 @@ enum EVisitMode
 };
 
 /// controls selection of reward granted to player
-enum ESelectMode
+enum ESelectMode : uint8_t
 {
 	SELECT_FIRST,  // first reward that matches limiters
 	SELECT_PLAYER, // player can select from all allowed rewards
@@ -42,7 +42,7 @@ enum ESelectMode
 	SELECT_ALL // grant all rewards that match limiters
 };
 
-enum class EEventType
+enum class EEventType : uint8_t
 {
 	EVENT_INVALID = 0,
 	EVENT_FIRST_VISIT,
@@ -52,7 +52,7 @@ enum class EEventType
 };
 
 constexpr std::array<std::string_view, 4> SelectModeString{"selectFirst", "selectPlayer", "selectRandom", "selectAll"};
-constexpr std::array<std::string_view, 6> VisitModeString{"unlimited", "once", "hero", "bonus", "limiter", "player"};
+constexpr std::array<std::string_view, 7> VisitModeString{"unlimited", "once", "hero", "bonus", "limiter", "player", "playerGlobal" };
 
 struct DLL_LINKAGE ResetInfo
 {
@@ -150,10 +150,10 @@ struct DLL_LINKAGE Configuration
 	std::vector<Rewardable::VisitInfo> info;
 
 	/// how reward will be selected, uses ESelectMode enum
-	ui8 selectMode = Rewardable::SELECT_FIRST;
+	ESelectMode selectMode = Rewardable::SELECT_FIRST;
 
 	/// controls who can visit an object, uses EVisitMode enum
-	ui8 visitMode = Rewardable::VISIT_UNLIMITED;
+	EVisitMode visitMode = Rewardable::VISIT_UNLIMITED;
 
 	/// how and when should the object be reset
 	Rewardable::ResetInfo resetParameters;

+ 2 - 2
lib/rewardable/Info.cpp

@@ -471,7 +471,7 @@ void Rewardable::Info::configureObject(Rewardable::Configuration & object, vstd:
 	{
 		if(Rewardable::VisitModeString[i] == visitMode)
 		{
-			object.visitMode = i;
+			object.visitMode = static_cast<EVisitMode>(i);
 			break;
 		}
 	}
@@ -481,7 +481,7 @@ void Rewardable::Info::configureObject(Rewardable::Configuration & object, vstd:
 	{
 		if(Rewardable::SelectModeString[i] == selectMode)
 		{
-			object.selectMode = i;
+			object.selectMode = static_cast<ESelectMode>(i);
 			break;
 		}
 	}

+ 1 - 1
lib/rewardable/Info.h

@@ -32,7 +32,7 @@ struct Configuration;
 struct Variables;
 struct VisitInfo;
 struct ResetInfo;
-enum class EEventType;
+enum class EEventType : uint8_t;
 
 class DLL_LINKAGE Info : public IObjectInfo
 {

+ 2 - 0
lib/rewardable/Limiter.cpp

@@ -30,6 +30,8 @@ Rewardable::Limiter::Limiter()
 	, manaPercentage(0)
 	, manaPoints(0)
 	, canLearnSkills(false)
+	, commanderAlive(false)
+	, hasExtraCreatures(false)
 	, primary(GameConstants::PRIMARY_SKILLS, 0)
 {
 }

+ 2 - 2
mapeditor/inspector/rewardswidget.cpp

@@ -249,8 +249,8 @@ void RewardsWidget::obtainData()
 bool RewardsWidget::commitChanges()
 {
 	//common parameters
-	object.configuration.visitMode = ui->visitMode->currentIndex();
-	object.configuration.selectMode = ui->selectMode->currentIndex();
+	object.configuration.visitMode = static_cast<Rewardable::EVisitMode>(ui->visitMode->currentIndex());
+	object.configuration.selectMode = static_cast<Rewardable::ESelectMode>(ui->selectMode->currentIndex());
 	object.configuration.infoWindowType = EInfoWindowMode(ui->windowMode->currentIndex());
 	if(ui->onSelectText->text().isEmpty())
 		object.configuration.onSelect.clear();