浏览代码

Some preparations towards handling stack experience by the new bonus system. New nodes for controlling premies for creatures of given tier (level). Minor changes.

Michał W. Urbańczyk 15 年之前
父节点
当前提交
979f77d900
共有 7 个文件被更改,包括 106 次插入42 次删除
  1. 7 0
      global.h
  2. 73 16
      lib/CCreatureHandler.cpp
  3. 6 6
      lib/CCreatureHandler.h
  4. 1 1
      lib/CCreatureSet.cpp
  5. 10 14
      lib/CGameState.cpp
  6. 3 1
      lib/HeroBonus.cpp
  7. 6 4
      lib/HeroBonus.h

+ 7 - 0
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
 {

+ 73 - 16
lib/CCreatureHandler.cpp

@@ -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);
 }

+ 6 - 6
lib/CCreatureHandler.h

@@ -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;
 	}
 };
 

+ 1 - 1
lib/CCreatureSet.cpp

@@ -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)

+ 10 - 14
lib/CGameState.cpp

@@ -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;

+ 3 - 1
lib/HeroBonus.cpp

@@ -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()

+ 6 - 4
lib/HeroBonus.h

@@ -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;
 	}