소스 검색

* refactoring

mateuszb 12 년 전
부모
커밋
9c1a117c1c

+ 2 - 2
client/CPlayerInterface.cpp

@@ -1240,8 +1240,8 @@ bool CPlayerInterface::moveHero( const CGHeroInstance *h, CGPath path )
 			boost::unique_lock<boost::mutex> un(stillMoveHero.mx);
 			stillMoveHero.data = CONTINUE_MOVE;
 
-            enum ETerrainType::ETerrainType currentTerrain = ETerrainType::BORDER; // not init yet
-            enum ETerrainType::ETerrainType newTerrain;
+            enum ETerrainType currentTerrain = ETerrainType::BORDER; // not init yet
+            enum ETerrainType newTerrain;
 			int sh = -1;
 
 			const TerrainTile * curTile = cb->getTile(CGHeroInstance::convertPosition(h->pos, false));

+ 1 - 1
client/mapHandler.cpp

@@ -34,7 +34,7 @@ extern SDL_Surface * screen;
 
 std::string nameFromType (int typ)
 {
-    switch(static_cast<ETerrainType::ETerrainType>(typ))
+    switch(ETerrainType(typ))
 	{
         case ETerrainType::DIRT:
 			return std::string("DIRTTL.DEF");

+ 5 - 5
lib/BattleState.cpp

@@ -346,15 +346,15 @@ struct RangeGenerator
 	boost::function<int()> myRand;
 };
 
-BattleInfo * BattleInfo::setupBattle( int3 tile, ETerrainType::ETerrainType terrain, BFieldType::BFieldType battlefieldType, const CArmedInstance *armies[2], const CGHeroInstance * heroes[2], bool creatureBank, const CGTownInstance *town )
+BattleInfo * BattleInfo::setupBattle( int3 tile, ETerrainType terrain, BFieldType battlefieldType, const CArmedInstance *armies[2], const CGHeroInstance * heroes[2], bool creatureBank, const CGTownInstance *town )
 {
 	CMP_stack cmpst;
 	BattleInfo *curB = new BattleInfo;
 	curB->castSpells[0] = curB->castSpells[1] = 0;
 	curB->sides[0] = armies[0]->tempOwner;
 	curB->sides[1] = armies[1]->tempOwner;
-	if(curB->sides[1] == 254)
-		curB->sides[1] = 255;
+	if(curB->sides[1] == GameConstants::UNFLAGGABLE_PLAYER)
+		curB->sides[1] = GameConstants::NEUTRAL_PLAYER;
 
 	std::vector<CStack*> & stacks = (curB->stacks);
 
@@ -804,9 +804,9 @@ shared_ptr<CObstacleInstance> BattleInfo::getObstacleOnTile(BattleHex tile) cons
 	return shared_ptr<CObstacleInstance>();
 }
 
-BattlefieldBI::BattlefieldBI BattleInfo::battlefieldTypeToBI(BFieldType::BFieldType bfieldType)
+BattlefieldBI::BattlefieldBI BattleInfo::battlefieldTypeToBI(BFieldType bfieldType)
 {
-	static const std::map<BFieldType::BFieldType, BattlefieldBI::BattlefieldBI> theMap = boost::assign::map_list_of
+	static const std::map<BFieldType, BattlefieldBI::BattlefieldBI> theMap = boost::assign::map_list_of
 		(BFieldType::CLOVER_FIELD, BattlefieldBI::CLOVER_FIELD)
 		(BFieldType::CURSED_GROUND, BattlefieldBI::CURSED_GROUND)
 		(BFieldType::EVIL_FOG, BattlefieldBI::EVIL_FOG)

+ 6 - 6
lib/BattleState.h

@@ -59,8 +59,8 @@ struct DLL_LINKAGE BattleInfo : public CBonusSystemNode, public CBattleInfoCallb
 	si16 enchanterCounter[2]; //tends to pass through 0, so sign is needed
 	SiegeInfo si;
 
-	BFieldType::BFieldType battlefieldType; //like !!BA:B
-	ETerrainType::ETerrainType terrainType; //used for some stack nativity checks (not the bonus limiters though that have their own copy)
+	BFieldType battlefieldType; //like !!BA:B
+	ETerrainType terrainType; //used for some stack nativity checks (not the bonus limiters though that have their own copy)
 
 	ui8 tacticsSide; //which side is requested to play tactics phase
 	ui8 tacticDistance; //how many hexes we can go forward (1 = only hexes adjacent to margin line)
@@ -125,13 +125,13 @@ struct DLL_LINKAGE BattleInfo : public CBonusSystemNode, public CBattleInfoCallb
 	void localInit();
 
 	void localInitStack(CStack * s);
-	static BattleInfo * setupBattle( int3 tile, ETerrainType::ETerrainType terrain, BFieldType::BFieldType battlefieldType, const CArmedInstance *armies[2], const CGHeroInstance * heroes[2], bool creatureBank, const CGTownInstance *town );
+	static BattleInfo * setupBattle( int3 tile, ETerrainType terrain, BFieldType battlefieldType, const CArmedInstance *armies[2], const CGHeroInstance * heroes[2], bool creatureBank, const CGTownInstance *town );
 	//bool hasNativeStack(ui8 side) const;
 
 	TPlayerColor theOtherPlayer(TPlayerColor player) const;
 	ui8 whatSide(TPlayerColor player) const;
 
-	static BattlefieldBI::BattlefieldBI battlefieldTypeToBI(BFieldType::BFieldType bfieldType); //converts above to ERM BI format
+	static BattlefieldBI::BattlefieldBI battlefieldTypeToBI(BFieldType bfieldType); //converts above to ERM BI format
 	static int battlefieldTypeToTerrain(int bfieldType); //converts above to ERM BI format
 };
 
@@ -143,8 +143,8 @@ public:
 	ui32 ID; //unique ID of stack
 	ui32 baseAmount;
 	ui32 firstHPleft; //HP of first creature in stack
-	TPlayerColor owner;
-	ui8 slot;  //owner - player colour (255 for neutrals), slot - position in garrison (may be 255 for neutrals/called creatures)
+	TPlayerColor owner; //owner - player colour (255 for neutrals)
+	ui8 slot;  //slot - position in garrison (may be 255 for neutrals/called creatures)
 	bool attackerOwned; //if true, this stack is owned by attakcer (this one from left hand side of battle)
 	BattleHex position; //position on battlefield; -2 - keep, -3 - lower tower, -4 - upper tower
 	ui8 counterAttacks; //how many counter attacks can be performed more in this turn (by default set at the beginning of the round to 1)

+ 67 - 65
lib/CArtHandler.cpp

@@ -554,12 +554,19 @@ void CArtHandler::sortArts()
  	//	}
  	//}
 }
-void CArtHandler::erasePickedArt( TArtifactInstanceID id )
+
+ArtifactID CArtHandler::getRandomArt(int flags)
+{
+	return getArtSync(ran(), flags, true);
+}
+ArtifactID CArtHandler::getArtSync (ui32 rand, int flags, bool erasePicked)
 {
-	std::vector<CArtifact*>* ptr;
-	CArtifact *art = artifacts[id];
-	switch (art->aClass)
+	auto erasePickedArt = [&]( TArtifactInstanceID id )
 	{
+		std::vector<CArtifact*>* ptr;
+		CArtifact *art = artifacts[id];
+		switch (art->aClass)
+		{
 		case CArtifact::ART_TREASURE:
 			ptr = &treasures;
 			break;
@@ -574,63 +581,58 @@ void CArtHandler::erasePickedArt( TArtifactInstanceID id )
 			break;
 		default: //special artifacts should not be erased
 			return;
-	}
-	ptr->erase (std::find(ptr->begin(), ptr->end(), art)); //remove the artifact from available list
-}
-ui16 CArtHandler::getRandomArt(int flags)
-{
-	std::vector<ConstTransitivePtr<CArtifact> > out;
-	getAllowed(out, flags);
-	ui16 id = out[ran() % out.size()]->id;
-	erasePickedArt (id);
-	return id;
-}
-ui16 CArtHandler::getArtSync (ui32 rand, int flags)
-{
-	std::vector<ConstTransitivePtr<CArtifact> > out;
-	getAllowed(out, flags);
-	CArtifact *art = out[rand % out.size()];
-	return art->id;
-}
-void CArtHandler::getAllowed(std::vector<ConstTransitivePtr<CArtifact> > &out, int flags)
-{
-	if (flags & CArtifact::ART_TREASURE)
-		getAllowedArts (out, &treasures, CArtifact::ART_TREASURE);
-	if (flags & CArtifact::ART_MINOR)
-		getAllowedArts (out, &minors, CArtifact::ART_MINOR);
-	if (flags & CArtifact::ART_MAJOR)
-		getAllowedArts (out, &majors, CArtifact::ART_MAJOR);
-	if (flags & CArtifact::ART_RELIC)
-		getAllowedArts (out, &relics, CArtifact::ART_RELIC);
-	if (!out.size()) //no artifact of specified rarity, we need to take another one
-	{
-		getAllowedArts (out, &treasures, CArtifact::ART_TREASURE);
-		getAllowedArts (out, &minors, CArtifact::ART_MINOR);
-		getAllowedArts (out, &majors, CArtifact::ART_MAJOR);
-		getAllowedArts (out, &relics, CArtifact::ART_RELIC);
-	}
-	if (!out.size()) //no arts are available at all
-	{
-		out.resize (64);
-		std::fill_n (out.begin(), 64, artifacts[2]); //Give Grail - this can't be banned (hopefully)
-	}
-}
-void CArtHandler::getAllowedArts(std::vector<ConstTransitivePtr<CArtifact> > &out, std::vector<CArtifact*> *arts, int flag)
-{
-	if (arts->empty()) //restock available arts
+		}
+		ptr->erase (std::find(ptr->begin(), ptr->end(), art)); //remove the artifact from available list
+	};
+
+	auto getAllowedArts = [&](std::vector<ConstTransitivePtr<CArtifact> > &out, std::vector<CArtifact*> *arts, int flag)
 	{
-		for (int i = 0; i < allowedArtifacts.size(); ++i)
+		if (arts->empty()) //restock available arts
+		{
+			for (int i = 0; i < allowedArtifacts.size(); ++i)
+			{
+				if (allowedArtifacts[i]->aClass == flag)
+					arts->push_back(allowedArtifacts[i]);
+			}
+		}
+
+		for (int i = 0; i < arts->size(); ++i)
 		{
-			if (allowedArtifacts[i]->aClass == flag)
-				arts->push_back(allowedArtifacts[i]);
+			CArtifact *art = (*arts)[i];
+			out.push_back(art);
 		}
-	}
+	};
 
-	for (int i = 0; i < arts->size(); ++i)
+	auto getAllowed = [&](std::vector<ConstTransitivePtr<CArtifact> > &out)
 	{
-		CArtifact *art = (*arts)[i];
-		out.push_back(art);
-	}
+		if (flags & CArtifact::ART_TREASURE)
+			getAllowedArts (out, &treasures, CArtifact::ART_TREASURE);
+		if (flags & CArtifact::ART_MINOR)
+			getAllowedArts (out, &minors, CArtifact::ART_MINOR);
+		if (flags & CArtifact::ART_MAJOR)
+			getAllowedArts (out, &majors, CArtifact::ART_MAJOR);
+		if (flags & CArtifact::ART_RELIC)
+			getAllowedArts (out, &relics, CArtifact::ART_RELIC);
+		if (!out.size()) //no artifact of specified rarity, we need to take another one
+		{
+			getAllowedArts (out, &treasures, CArtifact::ART_TREASURE);
+			getAllowedArts (out, &minors, CArtifact::ART_MINOR);
+			getAllowedArts (out, &majors, CArtifact::ART_MAJOR);
+			getAllowedArts (out, &relics, CArtifact::ART_RELIC);
+		}
+		if (!out.size()) //no arts are available at all
+		{
+			out.resize (64);
+			std::fill_n (out.begin(), 64, artifacts[2]); //Give Grail - this can't be banned (hopefully)
+		}
+	};
+
+	std::vector<ConstTransitivePtr<CArtifact> > out;
+	getAllowed(out);
+	ArtifactID artID = out[rand % out.size()]->id;
+	if(erasePicked)
+		erasePickedArt (artID);
+	return artID;
 }
 
 Bonus *createBonus(Bonus::BonusType type, int val, int subtype, Bonus::ValueType valType, shared_ptr<ILimiter> limiter = shared_ptr<ILimiter>(), int additionalInfo = 0)
@@ -681,7 +683,7 @@ void CArtHandler::makeItCreatureArt (CArtifact * a, bool onlyCreature /*=true*/)
 	a->possibleSlots[ArtBearer::CREATURE].push_back(ArtifactPosition::CREATURE_SLOT);
 }
 
-void CArtHandler::makeItCreatureArt (TArtifactInstanceID aid, bool onlyCreature /*=true*/)
+void CArtHandler::makeItCreatureArt (ArtifactID aid, bool onlyCreature /*=true*/)
 {
 	CArtifact *a = artifacts[aid];
 	makeItCreatureArt (a, onlyCreature);
@@ -698,7 +700,7 @@ void CArtHandler::makeItCommanderArt (CArtifact * a, bool onlyCommander /*= true
 		a->possibleSlots[ArtBearer::COMMANDER].push_back(ArtifactPosition(i));
 }
 
-void CArtHandler::makeItCommanderArt( TArtifactInstanceID aid, bool onlyCommander /*= true*/ )
+void CArtHandler::makeItCommanderArt( ArtifactID aid, bool onlyCommander /*= true*/ )
 {
 	CArtifact *a = artifacts[aid];
 	makeItCommanderArt (a, onlyCommander);
@@ -782,7 +784,7 @@ void CArtHandler::clearHlpLists()
 	relics.clear();
 }
 
-bool CArtHandler::legalArtifact(int id)
+bool CArtHandler::legalArtifact(ArtifactID id)
 {
 	return (artifacts[id]->possibleSlots[ArtBearer::HERO].size() ||
 			(artifacts[id]->possibleSlots[ArtBearer::COMMANDER].size() && VLC->modh->modules.COMMANDERS)) ||
@@ -793,7 +795,7 @@ void CArtHandler::initAllowedArtifactsList(const std::vector<bool> &allowed)
 {
 	allowedArtifacts.clear();
 	clearHlpLists();
-	for (int i=0; i<144; ++i) //yes, 144
+	for (ArtifactID i=ArtifactID::SPELLBOOK; i<ArtifactID::ART_SELECTION; i.advance(1))
 	{
 		if (allowed[i] && legalArtifact(i))
 			allowedArtifacts.push_back(artifacts[i]);
@@ -811,7 +813,7 @@ void CArtHandler::initAllowedArtifactsList(const std::vector<bool> &allowed)
 			allowedArtifacts.push_back(artifacts[i]);
 		 else //check if active modules allow artifact to be every used
 		 {
-			 if (legalArtifact(i))
+			 if (legalArtifact(ArtifactID(i)))
 				 allowedArtifacts.push_back(artifacts[i]);
 			 //keep im mind that artifact can be worn by more than one type of bearer
 		 }
@@ -912,7 +914,7 @@ bool CArtifactInstance::canBePutAt(const CArtifactSet *artSet, ArtifactPosition
  	auto possibleSlots = artType->possibleSlots.find(artSet->bearerType());
  	if(possibleSlots == artType->possibleSlots.end())
  	{
-		tlog3 << "Warning: arrtifact " << artType->Name() << " doesn't have defined allowed slots for bearer of type "
+		tlog3 << "Warning: artifact " << artType->Name() << " doesn't have defined allowed slots for bearer of type "
 			<< artSet->bearerType() << std::endl;
 		return false;
 	}
@@ -1014,15 +1016,15 @@ void CArtifactInstance::deserializationFix()
 	setType(artType);
 }
 
-int CArtifactInstance::getGivenSpellID() const
+SpellID CArtifactInstance::getGivenSpellID() const
 {
 	const Bonus * b = getBonusLocalFirst(Selector::type(Bonus::SPELL));
 	if(!b)
 	{
 		tlog3 << "Warning: " << nodeName() << " doesn't bear any spell!\n";
-		return -1;
+		return SpellID::NONE;
 	}
-	return b->subtype;
+	return SpellID(b->subtype);
 }
 
 bool CArtifactInstance::isPart(const CArtifactInstance *supposedPart) const

+ 8 - 7
lib/CArtHandler.h

@@ -120,7 +120,7 @@ public:
 
 	ArtifactPosition firstAvailableSlot(const CArtifactSet *h) const;
 	ArtifactPosition firstBackpackSlot(const CArtifactSet *h) const;
-	int getGivenSpellID() const; //to be used with scrolls (and similar arts), -1 if none
+	SpellID getGivenSpellID() const; //to be used with scrolls (and similar arts), -1 if none
 
 	virtual bool canBePutAt(const CArtifactSet *artSet, ArtifactPosition slot, bool assumeDestRemoved = false) const;
 	bool canBePutAt(const ArtifactLocation al, bool assumeDestRemoved = false) const;  //forwards to the above one
@@ -193,7 +193,8 @@ class DLL_LINKAGE CArtHandler //handles artifacts
 	void giveArtBonus(ArtifactID aid, Bonus::BonusType type, int val, int subtype, shared_ptr<IPropagator> propagator, int additionalinfo = 0);
 	void giveArtBonus(ArtifactID aid, Bonus *bonus);
 public:
-	std::vector<CArtifact*> treasures, minors, majors, relics;
+	std::vector<CArtifact*> treasures, minors, majors, relics; //tmp vectors!!! do not touch if you don't know what you are doing!!!
+
 	std::vector< ConstTransitivePtr<CArtifact> > artifacts;
 	std::vector<CArtifact *> allowedArtifacts;
 	std::set<ArtifactID> bigArtifacts; // Artifacts that cannot be moved to backpack, e.g. war machines.
@@ -211,9 +212,9 @@ public:
 	void addBonuses();
 	void clear();
 	void clearHlpLists();
-	ui16 getRandomArt (int flags);
-	ui16 getArtSync (ui32 rand, int flags);
-	bool legalArtifact(int id);
+	ArtifactID getRandomArt (int flags);
+	ArtifactID getArtSync (ui32 rand, int flags, bool erasePicked = false);
+	bool legalArtifact(ArtifactID id);
 	void getAllowedArts(std::vector<ConstTransitivePtr<CArtifact> > &out, std::vector<CArtifact*> *arts, int flag);
 	void getAllowed(std::vector<ConstTransitivePtr<CArtifact> > &out, int flags);
 	void erasePickedArt (TArtifactInstanceID id);
@@ -222,9 +223,9 @@ public:
 	static ArtifactID creatureToMachineID(CreatureID id);
 	static CreatureID machineIDToCreature(ArtifactID id);
 	void makeItCreatureArt (CArtifact * a, bool onlyCreature = true);
-	void makeItCreatureArt (TArtifactInstanceID aid, bool onlyCreature = true);
+	void makeItCreatureArt (ArtifactID aid, bool onlyCreature = true);
 	void makeItCommanderArt (CArtifact * a, bool onlyCommander = true);
-	void makeItCommanderArt (TArtifactInstanceID aid, bool onlyCommander = true);
+	void makeItCommanderArt (ArtifactID aid, bool onlyCommander = true);
 	CArtHandler();
 	~CArtHandler();
 

+ 2 - 2
lib/CBattleCallback.cpp

@@ -112,13 +112,13 @@ boost::optional<TPlayerColor> CCallbackBase::getPlayerID() const
 	return player;
 }
 
-ETerrainType::ETerrainType CBattleInfoEssentials::battleTerrainType() const
+ETerrainType CBattleInfoEssentials::battleTerrainType() const
 {
 	RETURN_IF_NOT_BATTLE(ETerrainType::WRONG);
 	return getBattle()->terrainType;
 }
 
-BFieldType::BFieldType CBattleInfoEssentials::battleGetBattlefieldType() const
+BFieldType CBattleInfoEssentials::battleGetBattlefieldType() const
 {
 	RETURN_IF_NOT_BATTLE(BFieldType::NONE);
 	return getBattle()->battlefieldType;

+ 2 - 2
lib/CBattleCallback.h

@@ -164,8 +164,8 @@ public:
 
 	BattlePerspective::BattlePerspective battleGetMySide() const;
 
-	ETerrainType::ETerrainType battleTerrainType() const;
-	BFieldType::BFieldType battleGetBattlefieldType() const;
+	ETerrainType battleTerrainType() const;
+	BFieldType battleGetBattlefieldType() const;
 	std::vector<shared_ptr<const CObstacleInstance> > battleGetAllObstacles(boost::optional<BattlePerspective::BattlePerspective> perspective = boost::none) const; //returns all obstacles on the battlefield
 	TStacks battleGetAllStacks() const; //returns all stacks, alive or dead or undead or mechanical :)
 	bool battleHasNativeStack(ui8 side) const;

+ 10 - 10
lib/CGameState.cpp

@@ -778,11 +778,11 @@ CGameState::~CGameState()
 BattleInfo * CGameState::setupBattle(int3 tile, const CArmedInstance *armies[2], const CGHeroInstance * heroes[2], bool creatureBank, const CGTownInstance *town)
 {
 	const TerrainTile &t = map->getTile(tile);
-    ETerrainType::ETerrainType terrain = t.terType;
+    ETerrainType terrain = t.terType;
 	if(t.isCoastal() && !t.isWater())
         terrain = ETerrainType::SAND;
 
-	BFieldType::BFieldType terType = battleGetBattlefieldType(tile);
+	BFieldType terType = battleGetBattlefieldType(tile);
 	return BattleInfo::setupBattle(tile, terrain, terType, armies, heroes, creatureBank, town);
 }
 
@@ -1567,7 +1567,7 @@ void CGameState::init(StartInfo * si)
 			vti->possibleSpells -= s->id;
 		}
 		vti->possibleSpells.clear();
-		if(vti->getOwner() != 255)
+		if(vti->getOwner() != GameConstants::NEUTRAL_PLAYER)
 			getPlayer(vti->getOwner())->towns.push_back(vti);
 	}
 
@@ -1743,7 +1743,7 @@ void CGameState::initDuel()
 	return;
 }
 
-BFieldType::BFieldType CGameState::battleGetBattlefieldType(int3 tile) const
+BFieldType CGameState::battleGetBattlefieldType(int3 tile) const
 {
 	if(tile==int3() && curB)
 		tile = curB->tile;
@@ -1793,13 +1793,13 @@ BFieldType::BFieldType CGameState::battleGetBattlefieldType(int3 tile) const
     switch(t.terType)
 	{
     case ETerrainType::DIRT:
-		return static_cast<BFieldType::BFieldType>(rand()%3+3);
+		return BFieldType(rand()%3+3);
     case ETerrainType::SAND:
 		return BFieldType::SAND_MESAS; //TODO: coast support
     case ETerrainType::GRASS:
-		return static_cast<BFieldType::BFieldType>(rand()%2+6);
+		return BFieldType(rand()%2+6);
     case ETerrainType::SNOW:
-		return static_cast<BFieldType::BFieldType>(rand()%2+10);
+		return BFieldType(rand()%2+10);
     case ETerrainType::SWAMP:
 		return BFieldType::SWAMP_TREES;
     case ETerrainType::ROUGH:
@@ -2439,7 +2439,7 @@ void CGameState::obtainPlayersStats(SThievesGuildInfo & tgi, int level)
 		std::vector< std::pair< TPlayerColor, si64 > > stats; \
 		for(auto g = players.begin(); g != players.end(); ++g) \
 		{ \
-			if(g->second.color == 255) \
+			if(g->second.color == GameConstants::NEUTRAL_PLAYER) \
 				continue; \
 			std::pair< ui8, si64 > stat; \
 			stat.first = g->second.color; \
@@ -2940,8 +2940,8 @@ DuelParameters DuelParameters::fromJSON(const std::string &fname)
 	DuelParameters ret;
 
 	const JsonNode duelData(ResourceID("DATA/" + fname, EResType::TEXT));
-	ret.terType = static_cast<ETerrainType::ETerrainType>((int)duelData["terType"].Float());
-	ret.bfieldType = static_cast<BFieldType::BFieldType>((int)duelData["bfieldType"].Float());
+	ret.terType = ETerrainType((int)duelData["terType"].Float());
+	ret.bfieldType = BFieldType((int)duelData["bfieldType"].Float());
 	BOOST_FOREACH(const JsonNode &n, duelData["sides"].Vector())
 	{
 		SideSettings &ss = ret.sides[(int)n["side"].Float()];

+ 3 - 3
lib/CGameState.h

@@ -267,8 +267,8 @@ struct DLL_LINKAGE CPathsInfo
 
 struct DLL_EXPORT DuelParameters
 {
-	ETerrainType::ETerrainType terType;
-	BFieldType::BFieldType bfieldType;
+	ETerrainType terType;
+	BFieldType bfieldType;
 	struct DLL_EXPORT SideSettings
 	{
 		struct DLL_EXPORT StackSettings
@@ -397,7 +397,7 @@ public:
 	void giveHeroArtifact(CGHeroInstance *h, int aid);
 
 	void apply(CPack *pack);
-	BFieldType::BFieldType battleGetBattlefieldType(int3 tile) const;
+	BFieldType battleGetBattlefieldType(int3 tile) const;
 	UpgradeInfo getUpgradeInfo(const CStackInstance &stack);
 	PlayerRelations::PlayerRelations getPlayerRelations(TPlayerColor color1, TPlayerColor color2);
 	bool checkForVisitableDir(const int3 & src, const int3 & dst) const; //check if src tile is visitable from dst tile

+ 3 - 3
lib/CHeroHandler.cpp

@@ -70,7 +70,7 @@ std::vector<BattleHex> CObstacleInfo::getBlocked(BattleHex hex) const
 	return ret;
 }
 
-bool CObstacleInfo::isAppropriate(ETerrainType::ETerrainType terrainType, int specialBattlefield /*= -1*/) const
+bool CObstacleInfo::isAppropriate(ETerrainType terrainType, int specialBattlefield /*= -1*/) const
 {
 	if(specialBattlefield != -1)
 		return vstd::contains(allowedSpecialBfields, specialBattlefield);
@@ -367,8 +367,8 @@ void CHeroHandler::loadObstacles()
 			obi.defName = obs["defname"].String();
 			obi.width = obs["width"].Float();
 			obi.height = obs["height"].Float();
-			obi.allowedTerrains = obs["allowedTerrain"].convertTo<std::vector<ETerrainType::ETerrainType> >();
-			obi.allowedSpecialBfields = obs["specialBattlefields"].convertTo<std::vector<BFieldType::BFieldType> >();
+			obi.allowedTerrains = obs["allowedTerrain"].convertTo<std::vector<ETerrainType> >();
+			obi.allowedSpecialBfields = obs["specialBattlefields"].convertTo<std::vector<BFieldType> >();
 			obi.blockedTiles = obs["blockedTiles"].convertTo<std::vector<si16> >();
 			obi.isAbsoluteObstacle = absolute;
 		}

+ 3 - 3
lib/CHeroHandler.h

@@ -131,8 +131,8 @@ struct DLL_LINKAGE CObstacleInfo
 {
 	si32 ID;
 	std::string defName;
-	std::vector<ETerrainType::ETerrainType> allowedTerrains;
-	std::vector<BFieldType::BFieldType> allowedSpecialBfields;
+	std::vector<ETerrainType> allowedTerrains;
+	std::vector<BFieldType> allowedSpecialBfields;
 
 	ui8 isAbsoluteObstacle; //there may only one such obstacle in battle and its position is always the same
 	si32 width, height; //how much space to the right and up is needed to place obstacle (affects only placement algorithm)
@@ -140,7 +140,7 @@ struct DLL_LINKAGE CObstacleInfo
 
 	std::vector<BattleHex> getBlocked(BattleHex hex) const; //returns vector of hexes blocked by obstacle when it's placed on hex 'hex'
 
-	bool isAppropriate(ETerrainType::ETerrainType terrainType, int specialBattlefield = -1) const;
+	bool isAppropriate(ETerrainType terrainType, int specialBattlefield = -1) const;
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{

+ 4 - 8
lib/CObjectHandler.cpp

@@ -5964,30 +5964,26 @@ void CBank::setPropertyDer (ui8 what, ui32 val)
 			break;
 		case 18: //add Artifact
 		{
-			int id = cb->getArtSync(val, CArtifact::ART_TREASURE);
+			int id = cb->getArtSync(val, CArtifact::ART_TREASURE, true);
 			artifacts.push_back (id);
-			cb->erasePickedArt(id);
 			break;
 		}
 		case 19: //add Artifact
 		{
-			int id = cb->getArtSync(val, CArtifact::ART_MINOR);
+			int id = cb->getArtSync(val, CArtifact::ART_MINOR, true);
 			artifacts.push_back (id);
-			cb->erasePickedArt(id);
 			break;
 		}
 		case 20: //add Artifact
 		{
-			int id = cb->getArtSync(val, CArtifact::ART_MAJOR);
+			int id = cb->getArtSync(val, CArtifact::ART_MAJOR, true);
 			artifacts.push_back (id);
-			cb->erasePickedArt(id);
 			break;
 		}
 		case 21: //add Artifact
 		{
-			int id = cb->getArtSync(val, CArtifact::ART_RELIC);
+			int id = cb->getArtSync(val, CArtifact::ART_RELIC, true);
 			artifacts.push_back (id);
-			cb->erasePickedArt(id);
 			break;
 		}
 	}

+ 1 - 1
lib/CTownHandler.cpp

@@ -527,7 +527,7 @@ void CTownHandler::load(const JsonNode &source)
 		faction.creatureBg120 = node.second["creatureBackground"]["120px"].String();
 		faction.creatureBg130 = node.second["creatureBackground"]["130px"].String();
 
-		faction.nativeTerrain = static_cast<ETerrainType::ETerrainType>(vstd::find_pos(GameConstants::TERRAIN_NAMES,
+		faction.nativeTerrain = ETerrainType(vstd::find_pos(GameConstants::TERRAIN_NAMES,
 			node.second["nativeTerrain"].String()));
 		int alignment = vstd::find_pos(EAlignment::names, node.second["alignment"].String());
 		if (alignment == -1)

+ 1 - 1
lib/CTownHandler.h

@@ -173,7 +173,7 @@ public:
 
 	TFaction factionID;
 
-	ETerrainType::ETerrainType nativeTerrain;
+	ETerrainType nativeTerrain;
 	EAlignment::EAlignment alignment;
 
 	CreatureID commander;

+ 4 - 0
lib/GameConstants.cpp

@@ -52,6 +52,8 @@ ID_LIKE_OPERATORS(SecondarySkill, SecondarySkill::ESecondarySkill)
 
 ID_LIKE_OPERATORS(Obj, Obj::EObj)
 
+ID_LIKE_OPERATORS(ETerrainType, ETerrainType::EETerrainType)
+
 ID_LIKE_OPERATORS(ArtifactID, ArtifactID::EArtifactID)
 
 ID_LIKE_OPERATORS(ArtifactPosition, ArtifactPosition::EArtifactPosition)
@@ -62,6 +64,8 @@ ID_LIKE_OPERATORS(SpellID, SpellID::ESpellID)
 
 ID_LIKE_OPERATORS(BuildingID, BuildingID::EBuildingID)
 
+ID_LIKE_OPERATORS(BFieldType, BFieldType::EBFieldType)
+
 
 bmap<int, ConstTransitivePtr<CGDefInfo> > & Obj::toDefObjInfo() const
 {

+ 26 - 6
lib/GameConstants.h

@@ -551,28 +551,48 @@ namespace Battle
 	};
 }
 
-namespace ETerrainType
+class ETerrainType
 {
-	enum ETerrainType
+public:
+	enum EETerrainType
 	{
 		WRONG = -2, BORDER = -1, DIRT, SAND, GRASS, SNOW, SWAMP,
 		ROUGH, SUBTERRANEAN, LAVA, WATER, ROCK
 	};
-}
+
+	ETerrainType(EETerrainType _num = WRONG) : num(_num)
+	{}
+
+	ID_LIKE_CLASS_COMMON(ETerrainType, EETerrainType)
+
+	EETerrainType num;
+};
+
+ID_LIKE_OPERATORS_DECLS(ETerrainType, ETerrainType::EETerrainType)
 
 
-namespace BFieldType
+class BFieldType
 {
+public:
 	//   1. sand/shore   2. sand/mesas   3. dirt/birches   4. dirt/hills   5. dirt/pines   6. grass/hills   7. grass/pines 
 	//8. lava   9. magic plains   10. snow/mountains   11. snow/trees   12. subterranean   13. swamp/trees   14. fiery fields
 	//15. rock lands   16. magic clouds   17. lucid pools   18. holy ground   19. clover field   20. evil fog
 	//21. "favourable winds" text on magic plains background   22. cursed ground   23. rough   24. ship to ship   25. ship
-	enum BFieldType {NONE = -1, NONE2, SAND_SHORE, SAND_MESAS, DIRT_BIRCHES, DIRT_HILLS, DIRT_PINES, GRASS_HILLS,
+	enum EBFieldType {NONE = -1, NONE2, SAND_SHORE, SAND_MESAS, DIRT_BIRCHES, DIRT_HILLS, DIRT_PINES, GRASS_HILLS,
 		GRASS_PINES, LAVA, MAGIC_PLAINS, SNOW_MOUNTAINS, SNOW_TREES, SUBTERRANEAN, SWAMP_TREES, FIERY_FIELDS,
 		ROCKLANDS, MAGIC_CLOUDS, LUCID_POOLS, HOLY_GROUND, CLOVER_FIELD, EVIL_FOG, FAVOURABLE_WINDS, CURSED_GROUND,
 		ROUGH, SHIP_TO_SHIP, SHIP
 	};
-}
+
+	BFieldType(EBFieldType _num = NONE) : num(_num)
+	{}
+
+	ID_LIKE_CLASS_COMMON(BFieldType, EBFieldType)
+
+	EBFieldType num;
+};
+
+ID_LIKE_OPERATORS_DECLS(BFieldType, BFieldType::EBFieldType)
 
 namespace EPlayerStatus
 {

+ 3 - 9
lib/IGameCallback.cpp

@@ -187,22 +187,16 @@ void CPrivilagedInfoCallback::pickAllowedArtsSet(std::vector<const CArtifact*> &
 	out.push_back(VLC->arth->artifacts[getRandomArt(CArtifact::ART_MAJOR)]);
 }
 
-ui16 CPrivilagedInfoCallback::getRandomArt (int flags)
+ArtifactID CPrivilagedInfoCallback::getRandomArt (int flags)
 {
 	return VLC->arth->getRandomArt(flags);
 }
 
-ui16 CPrivilagedInfoCallback::getArtSync (ui32 rand, int flags)
+ArtifactID CPrivilagedInfoCallback::getArtSync (ui32 rand, int flags, bool erasePicked)
 {
-	return VLC->arth->getArtSync (rand, flags);
+	return VLC->arth->getArtSync (rand, flags, erasePicked);
 }
 
-void CPrivilagedInfoCallback::erasePickedArt (si32 id)
-{
-	VLC->arth->erasePickedArt(id);
-}
-
-
 void CPrivilagedInfoCallback::getAllowedSpells(std::vector<SpellID> &out, ui16 level)
 {
 

+ 2 - 3
lib/IGameCallback.h

@@ -170,10 +170,9 @@ public:
 	void getFreeTiles (std::vector<int3> &tiles) const; //used for random spawns
 	void getTilesInRange(boost::unordered_set<int3, ShashInt3> &tiles, int3 pos, int radious, int player=-1, int mode=0) const;  //mode 1 - only unrevealed tiles; mode 0 - all, mode -1 -  only unrevealed
 	void getAllTiles (boost::unordered_set<int3, ShashInt3> &tiles, int player=-1, int level=-1, int surface=0) const; //returns all tiles on given level (-1 - both levels, otherwise number of level); surface: 0 - land and water, 1 - only land, 2 - only water
-	ui16 getRandomArt (int flags);
-	ui16 getArtSync (ui32 rand, int flags); //synchronous
+	ArtifactID getRandomArt (int flags);
+	ArtifactID getArtSync (ui32 rand, int flags, bool erasePicked); //synchronous
 	void pickAllowedArtsSet(std::vector<const CArtifact*> &out); //gives 3 treasures, 3 minors, 1 major -> used by Black Market and Artifact Merchant
-	void erasePickedArt (si32 id);
 	void getAllowedSpells(std::vector<SpellID> &out, ui16 level);
 };
 

+ 1 - 1
lib/Mapping/CMap.h

@@ -461,7 +461,7 @@ struct DLL_LINKAGE TerrainTile
 	bool hasFavourableWinds() const;
 
 	/** the type of terrain */
-	ETerrainType::ETerrainType terType;
+	ETerrainType terType;
 
 	/** the visual representation of the terrain */
 	ui8 terView;

+ 5 - 5
lib/Mapping/CMapEditManager.cpp

@@ -140,7 +140,7 @@ void CMapEditManager::clearTerrain()
 	}
 }
 
-void CMapEditManager::drawTerrain(ETerrainType::ETerrainType terType, int posx, int posy, int width, int height, bool underground)
+void CMapEditManager::drawTerrain(ETerrainType terType, int posx, int posy, int width, int height, bool underground)
 {
 	bool mapLevel = underground ? 1 : 0;
 	for(int i = posx; i < posx + width; ++i)
@@ -224,7 +224,7 @@ void CMapEditManager::updateTerrainViews(int posx, int posy, int width, int heig
 	}
 }
 
-ETerrainGroup::ETerrainGroup CMapEditManager::getTerrainGroup(ETerrainType::ETerrainType terType) const
+ETerrainGroup::ETerrainGroup CMapEditManager::getTerrainGroup(ETerrainType terType) const
 {
 	switch(terType)
 	{
@@ -243,7 +243,7 @@ ETerrainGroup::ETerrainGroup CMapEditManager::getTerrainGroup(ETerrainType::ETer
 
 CMapEditManager::ValidationResult CMapEditManager::validateTerrainView(int posx, int posy, int mapLevel, const TerrainViewPattern & pattern, int recDepth /*= 0*/) const
 {
-	ETerrainType::ETerrainType centerTerType = map->terrain[posx][posy][mapLevel].terType;
+	ETerrainType centerTerType = map->terrain[posx][posy][mapLevel].terType;
 	int totalPoints = 0;
 	std::string transitionReplacement;
 
@@ -259,7 +259,7 @@ CMapEditManager::ValidationResult CMapEditManager::validateTerrainView(int posx,
 		int cx = posx + (i % 3) - 1;
 		int cy = posy + (i / 3) - 1;
 		bool isAlien = false;
-		ETerrainType::ETerrainType terType;
+		ETerrainType terType;
 		if(cx < 0 || cx >= map->width || cy < 0 || cy >= map->height)
 		{
 			terType = centerTerType;
@@ -371,7 +371,7 @@ CMapEditManager::ValidationResult CMapEditManager::validateTerrainView(int posx,
 	return ValidationResult(true, transitionReplacement);
 }
 
-bool CMapEditManager::isSandType(ETerrainType::ETerrainType terType) const
+bool CMapEditManager::isSandType(ETerrainType terType) const
 {
 	switch(terType)
 	{

+ 3 - 3
lib/Mapping/CMapEditManager.h

@@ -192,7 +192,7 @@ public:
 	 * @param height the width of the terrain to draw
 	 * @param underground true if you want to draw at the underground, false if open
 	 */
-	void drawTerrain(ETerrainType::ETerrainType terType, int posx, int posy, int width, int height, bool underground);
+	void drawTerrain(ETerrainType terType, int posx, int posy, int width, int height, bool underground);
 
 	/**
 	 * Inserts an object.
@@ -242,7 +242,7 @@ private:
 	 * @param terType the terrain type
 	 * @return the terrain group
 	 */
-	ETerrainGroup::ETerrainGroup getTerrainGroup(ETerrainType::ETerrainType terType) const;
+	ETerrainGroup::ETerrainGroup getTerrainGroup(ETerrainType terType) const;
 
 	/**
 	 * Validates the terrain view of the given position and with the given pattern.
@@ -262,7 +262,7 @@ private:
 	 * @param terType the terrain type to test
 	 * @return true if the terrain type is a sand type, otherwise false
 	 */
-	bool isSandType(ETerrainType::ETerrainType terType) const;
+	bool isSandType(ETerrainType terType) const;
 
 	/**
 	 * Gets a flipped pattern.

+ 1 - 1
lib/Mapping/MapFormatH3M.cpp

@@ -711,7 +711,7 @@ void CMapLoaderH3M::readTerrain()
 		{
 			for(int z = 0; z < map->height; z++)
 			{
-				map->terrain[z][c][a].terType = static_cast<ETerrainType::ETerrainType>(reader.readUInt8());
+				map->terrain[z][c][a].terType = ETerrainType(reader.readUInt8());
 				map->terrain[z][c][a].terView = reader.readUInt8();
 				map->terrain[z][c][a].riverType = static_cast<ERiverType::ERiverType>(reader.readUInt8());
 				map->terrain[z][c][a].riverDir = reader.readUInt8();