mirror of
https://github.com/vcmi/vcmi.git
synced 2025-07-17 01:32:21 +02:00
Fixed #484. Preliminary support for bonus limiters/
This commit is contained in:
@ -48,6 +48,7 @@
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include "SDL_syswm.h"
|
#include "SDL_syswm.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
#if __MINGW32__
|
#if __MINGW32__
|
||||||
#undef main
|
#undef main
|
||||||
@ -427,6 +428,19 @@ void processCommand(const std::string &message)
|
|||||||
if(const CGHeroInstance *h = dynamic_cast<const CGHeroInstance *>(adventureInt->selection))
|
if(const CGHeroInstance *h = dynamic_cast<const CGHeroInstance *>(adventureInt->selection))
|
||||||
tlog0 << h->movement << "; max: " << h->maxMovePoints(true) << "/" << h->maxMovePoints(false) << std::endl;
|
tlog0 << h->movement << "; max: " << h->maxMovePoints(true) << "/" << h->maxMovePoints(false) << std::endl;
|
||||||
}
|
}
|
||||||
|
else if(cn == "bonuses")
|
||||||
|
{
|
||||||
|
tlog0 << "Bonuses of " << adventureInt->selection->getHoverText() << std::endl
|
||||||
|
<< adventureInt->selection->bonuses << std::endl;
|
||||||
|
|
||||||
|
tlog0 << "\nInherited bonuses:\n";
|
||||||
|
TCNodes parents;
|
||||||
|
adventureInt->selection->getParents(parents);
|
||||||
|
BOOST_FOREACH(const CBonusSystemNode *parent, parents)
|
||||||
|
{
|
||||||
|
tlog0 << "\nBonuses from " << typeid(*parent).name() << std::endl << parent->bonuses << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if(client && client->serv && client->serv->connected) //send to server
|
else if(client && client->serv && client->serv->connected) //send to server
|
||||||
{
|
{
|
||||||
PlayerMessage pm(LOCPLINT->playerID,message);
|
PlayerMessage pm(LOCPLINT->playerID,message);
|
||||||
|
@ -128,6 +128,12 @@ void CCreature::addBonus(int val, int type, int subtype /*= -1*/)
|
|||||||
bonuses.push_back(added);
|
bonuses.push_back(added);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CCreature::isMyUpgrade(const CCreature *anotherCre) const
|
||||||
|
{
|
||||||
|
//TODO upgrade of upgrade?
|
||||||
|
return vstd::contains(upgrades, anotherCre->idNumber);
|
||||||
|
}
|
||||||
|
|
||||||
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()
|
||||||
{
|
{
|
||||||
befi=i;
|
befi=i;
|
||||||
@ -337,12 +343,7 @@ void CCreatureHandler::loadCreatures()
|
|||||||
creatures.push_back(&ncre);
|
creatures.push_back(&ncre);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map types names
|
|
||||||
#define BONUS_NAME(x) ( #x, Bonus::x )
|
|
||||||
static const std::map<std::string, int> type_list = map_list_of BONUS_LIST;
|
|
||||||
#undef BONUS_NAME
|
|
||||||
|
|
||||||
////second part of reading cr_abils.txt////
|
////second part of reading cr_abils.txt////
|
||||||
bool contReading = true;
|
bool contReading = true;
|
||||||
while(contReading) //main reading loop
|
while(contReading) //main reading loop
|
||||||
@ -363,10 +364,10 @@ void CCreatureHandler::loadCreatures()
|
|||||||
reader >> creatureID;
|
reader >> creatureID;
|
||||||
reader >> type;
|
reader >> type;
|
||||||
|
|
||||||
std::map<std::string, int>::const_iterator it = type_list.find(type);
|
std::map<std::string, int>::const_iterator it = bonusNameMap.find(type);
|
||||||
CCreature *cre = creatures[creatureID];
|
CCreature *cre = creatures[creatureID];
|
||||||
|
|
||||||
if (it == type_list.end())
|
if (it == bonusNameMap.end())
|
||||||
{
|
{
|
||||||
if(type == "DOUBLE_WIDE")
|
if(type == "DOUBLE_WIDE")
|
||||||
cre->doubleWide = true;
|
cre->doubleWide = true;
|
||||||
@ -403,8 +404,8 @@ void CCreatureHandler::loadCreatures()
|
|||||||
std::string type;
|
std::string type;
|
||||||
reader >> creatureID;
|
reader >> creatureID;
|
||||||
reader >> type;
|
reader >> type;
|
||||||
std::map<std::string, int>::const_iterator it = type_list.find(type);
|
std::map<std::string, int>::const_iterator it = bonusNameMap.find(type);
|
||||||
if (it == type_list.end())
|
if (it == bonusNameMap.end())
|
||||||
{
|
{
|
||||||
if(type == "DOUBLE_WIDE")
|
if(type == "DOUBLE_WIDE")
|
||||||
creatures[creatureID]->doubleWide = false;
|
creatures[creatureID]->doubleWide = false;
|
||||||
|
@ -55,9 +55,11 @@ public:
|
|||||||
bool isEvil () const;
|
bool isEvil () const;
|
||||||
si32 maxAmount(const std::vector<si32> &res) const; //how many creatures can be bought
|
si32 maxAmount(const std::vector<si32> &res) const; //how many creatures can be bought
|
||||||
static int getQuantityID(const int & quantity); //0 - a few, 1 - several, 2 - pack, 3 - lots, 4 - horde, 5 - throng, 6 - swarm, 7 - zounds, 8 - legion
|
static int getQuantityID(const int & quantity); //0 - a few, 1 - several, 2 - pack, 3 - lots, 4 - horde, 5 - throng, 6 - swarm, 7 - zounds, 8 - legion
|
||||||
|
bool isMyUpgrade(const CCreature *anotherCre) const;
|
||||||
|
|
||||||
void addBonus(int val, int type, int subtype = -1);
|
void addBonus(int val, int type, int subtype = -1);
|
||||||
|
|
||||||
|
|
||||||
template<typename RanGen>
|
template<typename RanGen>
|
||||||
int getRandomAmount(RanGen &ranGen)
|
int getRandomAmount(RanGen &ranGen)
|
||||||
{
|
{
|
||||||
|
@ -973,50 +973,60 @@ void CGHeroInstance::initObj()
|
|||||||
{
|
{
|
||||||
case 1:// creature speciality
|
case 1:// creature speciality
|
||||||
{
|
{
|
||||||
|
speciality.growthsWithLevel = true;
|
||||||
|
|
||||||
bonus.type = Bonus::SPECIAL_CREATURE_LEV; // general info to indicate type of growing bonus
|
bonus.type = Bonus::SPECIAL_CREATURE_LEV; // general info to indicate type of growing bonus
|
||||||
bonus.additionalInfo = it->additionalinfo; //base creature ID
|
bonus.additionalInfo = it->additionalinfo; //base creature ID
|
||||||
speciality.bonuses.push_back (bonus);
|
speciality.bonuses.push_back (bonus);
|
||||||
|
|
||||||
std::vector<CCreature*>* creatures = &VLC->creh->creatures;
|
const CCreature &specCreature = *VLC->creh->creatures[it->additionalinfo]; //creature in which we have specialty
|
||||||
int creLevel = (*creatures)[it->additionalinfo]->level;
|
|
||||||
|
int creLevel = specCreature.level;
|
||||||
if(!creLevel) //TODO: set fixed level for War Machines
|
if(!creLevel) //TODO: set fixed level for War Machines
|
||||||
{
|
{
|
||||||
if(it->additionalinfo == 146)
|
if(it->additionalinfo == 146)
|
||||||
creLevel = 5; //treat ballista as 5-level
|
creLevel = 5; //treat ballista as 5-level
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tlog2 << "Warning: unknown level of " << (*creatures)[it->additionalinfo]->namePl << std::endl;
|
tlog2 << "Warning: unknown level of " << specCreature.namePl << std::endl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
speciality.growthsWithLevel = true;
|
int levelFactor = level / creLevel; //round down
|
||||||
bonus.type = Bonus::PRIMARY_SKILL; //TODO: limit to specific creature type
|
double primSkillModifier = levelFactor / 20.0;
|
||||||
|
|
||||||
|
bonus.limiter = new CCreatureTypeLimiter(specCreature);
|
||||||
|
bonus.type = Bonus::PRIMARY_SKILL;
|
||||||
bonus.valType = Bonus::ADDITIVE_VALUE;
|
bonus.valType = Bonus::ADDITIVE_VALUE;
|
||||||
bonus.subtype = 1; //attack
|
|
||||||
bonus.val = level * (*creatures)[it->additionalinfo]->attack / creLevel /20;
|
bonus.subtype = PrimarySkill::ATTACK;
|
||||||
|
bonus.val = std::ceil(primSkillModifier * specCreature.attack);
|
||||||
speciality.bonuses.push_back (bonus);
|
speciality.bonuses.push_back (bonus);
|
||||||
bonus.subtype = 2; //defense
|
|
||||||
bonus.val = level * (*creatures)[it->additionalinfo]->defence / creLevel /20;
|
bonus.subtype = PrimarySkill::DEFENSE;
|
||||||
|
bonus.val = std::ceil(primSkillModifier * specCreature.defence);
|
||||||
speciality.bonuses.push_back (bonus);
|
speciality.bonuses.push_back (bonus);
|
||||||
|
|
||||||
bonus.type = Bonus::STACKS_SPEED;
|
bonus.type = Bonus::STACKS_SPEED;
|
||||||
bonus.val = 1; //+1 speed
|
bonus.val = 1; //+1 speed
|
||||||
speciality.bonuses.push_back (bonus);
|
speciality.bonuses.push_back (bonus);
|
||||||
for (std::set<ui32>::iterator i = (*creatures)[it->additionalinfo]->upgrades.begin();
|
|
||||||
i != VLC->creh->creatures[it->additionalinfo]->upgrades.end(); i++)
|
// for (std::set<ui32>::iterator i = (*creatures)[it->additionalinfo]->upgrades.begin();
|
||||||
{
|
// i != VLC->creh->creatures[it->additionalinfo]->upgrades.end(); i++)
|
||||||
bonus.val = (*i); // for all direct upgrades of that creature
|
// {
|
||||||
bonus.type = Bonus::PRIMARY_SKILL;
|
// bonus.val = (*i); // for all direct upgrades of that creature
|
||||||
bonus.subtype = 1; //attack
|
// bonus.type = Bonus::PRIMARY_SKILL;
|
||||||
bonus.val = level * (*creatures)[*i]->attack / (*creatures)[*i]->level /20;
|
// bonus.subtype = 1; //attack
|
||||||
speciality.bonuses.push_back (bonus);
|
// bonus.val = level * (*creatures)[*i]->attack / (*creatures)[*i]->level /20;
|
||||||
bonus.subtype = 2; //defense
|
// speciality.bonuses.push_back (bonus);
|
||||||
bonus.val = level * (*creatures)[*i]->defence / (*creatures)[*i]->level /20;
|
// bonus.subtype = 2; //defense
|
||||||
speciality.bonuses.push_back (bonus);
|
// bonus.val = level * (*creatures)[*i]->defence / (*creatures)[*i]->level /20;
|
||||||
bonus.type = Bonus::STACKS_SPEED;
|
// speciality.bonuses.push_back (bonus);
|
||||||
bonus.val = 1; //+1 speed
|
// bonus.type = Bonus::STACKS_SPEED;
|
||||||
speciality.bonuses.push_back (bonus);
|
// bonus.val = 1; //+1 speed
|
||||||
}
|
// speciality.bonuses.push_back (bonus);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2://secondary skill
|
case 2://secondary skill
|
||||||
|
@ -252,6 +252,7 @@ void CStackInstance::init()
|
|||||||
type = NULL;
|
type = NULL;
|
||||||
idRand = -1;
|
idRand = -1;
|
||||||
armyObj = NULL;
|
armyObj = NULL;
|
||||||
|
nodeType = STACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CStackInstance::getQuantityID() const
|
int CStackInstance::getQuantityID() const
|
||||||
|
@ -117,11 +117,11 @@ class CObjectCaller : public IObjectCaller
|
|||||||
public:
|
public:
|
||||||
void preInit()
|
void preInit()
|
||||||
{
|
{
|
||||||
T::preInit();
|
//T::preInit();
|
||||||
}
|
}
|
||||||
void postInit()
|
void postInit()
|
||||||
{
|
{
|
||||||
T::postInit();
|
//T::postInit();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -148,14 +148,14 @@ public:
|
|||||||
|
|
||||||
void preInit()
|
void preInit()
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < apps.size(); i++)
|
// for (size_t i = 0; i < apps.size(); i++)
|
||||||
apps[i]->preInit();
|
// apps[i]->preInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void postInit()
|
void postInit()
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < apps.size(); i++)
|
// for (size_t i = 0; i < apps.size(); i++)
|
||||||
apps[i]->postInit();
|
// apps[i]->postInit();
|
||||||
}
|
}
|
||||||
} *objCaller = NULL;
|
} *objCaller = NULL;
|
||||||
|
|
||||||
@ -2365,7 +2365,7 @@ int3 CGameState::guardingCreaturePosition (int3 pos) const
|
|||||||
if (map->isInTheMap(pos))
|
if (map->isInTheMap(pos))
|
||||||
{
|
{
|
||||||
TerrainTile &tile = map->terrain[pos.x][pos.y][pos.z];
|
TerrainTile &tile = map->terrain[pos.x][pos.y][pos.z];
|
||||||
if (tile.visitable)
|
if (tile.visitable && (tile.tertype == TerrainTile::water) == (posTile.tertype == TerrainTile::water))
|
||||||
{
|
{
|
||||||
BOOST_FOREACH (CGObjectInstance* obj, tile.visitableObjects)
|
BOOST_FOREACH (CGObjectInstance* obj, tile.visitableObjects)
|
||||||
{
|
{
|
||||||
|
@ -5,10 +5,16 @@
|
|||||||
#include "../hch/CSpellHandler.h"
|
#include "../hch/CSpellHandler.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include "../hch/CCreatureHandler.h"
|
#include "../hch/CCreatureHandler.h"
|
||||||
|
#include <boost/assign/list_of.hpp>
|
||||||
|
#include "CCreatureSet.h"
|
||||||
|
|
||||||
#define FOREACH_CONST_PARENT(pname, source) TCNodes parents; getParents(parents, source); BOOST_FOREACH(const CBonusSystemNode *pname, parents)
|
#define FOREACH_CONST_PARENT(pname, source) TCNodes parents; getParents(parents, source); BOOST_FOREACH(const CBonusSystemNode *pname, parents)
|
||||||
#define FOREACH_PARENT(pname, source) TNodes parents; getParents(parents, source); BOOST_FOREACH(CBonusSystemNode *pname, parents)
|
#define FOREACH_PARENT(pname, source) TNodes parents; getParents(parents, source); BOOST_FOREACH(CBonusSystemNode *pname, parents)
|
||||||
|
|
||||||
|
#define BONUS_NAME(x) ( #x, Bonus::x )
|
||||||
|
DLL_EXPORT const std::map<std::string, int> bonusNameMap = boost::assign::map_list_of BONUS_LIST;
|
||||||
|
#undef BONUS_NAME
|
||||||
|
|
||||||
int DLL_EXPORT BonusList::totalValue() const
|
int DLL_EXPORT BonusList::totalValue() const
|
||||||
{
|
{
|
||||||
int base = 0;
|
int base = 0;
|
||||||
@ -75,6 +81,19 @@ void DLL_EXPORT BonusList::getBonuses(BonusList &out, const CSelector &selector,
|
|||||||
out.push_back(*i);
|
out.push_back(*i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BonusList::limit(const CBonusSystemNode &node)
|
||||||
|
{
|
||||||
|
for(const_iterator i = begin(); i != end(); i++)
|
||||||
|
{
|
||||||
|
if(i->limiter && i->limiter->limit(*i, node))
|
||||||
|
{
|
||||||
|
const_iterator toErase = i;
|
||||||
|
i--;
|
||||||
|
erase(toErase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int CBonusSystemNode::valOfBonuses(Bonus::BonusType type, int subtype /*= -1*/) const
|
int CBonusSystemNode::valOfBonuses(Bonus::BonusType type, int subtype /*= -1*/) const
|
||||||
{
|
{
|
||||||
CSelector s = Selector::type(type);
|
CSelector s = Selector::type(type);
|
||||||
@ -161,6 +180,9 @@ void CBonusSystemNode::getBonuses(BonusList &out, const CSelector &selector, con
|
|||||||
bonuses.getBonuses(out, selector);
|
bonuses.getBonuses(out, selector);
|
||||||
FOREACH_CONST_PARENT(p, root ? root : this)
|
FOREACH_CONST_PARENT(p, root ? root : this)
|
||||||
p->getBonuses(out, selector, root ? root : this);
|
p->getBonuses(out, selector, root ? root : this);
|
||||||
|
|
||||||
|
if(!root)
|
||||||
|
out.limit(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
BonusList CBonusSystemNode::getBonuses(const CSelector &selector, const CBonusSystemNode *root /*= NULL*/) const
|
BonusList CBonusSystemNode::getBonuses(const CSelector &selector, const CBonusSystemNode *root /*= NULL*/) const
|
||||||
@ -175,6 +197,9 @@ void CBonusSystemNode::getBonuses(BonusList &out, const CSelector &selector, con
|
|||||||
bonuses.getBonuses(out, selector, limit);
|
bonuses.getBonuses(out, selector, limit);
|
||||||
FOREACH_CONST_PARENT(p, root ? root : this)
|
FOREACH_CONST_PARENT(p, root ? root : this)
|
||||||
p->getBonuses(out, selector, limit, root ? root : this);
|
p->getBonuses(out, selector, limit, root ? root : this);
|
||||||
|
|
||||||
|
if(!root)
|
||||||
|
out.limit(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
BonusList CBonusSystemNode::getBonuses(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root /*= NULL*/) const
|
BonusList CBonusSystemNode::getBonuses(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root /*= NULL*/) const
|
||||||
@ -245,6 +270,16 @@ ui16 CBonusSystemNode::MaxHealth() const
|
|||||||
return valOfBonuses(Bonus::STACK_HEALTH);
|
return valOfBonuses(Bonus::STACK_HEALTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CBonusSystemNode::CBonusSystemNode()
|
||||||
|
{
|
||||||
|
nodeType = UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
CBonusSystemNode::~CBonusSystemNode()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int NBonus::valOf(const CBonusSystemNode *obj, Bonus::BonusType type, int subtype /*= -1*/)
|
int NBonus::valOf(const CBonusSystemNode *obj, Bonus::BonusType type, int subtype /*= -1*/)
|
||||||
{
|
{
|
||||||
if(obj)
|
if(obj)
|
||||||
@ -346,4 +381,65 @@ namespace Selector
|
|||||||
dummy.subtype = subtype;
|
dummy.subtype = subtype;
|
||||||
return sel(dummy);
|
return sel(dummy);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DLL_EXPORT std::ostream & operator<<(std::ostream &out, const BonusList &bonusList)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
BOOST_FOREACH(const Bonus &b, bonusList)
|
||||||
|
{
|
||||||
|
out << "Bonus " << i++ << "\n" << b << std::endl;
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
DLL_EXPORT std::ostream & operator<<(std::ostream &out, const Bonus &bonus)
|
||||||
|
{
|
||||||
|
for(std::map<std::string, int>::const_iterator i = bonusNameMap.begin(); i != bonusNameMap.end(); i++)
|
||||||
|
if(i->second == bonus.type)
|
||||||
|
out << "\tType: " << i->first << " \t";
|
||||||
|
|
||||||
|
#define printField(field) out << "\t" #field ": " << (int)bonus.field << "\n"
|
||||||
|
printField(val);
|
||||||
|
printField(subtype);
|
||||||
|
printField(duration);
|
||||||
|
printField(source);
|
||||||
|
printField(id);
|
||||||
|
printField(additionalInfo);
|
||||||
|
printField(turnsRemain);
|
||||||
|
printField(valType);
|
||||||
|
printField(effectRange);
|
||||||
|
#undef printField
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ILimiter::~ILimiter()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ILimiter::limit(const Bonus &b, const CBonusSystemNode &node) const /*return true to drop the bonus */
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CCreatureTypeLimiter::limit(const Bonus &b, const CBonusSystemNode &node) const
|
||||||
|
{
|
||||||
|
if(node.nodeType != CBonusSystemNode::STACK)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
const CCreature *c = (static_cast<const CStackInstance *>(&node))->type;
|
||||||
|
|
||||||
|
return c != creature && (!includeUpgrades || !creature->isMyUpgrade(c)); //drop bonus if it's not our creature and (we dont check upgrades or its not our upgrade)
|
||||||
|
}
|
||||||
|
|
||||||
|
CCreatureTypeLimiter::CCreatureTypeLimiter(const CCreature &Creature, ui8 IncludeUpgrades /*= true*/)
|
||||||
|
:creature(&Creature), includeUpgrades(IncludeUpgrades)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CCreatureTypeLimiter::CCreatureTypeLimiter()
|
||||||
|
{
|
||||||
|
creature = NULL;
|
||||||
|
includeUpgrades = false;
|
||||||
}
|
}
|
@ -19,17 +19,17 @@
|
|||||||
typedef ui8 TBonusType;
|
typedef ui8 TBonusType;
|
||||||
typedef si32 TBonusSubtype;
|
typedef si32 TBonusSubtype;
|
||||||
|
|
||||||
|
class CCreature;
|
||||||
class CSpell;
|
class CSpell;
|
||||||
struct Bonus;
|
struct Bonus;
|
||||||
class CBonusSystemNode;
|
class CBonusSystemNode;
|
||||||
|
class ILimiter;
|
||||||
|
|
||||||
typedef std::vector<std::pair<int,std::string> > TModDescr; //modifiers values and their descriptions
|
typedef std::vector<std::pair<int,std::string> > TModDescr; //modifiers values and their descriptions
|
||||||
typedef std::set<CBonusSystemNode*> TNodes;
|
typedef std::set<CBonusSystemNode*> TNodes;
|
||||||
typedef std::set<const CBonusSystemNode*> TCNodes;
|
typedef std::set<const CBonusSystemNode*> TCNodes;
|
||||||
typedef boost::function<bool(const Bonus&)> CSelector;
|
typedef boost::function<bool(const Bonus&)> CSelector;
|
||||||
|
|
||||||
|
|
||||||
namespace PrimarySkill
|
namespace PrimarySkill
|
||||||
{
|
{
|
||||||
enum { ATTACK, DEFENSE, SPELL_POWER, KNOWLEDGE};
|
enum { ATTACK, DEFENSE, SPELL_POWER, KNOWLEDGE};
|
||||||
@ -223,6 +223,8 @@ struct DLL_EXPORT Bonus
|
|||||||
si32 additionalInfo;
|
si32 additionalInfo;
|
||||||
ui8 effectRange; //if not NO_LIMIT, bonus will be ommitted by default
|
ui8 effectRange; //if not NO_LIMIT, bonus will be ommitted by default
|
||||||
|
|
||||||
|
ILimiter *limiter;
|
||||||
|
|
||||||
std::string description;
|
std::string description;
|
||||||
|
|
||||||
Bonus(ui8 Dur, ui8 Type, ui8 Src, si32 Val, ui32 ID, std::string Desc, si32 Subtype=-1)
|
Bonus(ui8 Dur, ui8 Type, ui8 Src, si32 Val, ui32 ID, std::string Desc, si32 Subtype=-1)
|
||||||
@ -232,6 +234,7 @@ struct DLL_EXPORT Bonus
|
|||||||
turnsRemain = 0;
|
turnsRemain = 0;
|
||||||
valType = ADDITIVE_VALUE;
|
valType = ADDITIVE_VALUE;
|
||||||
effectRange = NO_LIMIT;
|
effectRange = NO_LIMIT;
|
||||||
|
limiter = NULL;
|
||||||
}
|
}
|
||||||
Bonus(ui8 Dur, ui8 Type, ui8 Src, si32 Val, ui32 ID, si32 Subtype=-1, ui8 ValType = ADDITIVE_VALUE)
|
Bonus(ui8 Dur, ui8 Type, ui8 Src, si32 Val, ui32 ID, si32 Subtype=-1, ui8 ValType = ADDITIVE_VALUE)
|
||||||
:duration(Dur), type(Type), subtype(Subtype), source(Src), val(Val), id(ID), valType(ValType)
|
:duration(Dur), type(Type), subtype(Subtype), source(Src), val(Val), id(ID), valType(ValType)
|
||||||
@ -239,6 +242,7 @@ struct DLL_EXPORT Bonus
|
|||||||
additionalInfo = -1;
|
additionalInfo = -1;
|
||||||
turnsRemain = 0;
|
turnsRemain = 0;
|
||||||
effectRange = NO_LIMIT;
|
effectRange = NO_LIMIT;
|
||||||
|
limiter = NULL;
|
||||||
}
|
}
|
||||||
Bonus()
|
Bonus()
|
||||||
{
|
{
|
||||||
@ -247,6 +251,7 @@ struct DLL_EXPORT Bonus
|
|||||||
turnsRemain = 0;
|
turnsRemain = 0;
|
||||||
valType = ADDITIVE_VALUE;
|
valType = ADDITIVE_VALUE;
|
||||||
effectRange = NO_LIMIT;
|
effectRange = NO_LIMIT;
|
||||||
|
limiter = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// //comparison
|
// //comparison
|
||||||
@ -263,7 +268,7 @@ struct DLL_EXPORT Bonus
|
|||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & duration & type & subtype & source & val & id & description & additionalInfo & turnsRemain & valType & effectRange;
|
h & duration & type & subtype & source & val & id & description & additionalInfo & turnsRemain & valType & effectRange & limiter;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool OneDay(const Bonus &hb)
|
static bool OneDay(const Bonus &hb)
|
||||||
@ -307,6 +312,8 @@ struct DLL_EXPORT Bonus
|
|||||||
std::string Description() const;
|
std::string Description() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
DLL_EXPORT std::ostream & operator<<(std::ostream &out, const Bonus &bonus);
|
||||||
|
|
||||||
class BonusList : public std::list<Bonus>
|
class BonusList : public std::list<Bonus>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -319,16 +326,35 @@ public:
|
|||||||
DLL_EXPORT Bonus * getFirst(const CSelector &select);
|
DLL_EXPORT Bonus * getFirst(const CSelector &select);
|
||||||
DLL_EXPORT const Bonus * getFirst(const CSelector &select) const;
|
DLL_EXPORT const Bonus * getFirst(const CSelector &select) const;
|
||||||
|
|
||||||
|
void limit(const CBonusSystemNode &node); //erases bonuses using limitor
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & static_cast<std::list<Bonus>&>(*this);
|
h & static_cast<std::list<Bonus>&>(*this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
DLL_EXPORT std::ostream & operator<<(std::ostream &out, const BonusList &bonusList);
|
||||||
|
|
||||||
|
class DLL_EXPORT ILimiter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~ILimiter();
|
||||||
|
|
||||||
|
virtual bool limit(const Bonus &b, const CBonusSystemNode &node) const; //return true to drop the bonus
|
||||||
|
|
||||||
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
class DLL_EXPORT CBonusSystemNode
|
class DLL_EXPORT CBonusSystemNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BonusList bonuses;
|
BonusList bonuses;
|
||||||
|
ui8 nodeType;
|
||||||
|
|
||||||
|
CBonusSystemNode();
|
||||||
|
virtual ~CBonusSystemNode();
|
||||||
|
|
||||||
//new bonusing node interface
|
//new bonusing node interface
|
||||||
// * selector is predicate that tests if HeroBonus matches our criteria
|
// * selector is predicate that tests if HeroBonus matches our criteria
|
||||||
@ -366,8 +392,13 @@ public:
|
|||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & bonuses;
|
h & bonuses & nodeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum ENodeTypes
|
||||||
|
{
|
||||||
|
UNKNOWN, STACK
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace NBonus
|
namespace NBonus
|
||||||
@ -450,6 +481,23 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CCreatureTypeLimiter : public ILimiter //affect only stacks of given creature (and optionally it's upgrades)
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const CCreature *creature;
|
||||||
|
ui8 includeUpgrades;
|
||||||
|
|
||||||
|
CCreatureTypeLimiter();
|
||||||
|
CCreatureTypeLimiter(const CCreature &Creature, ui8 IncludeUpgrades = true);
|
||||||
|
|
||||||
|
bool limit(const Bonus &b, const CBonusSystemNode &node) const;
|
||||||
|
|
||||||
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
|
{
|
||||||
|
h & creature & includeUpgrades;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
namespace Selector
|
namespace Selector
|
||||||
{
|
{
|
||||||
extern DLL_EXPORT CSelectFieldEqual<TBonusType> type;
|
extern DLL_EXPORT CSelectFieldEqual<TBonusType> type;
|
||||||
@ -466,3 +514,5 @@ namespace Selector
|
|||||||
bool DLL_EXPORT matchesType(const CSelector &sel, TBonusType type);
|
bool DLL_EXPORT matchesType(const CSelector &sel, TBonusType type);
|
||||||
bool DLL_EXPORT matchesTypeSubtype(const CSelector &sel, TBonusType type, TBonusSubtype subtype);
|
bool DLL_EXPORT matchesTypeSubtype(const CSelector &sel, TBonusType type, TBonusSubtype subtype);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern DLL_EXPORT const std::map<std::string, int> bonusNameMap;
|
@ -737,9 +737,9 @@ DLL_EXPORT void HeroLevelUp::applyGs( CGameState *gs )
|
|||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
it->val = (level * (*creatures)[it->additionalInfo]->defence)/creLevel /20;
|
it->val = (level * (*creatures)[it->additionalInfo]->defence)/creLevel /20;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
template<typename Serializer> DLL_EXPORT
|
template<typename Serializer> DLL_EXPORT
|
||||||
void registerTypes1(Serializer &s)
|
void registerTypes1(Serializer &s)
|
||||||
{
|
{
|
||||||
|
//map objects
|
||||||
s.template registerType<CGHeroPlaceholder>();
|
s.template registerType<CGHeroPlaceholder>();
|
||||||
s.template registerType<CGHeroInstance>();
|
s.template registerType<CGHeroInstance>();
|
||||||
s.template registerType<CGTownInstance>();
|
s.template registerType<CGTownInstance>();
|
||||||
@ -64,6 +65,9 @@ void registerTypes1(Serializer &s)
|
|||||||
s.template registerType<CGLighthouse>();
|
s.template registerType<CGLighthouse>();
|
||||||
s.template registerType<CGMarket>();
|
s.template registerType<CGMarket>();
|
||||||
s.template registerType<CGBlackMarket>();
|
s.template registerType<CGBlackMarket>();
|
||||||
|
//end of objects
|
||||||
|
s.template registerType<ILimiter>();
|
||||||
|
s.template registerType<CCreatureTypeLimiter>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Serializer> DLL_EXPORT
|
template<typename Serializer> DLL_EXPORT
|
||||||
|
Reference in New Issue
Block a user