mirror of
https://github.com/vcmi/vcmi.git
synced 2025-07-17 01:32:21 +02:00
Now parsing CREXPBON into Bonus System, with limiters. StackExperience class removed.
Exp ranks are now calculated, though exp is never set.
This commit is contained in:
@ -628,25 +628,29 @@ void CCreatureHandler::loadCreatures()
|
|||||||
buf = bitmaph->getTextFile("CREXPBON.TXT");
|
buf = bitmaph->getTextFile("CREXPBON.TXT");
|
||||||
int it = 0;
|
int it = 0;
|
||||||
si32 creid = -1;
|
si32 creid = -1;
|
||||||
commonBonuses.resize(8); //8 tiers
|
Bonus b; //prototype with some default properties
|
||||||
stackExperience b;
|
|
||||||
b.expBonuses.resize(10);
|
|
||||||
b.source = Bonus::STACK_EXPERIENCE;
|
b.source = Bonus::STACK_EXPERIENCE;
|
||||||
|
b.valType = Bonus::ADDITIVE_VALUE;
|
||||||
b.additionalInfo = 0;
|
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, 3); //ignore first line
|
||||||
loadToIt (dump2, buf, it, 4); //ignore index
|
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
|
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
|
for (int j = 0; j < 4; ++j) //four modifiers common for tiers
|
||||||
{
|
{
|
||||||
loadToIt (dump2, buf, it, 4); //ignore index
|
loadToIt (dump2, buf, it, 4); //ignore index
|
||||||
loadStackExp(b, buf, it);
|
bl.clear();
|
||||||
commonBonuses[i].push_back(new stackExperience(b));
|
loadStackExp(b, bl, buf, it);
|
||||||
|
BOOST_FOREACH(Bonus * b, bl)
|
||||||
|
addBonusForTier(i, b);
|
||||||
loadToIt (dump2, buf, it, 3); //crop comment
|
loadToIt (dump2, buf, it, 3); //crop comment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -654,20 +658,33 @@ void CCreatureHandler::loadCreatures()
|
|||||||
{
|
{
|
||||||
loadToIt(creid, buf, it, 4); //get index
|
loadToIt(creid, buf, it, 4); //get index
|
||||||
b.id = creid; //id = this particular creature ID
|
b.id = creid; //id = this particular creature ID
|
||||||
loadStackExp(b, buf, it);
|
loadStackExp(b, creatures[creid]->bonuses, buf, it); //add directly to CCreature Node
|
||||||
creatures[creid]->bonuses.push_back(new stackExperience(b)); //experience list is common for creatures of that type
|
|
||||||
loadToIt (dump2, buf, it, 3); //crop comment
|
loadToIt (dump2, buf, it, 3); //crop comment
|
||||||
} while (it < buf.size());
|
} while (it < buf.size());
|
||||||
|
|
||||||
// BOOST_FOREACH(CCreature *c, creatures)
|
//Calculate rank exp values, formula appears complicated bu no parsing needed
|
||||||
// {
|
expRanks.resize(8);
|
||||||
// if (it = c->level < 7)
|
int dif = 0;
|
||||||
// std::copy(commonBonuses[it-1].begin(), commonBonuses[it-1].end(), c->bonuses.begin());
|
it = 8000; //ignore name of this variable
|
||||||
// else
|
expRanks[0].push_back(it);
|
||||||
// std::copy(commonBonuses[7].begin(), commonBonuses[7].end(), c->bonuses.begin()); //common for tiers 8+
|
for (int j = 1; j < 10; ++j) //used for tiers 8-10, and all other probably
|
||||||
// }
|
{
|
||||||
} //end of stack experience
|
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
|
//experiment - add 100 to attack for creatures of tier 1
|
||||||
// Bonus *b = new Bonus(Bonus::PERMANENT, Bonus::PRIMARY_SKILL, Bonus::OTHER, +100, 0, 0);
|
// Bonus *b = new Bonus(Bonus::PERMANENT, Bonus::PRIMARY_SKILL, Bonus::OTHER, +100, 0, 0);
|
||||||
// addBonusForTier(1, b);
|
// addBonusForTier(1, b);
|
||||||
@ -743,15 +760,18 @@ void CCreatureHandler::loadUnitAnimInfo(CCreature & unit, std::string & src, int
|
|||||||
i+=2;
|
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;
|
std::string buf, mod;
|
||||||
|
bool enable = false; //some bonuses are activated with values 2 or 1
|
||||||
loadToIt(buf, src, it, 4);
|
loadToIt(buf, src, it, 4);
|
||||||
loadToIt(mod, src, it, 4);
|
loadToIt(mod, src, it, 4);
|
||||||
|
|
||||||
switch (buf[0])
|
switch (buf[0])
|
||||||
{
|
{
|
||||||
case 'H':
|
case 'H':
|
||||||
b.type = Bonus::STACK_HEALTH;
|
b.type = Bonus::STACK_HEALTH;
|
||||||
|
b.valType = Bonus::PERCENT_TO_BASE;
|
||||||
break;
|
break;
|
||||||
case 'A':
|
case 'A':
|
||||||
b.type = Bonus::PRIMARY_SKILL;
|
b.type = Bonus::PRIMARY_SKILL;
|
||||||
@ -784,7 +804,7 @@ void CCreatureHandler::loadStackExp(stackExperience & b, std::string & src, int
|
|||||||
b.type = Bonus::ADDITIONAL_RETALIATION; break;
|
b.type = Bonus::ADDITIONAL_RETALIATION; break;
|
||||||
|
|
||||||
case 'f': //on-off skill
|
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])
|
switch (mod[0])
|
||||||
{
|
{
|
||||||
case 'A':
|
case 'A':
|
||||||
@ -808,7 +828,7 @@ void CCreatureHandler::loadStackExp(stackExperience & b, std::string & src, int
|
|||||||
case 'p': //Mind spells
|
case 'p': //Mind spells
|
||||||
case 'P':
|
case 'P':
|
||||||
{
|
{
|
||||||
loadMindImmunity(b, src, it);
|
loadMindImmunity(b, bl, src, it);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -829,7 +849,7 @@ void CCreatureHandler::loadStackExp(stackExperience & b, std::string & src, int
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'w': //specific spell immunities, enabled/disabled
|
case 'w': //specific spell immunities, enabled/disabled
|
||||||
b.enable = true;
|
enable = true;
|
||||||
switch (mod[0])
|
switch (mod[0])
|
||||||
{
|
{
|
||||||
case 'B': //Blind
|
case 'B': //Blind
|
||||||
@ -877,11 +897,11 @@ void CCreatureHandler::loadStackExp(stackExperience & b, std::string & src, int
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'i':
|
case 'i':
|
||||||
b.enable = true;
|
enable = true;
|
||||||
b.type = Bonus::NO_DISTANCE_PENALTY;
|
b.type = Bonus::NO_DISTANCE_PENALTY;
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
b.enable = true;
|
enable = true;
|
||||||
b.type = Bonus::NO_OBSTACLES_PENALTY;
|
b.type = Bonus::NO_OBSTACLES_PENALTY;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -902,28 +922,51 @@ void CCreatureHandler::loadStackExp(stackExperience & b, std::string & src, int
|
|||||||
{
|
{
|
||||||
case '+':
|
case '+':
|
||||||
case '=': //should we allow percent values to stack or pick highest?
|
case '=': //should we allow percent values to stack or pick highest?
|
||||||
b.valType = Bonus::BASE_NUMBER;
|
b.valType = Bonus::ADDITIVE_VALUE;
|
||||||
break;
|
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
|
||||||
if (b.enable) //switch 2 to 0
|
for (int i = 1; i < 11; ++i)
|
||||||
{
|
|
||||||
if (b.val == 2)
|
|
||||||
b.val = 0;
|
|
||||||
for (int i = 0; i < 10; ++i)
|
|
||||||
{
|
{
|
||||||
if (b.expBonuses[i] == 2)
|
loadToIt (curVal, src, it, 4);
|
||||||
b.expBonuses[i] = 0;
|
if (curVal == 1)
|
||||||
else break; //higher levels are rarely disabled?
|
{
|
||||||
|
b.limiter.reset (new ExpRankLimiter(i));
|
||||||
|
bl.push_back(new Bonus(b));
|
||||||
|
break; //never turned off it seems
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
loadToIt (lastVal, src, it, 4); //basic value, not particularly useful but existent
|
||||||
|
for (int i = 1; i < 11; ++i)
|
||||||
|
{
|
||||||
|
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
|
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)
|
for (int g=0; g < mindSpells.size(); ++g)
|
||||||
{
|
{
|
||||||
b.subtype = mindSpells[g];
|
b.subtype = mindSpells[g];
|
||||||
cre->bonuses.push_back(new stackExperience(b));
|
cre->bonuses.push_back(new Bonus(b));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +99,8 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
class DLL_EXPORT CCreatureHandler
|
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
|
CBonusSystemNode allCreatures, creaturesOfLevel[CREATURES_PER_TOWN + 1];//index 0 is used for creatures of unknown tier or outside <1-7> range
|
||||||
public:
|
public:
|
||||||
std::set<int> notUsedMonsters;
|
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
|
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::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 loadCreatures();
|
||||||
void loadAnimationInfo();
|
void loadAnimationInfo();
|
||||||
void loadUnitAnimInfo(CCreature & unit, std::string & src, int & i);
|
void loadUnitAnimInfo(CCreature & unit, std::string & src, int & i);
|
||||||
void loadStackExp(stackExperience & b, std::string & src, int & it);
|
void loadStackExp(Bonus & b, BonusList & bl, std::string & src, int & it);
|
||||||
void loadMindImmunity(stackExperience & b, std::string & src, int & it); //multiple bonuses at once
|
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
|
int stringToNumber(std::string & s);//help function for parsing CREXPBON.txt
|
||||||
|
|
||||||
bool isGood (si8 faction) const;
|
bool isGood (si8 faction) const;
|
||||||
|
@ -430,6 +430,29 @@ int CStackInstance::getQuantityID() const
|
|||||||
return CCreature::getQuantityID(count);
|
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)
|
void CStackInstance::setType(int creID)
|
||||||
{
|
{
|
||||||
setType(VLC->creh->creatures[creID]);
|
setType(VLC->creh->creatures[creID]);
|
||||||
|
@ -49,6 +49,7 @@ public:
|
|||||||
|
|
||||||
int getQuantityID() const;
|
int getQuantityID() const;
|
||||||
std::string getQuantityTXT(bool capitalized = true) const;
|
std::string getQuantityTXT(bool capitalized = true) const;
|
||||||
|
int getExpRank() const;
|
||||||
void init();
|
void init();
|
||||||
CStackInstance();
|
CStackInstance();
|
||||||
CStackInstance(TCreature id, TQuantity count);
|
CStackInstance(TCreature id, TQuantity count);
|
||||||
|
@ -771,4 +771,14 @@ bool CreatureAlignmentLimiter::limit(const Bonus *b, const CBonusSystemNode &nod
|
|||||||
tlog1 << "Warning: illegal alignment in limiter!\n";
|
tlog1 << "Warning: illegal alignment in limiter!\n";
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpRankLimiter::ExpRankLimiter(ui8 Rank)
|
||||||
|
:rank(Rank)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
RankRangeLimiter::RankRangeLimiter(ui8 Min, ui8 Max)
|
||||||
|
:min(Min), max(Max)
|
||||||
|
{
|
||||||
}
|
}
|
@ -304,18 +304,6 @@ struct DLL_EXPORT Bonus
|
|||||||
Bonus *addLimiter(ILimiter *Limiter); //returns this for convenient chain-calls
|
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);
|
DLL_EXPORT std::ostream & operator<<(std::ostream &out, const Bonus &bonus);
|
||||||
|
|
||||||
class BonusList : public std::list<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);
|
const CCreature *retrieveCreature(const CBonusSystemNode *node);
|
||||||
|
|
||||||
namespace Selector
|
namespace Selector
|
||||||
|
Reference in New Issue
Block a user