1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-25 21:38:59 +02:00

Statue of Legion is finally functional.

You can see my attempt to create very generic handling of global effects, but I abandoned it since no other items might actually use it.

However, Statue's constituents are buggy, so may be assembling & dissasembling them. Most likely this issue is general.
This commit is contained in:
DjWarmonger 2010-09-25 20:23:55 +00:00
parent b1636fd920
commit 717141ab0b
7 changed files with 67 additions and 23 deletions

View File

@ -1138,7 +1138,8 @@ void CCastleInterface::CCreaInfo::clickRight(tribool down, bool previousState)
if(down)
{
CCastleInterface * ci=LOCPLINT->castleInt;
std::set<si32> bld =ci->town->builtBuildings;
const CGTownInstance * town = ci->town;
std::set<si32> bld = ci->town->builtBuildings;
int summ=0, cnt=0;
std::string descr=CGI->generaltexth->allTexts[589];//Growth of creature is number
boost::algorithm::replace_first(descr,"%s",CGI->creh->creatures[crid]->nameSing);
@ -1156,9 +1157,12 @@ void CCastleInterface::CCreaInfo::clickRight(tribool down, bool previousState)
else if ( bld.find(8)!=bld.end())//else if citadel+50% to basic
summ+=AddToString(CGI->buildh->buildings[ci->town->subID][8]->Name()+" %+d",descr,summ/2);
summ+=AddToString(CGI->generaltexth->allTexts[63] + " %+d",descr,
summ+=AddToString(CGI->generaltexth->allTexts[63] + " %+d",descr, //plague
summ * CGI->creh->creatures[crid]->valOfBonuses(Bonus::CREATURE_GROWTH_PERCENT)/100);
summ+=AddToString(CGI->generaltexth->artifNames[133] + " %+d",descr,
summ * ci->town->valOfGlobalBonuses(Bonus::CREATURE_GROWTH_PERCENT, -1)/100); //Statue of Legion
if(ci->town->town->hordeLvl[0]==level)//horde, x to summ
if((bld.find(18)!=bld.end()) || (bld.find(19)!=bld.end()))
summ+=AddToString(CGI->buildh->buildings[ci->town->subID][18]->Name()+" %+d",descr,

View File

@ -673,7 +673,7 @@ void CArtHandler::addBonuses()
giveArtBonus(132, Bonus::OPENING_BATTLE_SPELL, 50, 52); // Misfortune
// Statue of Legion - gives only 50% growth
giveArtBonus(133, Bonus::CREATURE_GROWTH_PERCENT, 50);
giveArtBonus(133, Bonus::CREATURE_GROWTH_PERCENT, 50, -1);
//Power of the Dragon Father
giveArtBonus(134, Bonus::LEVEL_SPELL_IMMUNITY, 4);

View File

@ -1493,11 +1493,12 @@ int CGHeroInstance::getSpellCost(const CSpell *sp) const
void CGHeroInstance::getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const
{
CArmedInstance::getParents(out, root);// if(visitedTown && source != this && source != visitedTown)
// out.insert(visitedTown);
CArmedInstance::getParents(out, root);
if((root == this || contains(static_cast<const CStackInstance *>(root))) && visitedTown)
out.insert(visitedTown);
{
out.insert(visitedTown);
}
for (std::map<ui16,ui32>::const_iterator i = artifWorn.begin(); i != artifWorn.end(); i++)
out.insert(VLC->arth->artifacts[i->second]);
@ -1513,7 +1514,8 @@ void CGHeroInstance::pushPrimSkill(int which, int val)
void CGHeroInstance::getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root /*= NULL*/) const
{
#define FOREACH_OWNER_TOWN(town) if(const PlayerState *p = cb->getPlayerState(tempOwner)) BOOST_FOREACH(const CGTownInstance *town, p->towns)
CArmedInstance::getBonuses(out, selector, root);
CArmedInstance::getBonuses(out, selector, root); ///that's not part of macro!
//TODO eliminate by moving secondary skills effects to bonus system
if(Selector::matchesType(selector, Bonus::LUCK))
@ -6538,10 +6540,10 @@ void CArmedInstance::randomizeArmy(int type)
void CArmedInstance::getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const
{
const PlayerState *p = cb->getPlayerState(tempOwner);
if(p)
if (p && p != root)
out.insert(p); //hero always inherits bonuses from player
out.insert(&cb->gameState()->globalEffects); //global effect are always active I believe
out.insert(&cb->gameState()->globalEffects); //global effects are always active I believe
if(battle)
out.insert(battle);
@ -6606,6 +6608,12 @@ void CArmedInstance::getBonuses(BonusList &out, const CSelector &selector, const
}
}
int CArmedInstance::valOfGlobalBonuses(Bonus::BonusType type, int subtype) const
{
//if (tempOwner != NEUTRAL_PLAYER)
return cb->gameState()->players[tempOwner].valOfBonuses(type, subtype);
}
bool IMarket::getOffer(int id1, int id2, int &val1, int &val2, EMarketMode mode) const
{
switch(mode)

View File

@ -228,6 +228,7 @@ public:
//////////////////////////////////////////////////////////////////////////
void getParents(TCNodes &out, const CBonusSystemNode *root = NULL) const;
void getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root = NULL) const;
int valOfGlobalBonuses(Bonus::BonusType type, int subtype) const; //used only for castle interface
//////////////////////////////////////////////////////////////////////////
CArmedInstance();

View File

@ -4479,24 +4479,34 @@ PlayerState::PlayerState()
void PlayerState::getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const
{
/*
for (std::vector<CGHeroInstance *>::const_iterator it = heroes.begin(); it != heroes.end(); ++it)
//an issue - this way we get quadratic complexity at the moment all objects are called
for (std::vector<CGHeroInstance *>::const_iterator it = heroes.begin(); it != heroes.end(); it++)
{
if (*it != root)
(*it)->getParents(out, root);
out.insert(*it);
}
for (std::vector<CGTownInstance *>::const_iterator it = towns.begin(); it != towns.end(); ++it)
/*
for (std::vector<CGTownInstance *>::const_iterator it = towns.begin(); it != towns.end(); it++)
{
if (*it != root)
(*it)->getParents(out, root);
out.insert(*it);
}
*/
//TODO - dwellings
if (root != this)
{
out.erase(out.find(root)); //don't use yourself
root = this; //get all nodes ONLY once - see Armed Instance::getParents
}
}
void PlayerState::getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root /*= NULL*/) const
{
CBonusSystemNode::getBonuses(out, selector, root);
if (Selector::matchesType(selector, Bonus::CREATURE_GROWTH_PERCENT))
CBonusSystemNode::getBonuses(out, selector, this); //no recursive loops for PlayerState
/* //universal solution
if (root == this) // called directly
CBonusSystemNode::getBonuses(out, selector, this); //no recursive loops for PlayerState
else //unused yet
CBonusSystemNode::getBonuses(out, selector && Selector::effectRange(Bonus::GLOBAL), root); //only very specific bonuses can be propagated this way
*/
}
InfoAboutHero::InfoAboutHero()

View File

@ -223,9 +223,13 @@ void CBonusSystemNode::getParents(TNodes &out, const CBonusSystemNode *root /*=
void CBonusSystemNode::getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root /*= NULL*/) const
{
bonuses.getBonuses(out, selector);
FOREACH_CONST_PARENT(p, root ? root : this)
//FOREACH_CONST_PARENT(p, root ? root : this) //unwinded macro
TCNodes parents;
getParents(parents, root ? root : this);
BOOST_FOREACH(const CBonusSystemNode *p, parents)
p->getBonuses(out, selector, root ? root : this);
bonuses.getBonuses(out, selector);
if(!root)
out.limit(*this);
@ -240,10 +244,14 @@ BonusList CBonusSystemNode::getBonuses(const CSelector &selector, const CBonusSy
void CBonusSystemNode::getBonuses(BonusList &out, const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root /*= NULL*/) const
{
bonuses.getBonuses(out, selector, limit);
FOREACH_CONST_PARENT(p, root ? root : this)
//FOREACH_CONST_PARENT(p, root ? root : this) //unwinded macro
TCNodes parents;
getParents(parents, root ? root : this);
BOOST_FOREACH(const CBonusSystemNode *p, parents)
p->getBonuses(out, selector, limit, root ? root : this);
bonuses.getBonuses(out, selector, limit);
if(!root)
out.limit(*this);
}

View File

@ -201,7 +201,8 @@ struct DLL_EXPORT Bonus
NO_LIMIT = 0,
ONLY_DISTANCE_FIGHT=1, ONLY_MELEE_FIGHT, //used to mark bonuses for attack/defense primary skills from spells like Precision (distance only)
ONLY_ALLIED_ARMY, ONLY_ENEMY_ARMY,
PLAYR_HEROES
PLAYR_HEROES,
GLOBAL //Statue of Legion etc.
};
enum ValueType
@ -293,6 +294,18 @@ struct DLL_EXPORT Bonus
std::string Description() const;
};
struct DLL_EXPORT stackExperience : public Bonus
{
std::vector<ui32> 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>