Bläddra i källkod

Now parsing CREXPBON into Bonus System, with limiters. StackExperience class removed.

Exp ranks are now calculated, though exp is never set.
DjWarmonger 14 år sedan
förälder
incheckning
c0f2b3f32b
6 ändrade filer med 147 tillägg och 55 borttagningar
  1. 82 39
      lib/CCreatureHandler.cpp
  2. 5 4
      lib/CCreatureHandler.h
  3. 23 0
      lib/CCreatureSet.cpp
  4. 1 0
      lib/CCreatureSet.h
  5. 10 0
      lib/HeroBonus.cpp
  6. 26 12
      lib/HeroBonus.h

+ 82 - 39
lib/CCreatureHandler.cpp

@@ -628,25 +628,29 @@ void CCreatureHandler::loadCreatures()
 		buf = bitmaph->getTextFile("CREXPBON.TXT");
 		int it = 0;
 		si32 creid = -1;
-		commonBonuses.resize(8); //8 tiers
-		stackExperience b;
-		b.expBonuses.resize(10);
+		Bonus b; //prototype with some default properties
 		b.source = Bonus::STACK_EXPERIENCE;
+		b.valType = Bonus::ADDITIVE_VALUE;
 		b.additionalInfo = 0;
-		b.enable = false; //Bonuses are always active by default
+		BonusList bl;
 
 		loadToIt (dump2, buf, it, 3); //ignore first line
 		loadToIt (dump2, buf, it, 4); //ignore index
-		loadStackExp(b, buf, it);
+
+		loadStackExp(b, bl, buf, it);
+		BOOST_FOREACH(Bonus * b, bl)
+			addBonusForAllCreatures(b); //health bonus is common for all
+
 		loadToIt (dump2, buf, it, 4); //crop comment
-		for (i = 0; i < 8; ++i)
+		for (i = 1; i < 8; ++i)
 		{
-			commonBonuses[i].push_back(new stackExperience(b));//health bonus common for all
 			for (int j = 0; j < 4; ++j) //four modifiers common for tiers
 			{
 				loadToIt (dump2, buf, it, 4); //ignore index
-				loadStackExp(b, buf, it);
-				commonBonuses[i].push_back(new stackExperience(b));
+				bl.clear();
+				loadStackExp(b, bl, buf, it);
+				BOOST_FOREACH(Bonus * b, bl)
+					addBonusForTier(i, b);
 				loadToIt (dump2, buf, it, 3); //crop comment
 			}
 		}
@@ -654,20 +658,33 @@ void CCreatureHandler::loadCreatures()
 		{
 			loadToIt(creid, buf, it, 4); //get index
 			b.id = creid; //id = this particular creature ID
-			loadStackExp(b, buf, it);
-			creatures[creid]->bonuses.push_back(new stackExperience(b)); //experience list is common for creatures of that type
+			loadStackExp(b, creatures[creid]->bonuses, buf, it); //add directly to CCreature Node
 			loadToIt (dump2, buf, it, 3); //crop comment
 		} while (it < buf.size());
 
-//  		BOOST_FOREACH(CCreature *c, creatures)
-//  		{
-//  			if (it = c->level < 7)
-//  				std::copy(commonBonuses[it-1].begin(), commonBonuses[it-1].end(), c->bonuses.begin());
-//  			else
-//  				std::copy(commonBonuses[7].begin(), commonBonuses[7].end(), c->bonuses.begin()); //common for tiers 8+
-//  		}
-	} //end of stack experience
+		//Calculate rank exp values, formula appears complicated bu no parsing needed
+		expRanks.resize(8);
+		int dif = 0;
+		it = 8000; //ignore name of this variable
+		expRanks[0].push_back(it);
+		for (int j = 1; j < 10; ++j) //used for tiers 8-10, and all other probably
+		{
+			expRanks[0].push_back(expRanks[0][j-1] + dif);
+			dif += it/5;
+		}
+		for (int i = 1; i < 8; ++i)
+		{
+			dif = 0;
+			it = 1000 * i;
+			expRanks[i].push_back(it);
+			for (int j = 1; j < 10; ++j)
+			{
+				expRanks[i].push_back(expRanks[i][j-1] + dif);
+				dif += it/5;
+			}
+		}
 
+	}//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);
@@ -743,15 +760,18 @@ void CCreatureHandler::loadUnitAnimInfo(CCreature & unit, std::string & src, int
 	i+=2;
 }
 
-void CCreatureHandler::loadStackExp(stackExperience & b, std::string & src, int & it) //help function for parsing CREXPBON.txt, assuming all its details are already defined
-{
+void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, std::string & src, int & it) //help function for parsing CREXPBON.txt
+{ //TODO: handle rank limiters
 	std::string buf, mod;
+	bool enable = false; //some bonuses are activated with values 2 or 1
 	loadToIt(buf, src, it, 4);
 	loadToIt(mod, src, it, 4);
+
 	switch (buf[0])
 	{
 	case 'H':
 		b.type = Bonus::STACK_HEALTH;
+		b.valType = Bonus::PERCENT_TO_BASE;
 		break;
 	case 'A':
 		b.type = Bonus::PRIMARY_SKILL;
@@ -784,7 +804,7 @@ void CCreatureHandler::loadStackExp(stackExperience & b, std::string & src, int
 		b.type = Bonus::ADDITIONAL_RETALIATION; break;
 
 	case 'f': //on-off skill
-		b.enable = true; //sometimes format is: 2 -> 0, 1 -> 1
+		enable = true; //sometimes format is: 2 -> 0, 1 -> 1
 		switch (mod[0])
 		{
 			case 'A':
@@ -808,7 +828,7 @@ void CCreatureHandler::loadStackExp(stackExperience & b, std::string & src, int
 			case 'p': //Mind spells
 			case 'P':
 				{
-					loadMindImmunity(b, src, it);
+					loadMindImmunity(b, bl, src, it);
 					return;
 				}
 				return;
@@ -829,7 +849,7 @@ void CCreatureHandler::loadStackExp(stackExperience & b, std::string & src, int
 		}
 		break;
 	case 'w': //specific spell immunities, enabled/disabled
-		b.enable = true;
+		enable = true;
 		switch (mod[0])
 		{
 			case 'B': //Blind
@@ -877,11 +897,11 @@ void CCreatureHandler::loadStackExp(stackExperience & b, std::string & src, int
 		break;
 
 	case 'i':
-		b.enable = true;
+		enable = true;
 		b.type = Bonus::NO_DISTANCE_PENALTY;
 		break;
 	case 'o':
-		b.enable = true;
+		enable = true;
 		b.type = Bonus::NO_OBSTACLES_PENALTY;
 		break;
 
@@ -902,28 +922,51 @@ void CCreatureHandler::loadStackExp(stackExperience & b, std::string & src, int
 	{
 		case '+':
 		case '=': //should we allow percent values to stack or pick highest?
-			b.valType = Bonus::BASE_NUMBER;
+			b.valType = Bonus::ADDITIVE_VALUE;
 			break;
 	}
-	loadToIt (b.val, src, it, 4); //basic value, not particularly useful but existent
-	for (int i = 0; i < 10; ++i)
+
+	//limiters, range
+	si32 lastVal, curVal, lastLev = 0;
+
+	if (enable) //0 and 2 means non-active, 1 - active
 	{
-		loadToIt (b.expBonuses[i], src, it, 4); //vector must have length 10
+		b.val = 0; //on-off ability, no value specified
+		loadToIt (curVal, src, it, 4); // 0 level is never active
+		for (int i = 1; i < 11; ++i)
+		{
+			loadToIt (curVal, src, it, 4);
+			if (curVal == 1)
+			{
+				b.limiter.reset (new ExpRankLimiter(i));
+				bl.push_back(new Bonus(b));
+				break; //never turned off it seems
+			}
+		}
 	}
-	if (b.enable) //switch 2 to 0
+	else
 	{
-		if (b.val == 2)
-			b.val = 0;
-		for (int i = 0; i < 10; ++i)
+		loadToIt (lastVal, src, it, 4); //basic value, not particularly useful but existent
+		for (int i = 1; i < 11; ++i)
 		{
-			if (b.expBonuses[i] == 2)
-				b.expBonuses[i] = 0;
-			else break; //higher levels are rarely disabled?
+			loadToIt (curVal, src, it, 4);
+			if (curVal > lastVal) //threshold, add last bonus
+			{
+				b.val = lastVal;
+				b.limiter.reset (new ExpRankLimiter(i));
+				bl.push_back(new Bonus(b));
+				lastLev = i; //start new range from here, i = previous rank
+			}
+			else if (curVal < lastVal)
+			{
+				b.val = lastVal;
+				b.limiter.reset (new RankRangeLimiter(lastLev, i));
+			}
 		}
 	}
 }
 
-void CCreatureHandler::loadMindImmunity(stackExperience & b, std::string & src, int & it)
+void CCreatureHandler::loadMindImmunity(Bonus & b, BonusList & bl, std::string & src, int & it)
 {
 	CCreature * cre = creatures[b.id]; //odd workaround
 
@@ -944,7 +987,7 @@ void CCreatureHandler::loadMindImmunity(stackExperience & b, std::string & src,
 	for (int g=0; g < mindSpells.size(); ++g)
 	{
 		b.subtype = mindSpells[g];
-		cre->bonuses.push_back(new stackExperience(b));
+		cre->bonuses.push_back(new Bonus(b));
 	}
 }
 

+ 5 - 4
lib/CCreatureHandler.h

@@ -99,7 +99,8 @@ public:
 };
 
 class DLL_EXPORT CCreatureHandler
-{	
+{
+private: //?
 	CBonusSystemNode allCreatures, creaturesOfLevel[CREATURES_PER_TOWN + 1];//index 0 is used for creatures of unknown tier or outside <1-7> range
 public:
 	std::set<int> notUsedMonsters;
@@ -112,13 +113,13 @@ public:
 	int factionToTurretCreature[F_NUMBER]; //which creature's animation should be used to dispaly creature in turret while siege
 
 	std::map<TBonusType, std::pair<std::string, std::string> > stackBonuses; // bonus => name, description
-	std::vector<BonusList> commonBonuses; // levels 1-8 from CREXPBON.txt
+	std::vector<std::vector<ui32>> expRanks; // stack experience needed for certain rank, index 0 for other tiers (?)
 
 	void loadCreatures();
 	void loadAnimationInfo();
 	void loadUnitAnimInfo(CCreature & unit, std::string & src, int & i);
-	void loadStackExp(stackExperience & b, std::string & src, int & it);
-	void loadMindImmunity(stackExperience & b, std::string & src, int & it); //multiple bonuses at once
+	void loadStackExp(Bonus & b, BonusList & bl, std::string & src, int & it);
+	void loadMindImmunity(Bonus & b, BonusList & bl, std::string & src, int & it); //multiple bonuses at once
 	int stringToNumber(std::string & s);//help function for parsing CREXPBON.txt
 
 	bool isGood (si8 faction) const;

+ 23 - 0
lib/CCreatureSet.cpp

@@ -430,6 +430,29 @@ int CStackInstance::getQuantityID() const
 	return CCreature::getQuantityID(count);
 }
 
+int CStackInstance::getExpRank() const
+{
+	int tier = type->level;
+	if (isbetw(tier, 1, 7))
+	{
+		for (int i = VLC->creh->expRanks[tier].size()-2; i >-1; --i)//sic!
+		{ //exp values vary from 1st level to max exp at 11th level
+			if (experience >= VLC->creh->expRanks[tier][i])
+				return ++i; //faster, but confusing - 0 index mean 1st level of experience
+		}
+		return 0;
+	}
+	else //higher tier
+	{
+		for (int i = VLC->creh->expRanks[tier].size()-2; i >-1; --i)
+		{
+			if (experience >= VLC->creh->expRanks[0][i])
+				return ++i;
+		}
+		return 0;
+	}
+}
+
 void CStackInstance::setType(int creID)
 {
 	setType(VLC->creh->creatures[creID]);

+ 1 - 0
lib/CCreatureSet.h

@@ -49,6 +49,7 @@ public:
 
 	int getQuantityID() const;
 	std::string getQuantityTXT(bool capitalized = true) const;
+	int getExpRank() const;
 	void init();
 	CStackInstance();
 	CStackInstance(TCreature id, TQuantity count);

+ 10 - 0
lib/HeroBonus.cpp

@@ -771,4 +771,14 @@ bool CreatureAlignmentLimiter::limit(const Bonus *b, const CBonusSystemNode &nod
 		tlog1 << "Warning: illegal alignment in limiter!\n";
 		return true;
 	}
+}
+
+ExpRankLimiter::ExpRankLimiter(ui8 Rank)
+	:rank(Rank)
+{
+}
+
+RankRangeLimiter::RankRangeLimiter(ui8 Min, ui8 Max)
+	:min(Min), max(Max)
+{
 }

+ 26 - 12
lib/HeroBonus.h

@@ -304,18 +304,6 @@ struct DLL_EXPORT Bonus
 	Bonus *addLimiter(ILimiter *Limiter); //returns this for convenient chain-calls
 };
 
-struct DLL_EXPORT stackExperience : public Bonus
-{
-	std::vector<si32> expBonuses; // variations for levels 1-10, copied to val field;
-	bool enable; //if true - turns ability on / off for zero value
-
-	template <typename Handler> void serialize(Handler &h, const int version)
-	{
-		h & static_cast<Bonus&>(this);
-		h & expBonuses & enable;
-	}
-};
-
 DLL_EXPORT std::ostream & operator<<(std::ostream &out, const Bonus &bonus);
 
 class BonusList : public std::list<Bonus*>
@@ -630,6 +618,32 @@ public:
 	}
 };
 
+class DLL_EXPORT ExpRankLimiter : public ILimiter //applies to creatures with Rank >= rank
+{
+public:
+	ui8 rank;
+
+	ExpRankLimiter(ui8 Rank);
+
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & rank;
+	}
+};
+
+class DLL_EXPORT RankRangeLimiter : public ILimiter //applies to creatures with min <= Rank <= max
+{
+public:
+	ui8 min, max;
+
+	RankRangeLimiter(ui8 Min, ui8 Max);
+
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & min & max;
+	}
+};
+
 const CCreature *retrieveCreature(const CBonusSystemNode *node);
 
 namespace Selector