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, CREI_TYPE = 54,
EVENTI_TYPE = 26; EVENTI_TYPE = 26;
const int CREATURES_COUNT = 197;
const int CRE_LEVELS = 10; const int CRE_LEVELS = 10;
const int F_NUMBER = 9; //factions (town types) quantity const int F_NUMBER = 9; //factions (town types) quantity
const int PLAYER_LIMIT = 8; //player limit per map 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; 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> template <typename T>
void delNull(T* &ptr) //deleted pointer and sets it to NULL void delNull(T* &ptr) //deleted pointer and sets it to NULL
{ {

View File

@ -13,6 +13,7 @@
#include "../lib/VCMI_Lib.h" #include "../lib/VCMI_Lib.h"
#include "../lib/CGameState.h" #include "../lib/CGameState.h"
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>
using namespace boost::assign; using namespace boost::assign;
extern CLodHandler * bitmaph; extern CLodHandler * bitmaph;
@ -47,6 +48,11 @@ CCreatureHandler::CCreatureHandler()
// Neutral: Stronghold, Fortess, Conflux // Neutral: Stronghold, Fortess, Conflux
factionAlignments += 1, 1, 1, -1, -1, -1, 0, 0, 0; 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 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) int CCreature::getQuantityID(const int & quantity)
@ -147,7 +153,7 @@ bool CCreature::valid() const
std::string CCreature::nodeName() 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() 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.close();
ifs.clear(); ifs.clear();
for(i = 1; i <= CRE_LEVELS; i++)
levelCreatures[i];
tlog5 << "\t\tReading config/monsters.txt" << std::endl; tlog5 << "\t\tReading config/monsters.txt" << std::endl;
ifs.open(DATA_DIR "/config/monsters.txt"); ifs.open(DATA_DIR "/config/monsters.txt");
@ -479,13 +483,19 @@ void CCreatureHandler::loadCreatures()
{ {
int id, lvl; int id, lvl;
ifs >> id >> lvl; ifs >> id >> lvl;
if(lvl>0) if(!ifs.good())
{ break;
creatures[id]->level = lvl; CCreature *c = creatures[id];
levelCreatures[lvl].push_back(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.close();
ifs.clear(); ifs.clear();
@ -657,6 +667,10 @@ void CCreatureHandler::loadCreatures()
// std::copy(commonBonuses[7].begin(), commonBonuses[7].end(), c->bonuses.begin()); //common for tiers 8+ // std::copy(commonBonuses[7].begin(), commonBonuses[7].end(), c->bonuses.begin()); //common for tiers 8+
// } // }
} //end of stack experience } //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() 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; int r = 0;
do if(tier == -1) //pick any allowed creature
{ {
if(randGen) do
r = randGen(); {
else pickRandomElementOf(creatures, randGen);
r = rand(); //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; allowed.push_back(creid);
} while (vstd::contains(VLC->creh->notUsedMonsters,r)); }
if(!allowed.size())
{
tlog2 << "Cannot pick a random creature of tier " << tier << "!\n";
return 0;
}
return pickRandomElementOf(allowed, randGen);
}
return r; 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; friend class CCreatureHandler;
}; };
class DLL_EXPORT 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: public:
CBonusSystemNode *globalEffects;
std::set<int> notUsedMonsters; std::set<int> notUsedMonsters;
std::set<TCreature> doubledCreatures; //they get double week std::set<TCreature> doubledCreatures; //they get double week
std::vector<ConstTransitivePtr<CCreature> > creatures; //creature ID -> creature info 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<std::string,int> nameToID;
bmap<int,std::string> idToProjectile; bmap<int,std::string> idToProjectile;
bmap<int,bool> idToProjectileSpin; //if true, appropriate projectile is spinning during flight bmap<int,bool> idToProjectileSpin; //if true, appropriate projectile is spinning during flight
@ -126,8 +124,9 @@ public:
bool isGood (si8 faction) const; bool isGood (si8 faction) const;
bool isEvil (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();
~CCreatureHandler(); ~CCreatureHandler();
@ -136,7 +135,8 @@ public:
{ {
//TODO: should be optimized, not all these informations needs to be serialized (same for ccreature) //TODO: should be optimized, not all these informations needs to be serialized (same for ccreature)
h & notUsedMonsters & creatures & nameToID & idToProjectile & idToProjectileSpin & factionToTurretCreature; 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::string CStackInstance::nodeName() const
{ {
std::ostringstream oss; std::ostringstream oss;
oss << "Stack of " << count << " creatures of "; oss << "Stack of " << count << " of ";
if(type) if(type)
oss << type->namePl; oss << type->namePl;
else if(idRand) else if(idRand)

View File

@ -523,21 +523,17 @@ std::pair<int,int> CGameState::pickObject (CGObjectInstance *obj)
case 69: //random relic artifact case 69: //random relic artifact
return std::pair<int,int>(5, VLC->arth->getRandomArt (CArtifact::ART_RELIC)); return std::pair<int,int>(5, VLC->arth->getRandomArt (CArtifact::ART_RELIC));
case 70: //random hero 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 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 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 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 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 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 case 76: //random resource
return std::pair<int,int>(79,ran()%7); //now it's OH3 style, use %8 for mithril return std::pair<int,int>(79,ran()%7); //now it's OH3 style, use %8 for mithril
case 77: //random town case 77: //random town
@ -559,11 +555,11 @@ std::pair<int,int> CGameState::pickObject (CGObjectInstance *obj)
return std::pair<int,int>(TOWNI_TYPE,f); return std::pair<int,int>(TOWNI_TYPE,f);
} }
case 162: //random monster lvl5 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 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 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 case 216: //random dwelling
{ {
int faction = ran()%F_NUMBER; int faction = ran()%F_NUMBER;
@ -762,6 +758,7 @@ CGameState::CGameState()
applierGs = new CApplier<CBaseForGSApply>; applierGs = new CApplier<CBaseForGSApply>;
registerTypes2(*applierGs); registerTypes2(*applierGs);
objCaller = new CObjectCallersHandler; objCaller = new CObjectCallersHandler;
globalEffects.description = "Global effects";
} }
CGameState::~CGameState() CGameState::~CGameState()
{ {
@ -871,7 +868,6 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
seed = Seed; seed = Seed;
ran.seed((boost::int32_t)seed); ran.seed((boost::int32_t)seed);
VLC->creh->globalEffects = &globalEffects;
scenarioOps = new StartInfo(*si); scenarioOps = new StartInfo(*si);
initialOpts = new StartInfo(*si); initialOpts = new StartInfo(*si);
si = NULL; si = NULL;

View File

@ -439,7 +439,9 @@ bool CBonusSystemNode::isIndependentNode() const
std::string CBonusSystemNode::nodeName() 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() void CBonusSystemNode::deserializationFix()

View File

@ -362,13 +362,14 @@ public:
class DLL_EXPORT CBonusSystemNode class DLL_EXPORT CBonusSystemNode
{ {
public: public:
BonusList bonuses; //wielded bonuses (local and up-propagated here) BonusList bonuses; //wielded bonuses (local or up-propagated here)
BonusList exportedBonuses; 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 TNodesVector parents; //parents -> we inherit bonuses from them, we may attach our bonuses to them
children; TNodesVector children;
ui8 nodeType; ui8 nodeType;
std::string description;
CBonusSystemNode(); CBonusSystemNode();
virtual ~CBonusSystemNode(); virtual ~CBonusSystemNode();
@ -438,6 +439,7 @@ public:
{ {
h & bonuses & nodeType; h & bonuses & nodeType;
h & exportedBonuses; h & exportedBonuses;
h & description;
//h & parents & children; //h & parents & children;
} }