1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +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:
Michał W. Urbańczyk 2011-02-10 13:12:53 +00:00
parent 8b8d06ac64
commit 979f77d900
7 changed files with 106 additions and 42 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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