mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Some preparations towards handling stack experience by the new bonus system. New nodes for controlling premies for creatures of given tier (level). Minor changes.
This commit is contained in:
		
							
								
								
									
										7
									
								
								global.h
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								global.h
									
									
									
									
									
								
							| @@ -100,6 +100,7 @@ const int HEROI_TYPE = 34, | ||||
| 	CREI_TYPE = 54, | ||||
| 	EVENTI_TYPE = 26; | ||||
|  | ||||
| const int CREATURES_COUNT = 197; | ||||
| const int CRE_LEVELS = 10; | ||||
| const int F_NUMBER = 9; //factions (town types) quantity | ||||
| const int PLAYER_LIMIT = 8; //player limit per map | ||||
| @@ -554,6 +555,12 @@ bool isbetw(const t1 &a, const t2 &b, const t3 &c) //checks if a is between b an | ||||
| 	return a > b && a < c; | ||||
| } | ||||
|  | ||||
| template <typename t1, typename t2, typename t3> | ||||
| bool iswith(const t1 &a, const t2 &b, const t3 &c) //checks if a is within b and c | ||||
| { | ||||
| 	return a >= b && a <= c; | ||||
| } | ||||
|  | ||||
| template <typename T>  | ||||
| void delNull(T* &ptr) //deleted pointer and sets it to NULL | ||||
| { | ||||
|   | ||||
| @@ -13,6 +13,7 @@ | ||||
| #include "../lib/VCMI_Lib.h" | ||||
| #include "../lib/CGameState.h" | ||||
| #include <boost/foreach.hpp> | ||||
| #include <boost/lexical_cast.hpp> | ||||
|  | ||||
| using namespace boost::assign; | ||||
| extern CLodHandler * bitmaph; | ||||
| @@ -47,6 +48,11 @@ CCreatureHandler::CCreatureHandler() | ||||
| 	// Neutral: Stronghold, Fortess, Conflux | ||||
| 	factionAlignments += 1, 1, 1, -1, -1, -1, 0, 0, 0; | ||||
| 	doubledCreatures +=  4, 14, 20, 28, 42, 44, 60, 70, 72, 85, 86, 100, 104; //according to Strategija | ||||
|  | ||||
| 	allCreatures.description = "All creatures"; | ||||
| 	creaturesOfLevel[0].description = "Creatures of unnormalized tier"; | ||||
| 	for(int i = 1; i < ARRAY_COUNT(creaturesOfLevel); i++) | ||||
| 		creaturesOfLevel[i].description = "Creatures of tier " + boost::lexical_cast<std::string>(i); | ||||
| } | ||||
|  | ||||
| int CCreature::getQuantityID(const int & quantity) | ||||
| @@ -147,7 +153,7 @@ bool CCreature::valid() const | ||||
|  | ||||
| std::string CCreature::nodeName() const | ||||
| { | ||||
| 	return "Type of creature " + namePl; | ||||
| 	return "\"" + namePl + "\""; | ||||
| } | ||||
|  | ||||
| int readNumber(int & befi, int & i, int andame, std::string & buf) //helper function for void CCreatureHandler::loadCreatures() and loadUnitAnimInfo() | ||||
| @@ -469,8 +475,6 @@ void CCreatureHandler::loadCreatures() | ||||
| 	} | ||||
| 	ifs.close(); | ||||
| 	ifs.clear(); | ||||
| 	for(i = 1; i <= CRE_LEVELS; i++) | ||||
| 		levelCreatures[i]; | ||||
|  | ||||
| 	tlog5 << "\t\tReading config/monsters.txt" << std::endl; | ||||
| 	ifs.open(DATA_DIR "/config/monsters.txt"); | ||||
| @@ -479,13 +483,19 @@ void CCreatureHandler::loadCreatures() | ||||
| 		{ | ||||
| 			int id, lvl; | ||||
| 			ifs >> id >> lvl; | ||||
| 			if(lvl>0) | ||||
| 			{ | ||||
| 				creatures[id]->level = lvl; | ||||
| 				levelCreatures[lvl].push_back(creatures[id]); | ||||
| 			} | ||||
| 			if(!ifs.good()) | ||||
| 				break; | ||||
| 			CCreature *c = creatures[id]; | ||||
| 			if(isbetw(lvl, 0, ARRAY_COUNT(creaturesOfLevel))) | ||||
| 				c->attachTo(&creaturesOfLevel[lvl]); | ||||
| 			else | ||||
| 				c->attachTo(&creaturesOfLevel[0]); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	BOOST_FOREACH(CBonusSystemNode &b, creaturesOfLevel) | ||||
| 		b.attachTo(&allCreatures); | ||||
|  | ||||
| 	ifs.close(); | ||||
| 	ifs.clear(); | ||||
|  | ||||
| @@ -657,6 +667,10 @@ void CCreatureHandler::loadCreatures() | ||||
| //  				std::copy(commonBonuses[7].begin(), commonBonuses[7].end(), c->bonuses.begin()); //common for tiers 8+ | ||||
| //  		} | ||||
| 	} //end of stack experience | ||||
|  | ||||
| 	//experiment - add 100 to attack for creatures of tier 1 | ||||
| // 	Bonus *b = new Bonus(Bonus::PERMANENT, Bonus::PRIMARY_SKILL, Bonus::OTHER, +100, 0, 0); | ||||
| // 	addBonusForTier(1, b); | ||||
| } | ||||
|  | ||||
| void CCreatureHandler::loadAnimationInfo() | ||||
| @@ -944,18 +958,61 @@ CCreatureHandler::~CCreatureHandler() | ||||
| { | ||||
| } | ||||
|  | ||||
| int CCreatureHandler::pickRandomMonster(const boost::function<int()> &randGen) const | ||||
| static int retreiveRandNum(const boost::function<int()> &randGen) | ||||
| { | ||||
| 	if(randGen) | ||||
| 		return randGen(); | ||||
| 	else | ||||
| 		return rand(); | ||||
| } | ||||
|  | ||||
| template <typename T> const T & pickRandomElementOf(const std::vector<T> &v, const boost::function<int()> &randGen) | ||||
| { | ||||
| 	return v[retreiveRandNum(randGen) % v.size()]; | ||||
| } | ||||
|  | ||||
| int CCreatureHandler::pickRandomMonster(const boost::function<int()> &randGen, int tier) const | ||||
| { | ||||
| 	int r = 0; | ||||
| 	do  | ||||
| 	if(tier == -1) //pick any allowed creature | ||||
| 	{ | ||||
| 		if(randGen) | ||||
| 			r = randGen(); | ||||
| 		else | ||||
| 			r = rand(); | ||||
| 		do  | ||||
| 		{ | ||||
| 			pickRandomElementOf(creatures, randGen); | ||||
| 			//r = retreiveRandNum(randGen) % CREATURES_COUNT; | ||||
| 		} while (vstd::contains(VLC->creh->notUsedMonsters,r)); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		assert(iswith(tier, 1, 7)); | ||||
| 		std::vector<int> allowed; | ||||
| 		BOOST_FOREACH(const CBonusSystemNode *b, creaturesOfLevel[tier].children) | ||||
| 		{ | ||||
| 			assert(b->nodeType == CBonusSystemNode::CREATURE); | ||||
| 			int creid = static_cast<const CCreature*>(b)->idNumber; | ||||
| 			if(!vstd::contains(notUsedMonsters, creid)) | ||||
|  | ||||
| 		r %= 197; | ||||
| 	} while (vstd::contains(VLC->creh->notUsedMonsters,r)); | ||||
| 				allowed.push_back(creid); | ||||
| 		} | ||||
|  | ||||
| 		if(!allowed.size()) | ||||
| 		{ | ||||
| 			tlog2 << "Cannot pick a random creature of tier " << tier << "!\n"; | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		return pickRandomElementOf(allowed, randGen); | ||||
| 	} | ||||
| 	return r; | ||||
| } | ||||
|  | ||||
| void CCreatureHandler::addBonusForTier(int tier, Bonus *b) | ||||
| { | ||||
| 	assert(iswith(tier, 1, 7)); | ||||
| 	creaturesOfLevel[tier].addNewBonus(b); | ||||
| } | ||||
|  | ||||
| void CCreatureHandler::addBonusForAllCreatures(Bonus *b) | ||||
| { | ||||
| 	allCreatures.addNewBonus(b); | ||||
| } | ||||
| @@ -98,15 +98,13 @@ public: | ||||
| 	friend class CCreatureHandler; | ||||
| }; | ||||
|  | ||||
|  | ||||
| class DLL_EXPORT CCreatureHandler | ||||
| {	 | ||||
| 	CBonusSystemNode allCreatures, creaturesOfLevel[CREATURES_PER_TOWN + 1];//index 0 is used for creatures of unknown tier or outside <1-7> range | ||||
| public: | ||||
| 	CBonusSystemNode *globalEffects; | ||||
| 	std::set<int> notUsedMonsters; | ||||
| 	std::set<TCreature> doubledCreatures; //they get double week | ||||
| 	std::vector<ConstTransitivePtr<CCreature> > creatures; //creature ID -> creature info | ||||
| 	bmap<int,std::vector<ConstTransitivePtr< CCreature> > > levelCreatures; //level -> list of creatures | ||||
| 	bmap<std::string,int> nameToID; | ||||
| 	bmap<int,std::string> idToProjectile; | ||||
| 	bmap<int,bool> idToProjectileSpin; //if true, appropriate projectile is spinning during flight | ||||
| @@ -126,8 +124,9 @@ public: | ||||
| 	bool isGood (si8 faction) const; | ||||
| 	bool isEvil (si8 faction) const; | ||||
|  | ||||
| 	int pickRandomMonster(const boost::function<int()> &randGen = 0) const; | ||||
|  | ||||
| 	int pickRandomMonster(const boost::function<int()> &randGen = 0, int tier = -1) const; //tier <1 - CREATURES_PER_TOWN> or -1 for any | ||||
| 	void addBonusForTier(int tier, Bonus *b); //tier must be <1-7> | ||||
| 	void addBonusForAllCreatures(Bonus *b); | ||||
|  | ||||
| 	CCreatureHandler(); | ||||
| 	~CCreatureHandler(); | ||||
| @@ -136,7 +135,8 @@ public: | ||||
| 	{ | ||||
| 		//TODO: should be optimized, not all these informations needs to be serialized (same for ccreature) | ||||
| 		h & notUsedMonsters & creatures & nameToID & idToProjectile & idToProjectileSpin & factionToTurretCreature; | ||||
| 		h & levelCreatures & globalEffects;		 | ||||
| 		h & allCreatures; | ||||
| 		h & creaturesOfLevel; | ||||
| 	} | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -588,7 +588,7 @@ CStackInstance::~CStackInstance() | ||||
| std::string CStackInstance::nodeName() const | ||||
| { | ||||
| 	std::ostringstream oss; | ||||
| 	oss << "Stack of " << count << " creatures of "; | ||||
| 	oss << "Stack of " << count << " of "; | ||||
| 	if(type) | ||||
| 		oss << type->namePl; | ||||
| 	else if(idRand) | ||||
|   | ||||
| @@ -523,21 +523,17 @@ std::pair<int,int> CGameState::pickObject (CGObjectInstance *obj) | ||||
| 	case 69: //random relic artifact | ||||
| 		return std::pair<int,int>(5, VLC->arth->getRandomArt (CArtifact::ART_RELIC)); | ||||
| 	case 70: //random hero | ||||
| 		{ | ||||
| 			return std::pair<int,int>(HEROI_TYPE,pickHero(obj->tempOwner)); | ||||
| 		} | ||||
| 		return std::pair<int,int>(HEROI_TYPE,pickHero(obj->tempOwner)); | ||||
| 	case 71: //random monster | ||||
| 		{ | ||||
| 			return std::pair<int,int>(54,VLC->creh->pickRandomMonster(boost::ref(ran)));  | ||||
| 		} | ||||
| 		return std::pair<int,int>(54,VLC->creh->pickRandomMonster(boost::ref(ran)));  | ||||
| 	case 72: //random monster lvl1 | ||||
| 		return std::pair<int,int>(54,VLC->creh->levelCreatures[1][ran()%VLC->creh->levelCreatures[1].size()]->idNumber);  | ||||
| 		return std::pair<int,int>(54,VLC->creh->pickRandomMonster(boost::ref(ran), 1));  | ||||
| 	case 73: //random monster lvl2 | ||||
| 		return std::pair<int,int>(54,VLC->creh->levelCreatures[2][ran()%VLC->creh->levelCreatures[2].size()]->idNumber); | ||||
| 		return std::pair<int,int>(54,VLC->creh->pickRandomMonster(boost::ref(ran), 2)); | ||||
| 	case 74: //random monster lvl3 | ||||
| 		return std::pair<int,int>(54,VLC->creh->levelCreatures[3][ran()%VLC->creh->levelCreatures[3].size()]->idNumber); | ||||
| 		return std::pair<int,int>(54,VLC->creh->pickRandomMonster(boost::ref(ran), 3)); | ||||
| 	case 75: //random monster lvl4 | ||||
| 		return std::pair<int,int>(54,VLC->creh->levelCreatures[4][ran()%VLC->creh->levelCreatures[4].size()]->idNumber); | ||||
| 		return std::pair<int,int>(54, VLC->creh->pickRandomMonster(boost::ref(ran), 4)); | ||||
| 	case 76: //random resource | ||||
| 		return std::pair<int,int>(79,ran()%7); //now it's OH3 style, use %8 for mithril  | ||||
| 	case 77: //random town | ||||
| @@ -559,11 +555,11 @@ std::pair<int,int> CGameState::pickObject (CGObjectInstance *obj) | ||||
| 			return std::pair<int,int>(TOWNI_TYPE,f);  | ||||
| 		} | ||||
| 	case 162: //random monster lvl5 | ||||
| 		return std::pair<int,int>(54,VLC->creh->levelCreatures[5][ran()%VLC->creh->levelCreatures[5].size()]->idNumber); | ||||
| 		return std::pair<int,int>(54, VLC->creh->pickRandomMonster(boost::ref(ran), 5)); | ||||
| 	case 163: //random monster lvl6 | ||||
| 		return std::pair<int,int>(54,VLC->creh->levelCreatures[6][ran()%VLC->creh->levelCreatures[6].size()]->idNumber); | ||||
| 		return std::pair<int,int>(54, VLC->creh->pickRandomMonster(boost::ref(ran), 6)); | ||||
| 	case 164: //random monster lvl7 | ||||
| 		return std::pair<int,int>(54,VLC->creh->levelCreatures[7][ran()%VLC->creh->levelCreatures[7].size()]->idNumber);  | ||||
| 		return std::pair<int,int>(54, VLC->creh->pickRandomMonster(boost::ref(ran), 7)); | ||||
| 	case 216: //random dwelling | ||||
| 		{ | ||||
| 			int faction = ran()%F_NUMBER; | ||||
| @@ -762,6 +758,7 @@ CGameState::CGameState() | ||||
| 	applierGs = new CApplier<CBaseForGSApply>; | ||||
| 	registerTypes2(*applierGs); | ||||
| 	objCaller = new CObjectCallersHandler; | ||||
| 	globalEffects.description = "Global effects"; | ||||
| } | ||||
| CGameState::~CGameState() | ||||
| { | ||||
| @@ -871,7 +868,6 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed ) | ||||
|  | ||||
| 	seed = Seed; | ||||
| 	ran.seed((boost::int32_t)seed); | ||||
| 	VLC->creh->globalEffects = &globalEffects; | ||||
| 	scenarioOps = new StartInfo(*si); | ||||
| 	initialOpts = new StartInfo(*si); | ||||
| 	si = NULL; | ||||
|   | ||||
| @@ -439,7 +439,9 @@ bool CBonusSystemNode::isIndependentNode() const | ||||
|  | ||||
| std::string CBonusSystemNode::nodeName() const | ||||
| { | ||||
| 	return std::string("Bonus system node of type ") + typeid(*this).name(); | ||||
| 	return description.size()  | ||||
| 		? description | ||||
| 		: std::string("Bonus system node of type ") + typeid(*this).name(); | ||||
| } | ||||
|  | ||||
| void CBonusSystemNode::deserializationFix() | ||||
|   | ||||
| @@ -362,13 +362,14 @@ public: | ||||
| class DLL_EXPORT CBonusSystemNode | ||||
| { | ||||
| public: | ||||
| 	BonusList bonuses; //wielded bonuses (local and up-propagated here) | ||||
| 	BonusList exportedBonuses; | ||||
| 	BonusList bonuses; //wielded bonuses (local or up-propagated here) | ||||
| 	BonusList exportedBonuses; //bonuses coming from this node (wielded or propagated away) | ||||
|  | ||||
| 	TNodesVector parents, //parents -> we inherit bonuses from them, we may attach our bonuses to them | ||||
| 									children; | ||||
| 	TNodesVector parents; //parents -> we inherit bonuses from them, we may attach our bonuses to them | ||||
| 	TNodesVector children; | ||||
|  | ||||
| 	ui8 nodeType; | ||||
| 	std::string description; | ||||
|  | ||||
| 	CBonusSystemNode(); | ||||
| 	virtual ~CBonusSystemNode(); | ||||
| @@ -438,6 +439,7 @@ public: | ||||
| 	{ | ||||
| 		h & bonuses & nodeType; | ||||
| 		h & exportedBonuses; | ||||
| 		h & description; | ||||
| 		//h & parents & children; | ||||
| 	} | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user