mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Visual Studio 2013 Preview compile fixes:
* 0 is not convertible to std::function, nullptr should be used * std::ref(rand) is not convertible to function<int()>, used lambdas (why we dont just pass "rand" ? ) * CFunctionList needs to be constructible from nullptr * move constructor for CMapInfo (Visual cannot generate them :( ) * #ifdefed some stuff that is not needed anymore since cmath is updated with C99 stuff * using std::make_unique instead of our vstd implementation CSelector: * introduced a class in place of typedef * Having an overloaded && || operators over sth that is convertible to bool… Wasn't a good idea after all. Purged the operators, replaced with And/Or methods (chaining-style). * constructor that is present only when constructing from class or function (SFINAE). std::function has an implicit converting constructor from T causing ambiguities (even if the overload would cause compile error in the body)
This commit is contained in:
parent
f82122d9be
commit
4576719abe
@ -627,7 +627,7 @@ AttackPossibility AttackPossibility::evaluate(const BattleAttackInfo &AttackInfo
|
||||
|
||||
const int remainingCounterAttacks = getValOr(state.counterAttacksLeft, enemy, enemy->counterAttacks);
|
||||
const bool counterAttacksBlocked = attacker->hasBonusOfType(Bonus::BLOCKS_RETALIATION) || enemy->hasBonusOfType(Bonus::NO_RETALIATION);
|
||||
const int totalAttacks = 1 + AttackInfo.attackerBonuses->getBonuses(Selector::type(Bonus::ADDITIONAL_ATTACK), (Selector::effectRange (Bonus::NO_LIMIT) || Selector::effectRange(Bonus::ONLY_MELEE_FIGHT)))->totalValue();
|
||||
const int totalAttacks = 1 + AttackInfo.attackerBonuses->getBonuses(Selector::type(Bonus::ADDITIONAL_ATTACK), (Selector::effectRange (Bonus::NO_LIMIT).Or(Selector::effectRange(Bonus::ONLY_MELEE_FIGHT))))->totalValue();
|
||||
|
||||
AttackPossibility ap = {enemy, hex, AttackInfo, 0, 0, 0};
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
#ifndef FL_DEFS_H
|
||||
#define FL_DEFS_H
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if _MSC_VER < 1800
|
||||
#ifndef NAN
|
||||
static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff};
|
||||
#define NAN (*(const float *) __nan)
|
||||
|
4
Global.h
4
Global.h
@ -441,6 +441,9 @@ namespace vstd
|
||||
ptr = nullptr;
|
||||
}
|
||||
|
||||
#if _MSC_VER >= 1800
|
||||
using std::make_unique;
|
||||
#else
|
||||
template<typename T>
|
||||
std::unique_ptr<T> make_unique()
|
||||
{
|
||||
@ -466,6 +469,7 @@ namespace vstd
|
||||
{
|
||||
return std::unique_ptr<T>(new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2), std::forward<Arg3>(arg3), std::forward<Arg4>(arg4)));
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename Container>
|
||||
typename Container::const_reference circularAt(const Container &r, size_t index)
|
||||
|
@ -106,7 +106,7 @@ CCreatureWindow::CCreatureWindow(const CStackInstance &st, CreWinType Type, std:
|
||||
fs += Upg;
|
||||
fs += std::bind(&CCreatureWindow::close,this);
|
||||
CFunctionList<void()> cfl;
|
||||
cfl = std::bind(&CPlayerInterface::showYesNoDialog, LOCPLINT, CGI->generaltexth->allTexts[207], fs, 0, false, std::ref(upgResCost));
|
||||
cfl = std::bind(&CPlayerInterface::showYesNoDialog, LOCPLINT, CGI->generaltexth->allTexts[207], fs, nullptr, false, std::ref(upgResCost));
|
||||
upgrade = new CAdventureMapButton("",CGI->generaltexth->zelp[446].second,cfl,385, 148,"IVIEWCR.DEF",SDLK_u);
|
||||
}
|
||||
else
|
||||
@ -248,7 +248,7 @@ void CCreatureWindow::init(const CStackInstance *Stack, const CBonusSystemNode *
|
||||
}
|
||||
|
||||
BonusList bl, blTemp;
|
||||
blTemp = (*(stackNode->getBonuses(Selector::durationType(Bonus::PERMANENT) && Selector::anyRange())));
|
||||
blTemp = (*(stackNode->getBonuses(Selector::durationType(Bonus::PERMANENT).And(Selector::anyRange()))));
|
||||
|
||||
while (blTemp.size())
|
||||
{
|
||||
|
@ -146,7 +146,7 @@ public:
|
||||
|
||||
CAdventureMapButton * dismiss, * upgrade, * ok;
|
||||
|
||||
CCreInfoWindow(const CStackInstance & st, bool LClicked, std::function<void()> Upg = 0, std::function<void()> Dsm = 0, UpgradeInfo * ui = nullptr);
|
||||
CCreInfoWindow(const CStackInstance & st, bool LClicked, std::function<void()> Upg = nullptr, std::function<void()> Dsm = nullptr, UpgradeInfo * ui = nullptr);
|
||||
CCreInfoWindow(const CStack & st, bool LClicked = 0);
|
||||
CCreInfoWindow(int Cid, bool LClicked, int creatureCount);
|
||||
~CCreInfoWindow();
|
||||
@ -159,4 +159,4 @@ public:
|
||||
|
||||
CIntObject *createCreWindow(const CStack *s, bool lclick = false);
|
||||
CIntObject *createCreWindow(CreatureID Cid, CCreatureWindow::CreWinType Type, int creatureCount);
|
||||
CIntObject *createCreWindow(const CStackInstance *s, CCreatureWindow::CreWinType type, std::function<void()> Upg = 0, std::function<void()> Dsm = 0, UpgradeInfo *ui = nullptr);
|
||||
CIntObject *createCreWindow(const CStackInstance *s, CCreatureWindow::CreWinType type, std::function<void()> Upg = nullptr, std::function<void()> Dsm = nullptr, UpgradeInfo *ui = nullptr);
|
||||
|
@ -33,6 +33,8 @@ public:
|
||||
{
|
||||
funcs.push_back(first);
|
||||
}
|
||||
CFunctionList(std::nullptr_t)
|
||||
{}
|
||||
CFunctionList & operator+=(const boost::function<Signature> &first)
|
||||
{
|
||||
funcs.push_back(first);
|
||||
|
@ -321,8 +321,8 @@ void CGarrisonSlot::clickLeft(tribool down, bool previousState)
|
||||
bool canDismiss = getObj()->tempOwner == LOCPLINT->playerID && (getObj()->stacksCount()>1 || !getObj()->needsLastStack());
|
||||
std::function<void()> upgr = nullptr;
|
||||
std::function<void()> dism = nullptr;
|
||||
if (canUpgrade) upgr = std::bind(&CCallback::upgradeCreature, LOCPLINT->cb.get(), getObj(), ID, pom.newID[0]);
|
||||
if (canDismiss) dism = std::bind(&CCallback::dismissCreature, LOCPLINT->cb.get(), getObj(), ID);
|
||||
if(canUpgrade) upgr = [=] { LOCPLINT->cb->upgradeCreature(getObj(), ID, pom.newID[0]); };
|
||||
if(canDismiss) dism = [=] { LOCPLINT->cb->dismissCreature(getObj(), ID); };
|
||||
|
||||
owner->selectSlot(nullptr);
|
||||
owner->setSplittingMode(false);
|
||||
|
@ -233,8 +233,8 @@ public:
|
||||
void select(bool on);
|
||||
|
||||
void clickLeft(tribool down, bool previousState); //call-in
|
||||
CSelectableComponent(Etype Type, int Sub, int Val, ESize imageSize=large, std::function<void()> OnSelect = 0); //c-tor
|
||||
CSelectableComponent(const Component &c, std::function<void()> OnSelect = 0); //c-tor
|
||||
CSelectableComponent(Etype Type, int Sub, int Val, ESize imageSize=large, std::function<void()> OnSelect = nullptr); //c-tor
|
||||
CSelectableComponent(const Component &c, std::function<void()> OnSelect = nullptr); //c-tor
|
||||
};
|
||||
|
||||
/// box with multiple components (up to 8?)
|
||||
@ -269,7 +269,7 @@ public:
|
||||
/// constructor for selectable components
|
||||
/// will also create "or" labels between components
|
||||
/// onSelect - optional function that will be called every time on selection change
|
||||
CComponentBox(std::vector<CSelectableComponent *> components, Rect position, std::function<void(int newID)> onSelect = 0);
|
||||
CComponentBox(std::vector<CSelectableComponent *> components, Rect position, std::function<void(int newID)> onSelect = nullptr);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -890,10 +890,10 @@ void CStack::postInit()
|
||||
|
||||
ui32 CStack::Speed( int turn /*= 0*/ , bool useBind /* = false*/) const
|
||||
{
|
||||
if(hasBonus(Selector::type(Bonus::SIEGE_WEAPON) && Selector::turns(turn))) //war machines cannot move
|
||||
if(hasBonus(Selector::type(Bonus::SIEGE_WEAPON).And(Selector::turns(turn)))) //war machines cannot move
|
||||
return 0;
|
||||
|
||||
int speed = valOfBonuses(Selector::type(Bonus::STACKS_SPEED) && Selector::turns(turn));
|
||||
int speed = valOfBonuses(Selector::type(Bonus::STACKS_SPEED).And(Selector::turns(turn)));
|
||||
|
||||
int percentBonus = 0;
|
||||
for(const Bonus *b : getBonusList())
|
||||
@ -970,7 +970,7 @@ bool CStack::willMove(int turn /*= 0*/) const
|
||||
bool CStack::canMove( int turn /*= 0*/ ) const
|
||||
{
|
||||
return alive()
|
||||
&& !hasBonus(Selector::type(Bonus::NOT_ACTIVE) && Selector::turns(turn)); //eg. Ammo Cart or blinded creature
|
||||
&& !hasBonus(Selector::type(Bonus::NOT_ACTIVE).And(Selector::turns(turn))); //eg. Ammo Cart or blinded creature
|
||||
}
|
||||
|
||||
bool CStack::moved( int turn /*= 0*/ ) const
|
||||
|
@ -780,8 +780,13 @@ TDmgRange CBattleInfoCallback::calculateDmgRange(const BattleAttackInfo &info) c
|
||||
{
|
||||
auto battleBonusValue = [&](const IBonusBearer * bearer, CSelector selector) -> int
|
||||
{
|
||||
return bearer->getBonuses(selector, Selector::effectRange(Bonus::NO_LIMIT) || //any regular bonuses or just ones for melee/ranged
|
||||
(info.shooting ? Selector::effectRange(Bonus::ONLY_DISTANCE_FIGHT) : Selector::effectRange(Bonus::ONLY_MELEE_FIGHT)))->totalValue();
|
||||
auto noLimit = Selector::effectRange(Bonus::NO_LIMIT);
|
||||
auto limitMatches = info.shooting
|
||||
? Selector::effectRange(Bonus::ONLY_DISTANCE_FIGHT)
|
||||
: Selector::effectRange(Bonus::ONLY_MELEE_FIGHT);
|
||||
|
||||
//any regular bonuses or just ones for melee/ranged
|
||||
return bearer->getBonuses(selector, noLimit.Or(limitMatches))->totalValue();
|
||||
};
|
||||
|
||||
double additiveBonus = 1.0, multBonus = 1.0,
|
||||
@ -800,7 +805,7 @@ TDmgRange CBattleInfoCallback::calculateDmgRange(const BattleAttackInfo &info) c
|
||||
{ //minDmg and maxDmg are multiplied by hero attack + 1
|
||||
auto retreiveHeroPrimSkill = [&](int skill) -> int
|
||||
{
|
||||
const Bonus *b = info.attackerBonuses->getBonus(Selector::sourceTypeSel(Bonus::HERO_BASE_SKILL) && Selector::typeSubtype(Bonus::PRIMARY_SKILL, skill));
|
||||
const Bonus *b = info.attackerBonuses->getBonus(Selector::sourceTypeSel(Bonus::HERO_BASE_SKILL).And(Selector::typeSubtype(Bonus::PRIMARY_SKILL, skill)));
|
||||
return b ? b->val : 0; //if there is no hero or no info on his primary skill, return 0
|
||||
};
|
||||
|
||||
@ -2103,8 +2108,11 @@ SpellID CBattleInfoCallback::getRandomBeneficialSpell(const CStack * subject) co
|
||||
{
|
||||
auto kingMonster = getStackIf([&](const CStack *stack) //look for enemy, non-shooting stack
|
||||
{
|
||||
return stack->owner != subject->owner
|
||||
&& (stack->hasBonus(Selector::type(Bonus::KING1) || Selector::type(Bonus::KING2) || Selector::type(Bonus::KING3)));
|
||||
const auto isKing = Selector::type(Bonus::KING1)
|
||||
.Or(Selector::type(Bonus::KING2))
|
||||
.Or(Selector::type(Bonus::KING3));
|
||||
|
||||
return stack->owner != subject->owner && stack->hasBonus(isKing);
|
||||
});
|
||||
|
||||
if (!kingMonster)
|
||||
|
@ -184,7 +184,7 @@ public:
|
||||
std::vector <std::pair <Bonus*, std::pair <ui8, ui8> > > skillRequirements; // first - Bonus, second - which two skills are needed to use it
|
||||
|
||||
void deserializationFix();
|
||||
CreatureID pickRandomMonster(const std::function<int()> &randGen = 0, int tier = -1) const; //tier <1 - CREATURES_PER_TOWN> or -1 for any
|
||||
CreatureID pickRandomMonster(const std::function<int()> &randGen = nullptr, 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);
|
||||
|
||||
|
@ -1250,7 +1250,7 @@ void CGHeroInstance::updateSkill(SecondarySkill which, int val)
|
||||
bool luck = which == SecondarySkill::LUCK;
|
||||
Bonus::BonusType type[] = {Bonus::MORALE, Bonus::LUCK};
|
||||
|
||||
Bonus *b = getBonusLocalFirst(Selector::type(type[luck]) && Selector::sourceType(Bonus::SECONDARY_SKILL));
|
||||
Bonus *b = getBonusLocalFirst(Selector::type(type[luck]).And(Selector::sourceType(Bonus::SECONDARY_SKILL)));
|
||||
if(!b)
|
||||
{
|
||||
b = new Bonus(Bonus::PERMANENT, type[luck], Bonus::SECONDARY_SKILL, +val, which, which, Bonus::BASE_NUMBER);
|
||||
@ -1262,7 +1262,7 @@ void CGHeroInstance::updateSkill(SecondarySkill which, int val)
|
||||
else if(which == SecondarySkill::DIPLOMACY) //surrender discount: 20% per level
|
||||
{
|
||||
|
||||
if(Bonus *b = getBonusLocalFirst(Selector::type(Bonus::SURRENDER_DISCOUNT) && Selector::sourceType(Bonus::SECONDARY_SKILL)))
|
||||
if(Bonus *b = getBonusLocalFirst(Selector::type(Bonus::SURRENDER_DISCOUNT).And(Selector::sourceType(Bonus::SECONDARY_SKILL))))
|
||||
b->val = +val;
|
||||
else
|
||||
addNewBonus(new Bonus(Bonus::PERMANENT, Bonus::SURRENDER_DISCOUNT, Bonus::SECONDARY_SKILL, val * 20, which));
|
||||
@ -1312,7 +1312,8 @@ void CGHeroInstance::updateSkill(SecondarySkill which, int val)
|
||||
|
||||
|
||||
Bonus::ValueType skillValType = skillVal ? Bonus::BASE_NUMBER : Bonus::INDEPENDENT_MIN;
|
||||
if(Bonus * b = getBonusList().getFirst(Selector::typeSubtype(Bonus::SECONDARY_SKILL_PREMY, which) && Selector::sourceType(Bonus::SECONDARY_SKILL))) //only local hero bonus
|
||||
if(Bonus * b = getBonusList().getFirst(Selector::typeSubtype(Bonus::SECONDARY_SKILL_PREMY, which)
|
||||
.And(Selector::sourceType(Bonus::SECONDARY_SKILL)))) //only local hero bonus
|
||||
{
|
||||
b->val = skillVal;
|
||||
b->valType = skillValType;
|
||||
@ -2090,7 +2091,7 @@ GrowthInfo CGTownInstance::getGrowthInfo(int level) const
|
||||
ret.entries.push_back(GrowthInfo::Entry(VLC->generaltexth->allTexts[591], dwellingBonus));// \nExternal dwellings %+d
|
||||
|
||||
//other *-of-legion-like bonuses (%d to growth cumulative with grail)
|
||||
TBonusListPtr bonuses = getBonuses(Selector::type(Bonus::CREATURE_GROWTH) && Selector::subtype(level));
|
||||
TBonusListPtr bonuses = getBonuses(Selector::type(Bonus::CREATURE_GROWTH).And(Selector::subtype(level)));
|
||||
for(const Bonus *b : *bonuses)
|
||||
ret.entries.push_back(GrowthInfo::Entry(b->Description() + " %+d", b->val));
|
||||
|
||||
@ -2465,7 +2466,7 @@ void CGTownInstance::deserializationFix()
|
||||
|
||||
void CGTownInstance::updateMoraleBonusFromArmy()
|
||||
{
|
||||
Bonus *b = getBonusList().getFirst(Selector::sourceType(Bonus::ARMY) && Selector::type(Bonus::MORALE));
|
||||
Bonus *b = getBonusList().getFirst(Selector::sourceType(Bonus::ARMY).And(Selector::type(Bonus::MORALE)));
|
||||
if(!b)
|
||||
{
|
||||
b = new Bonus(Bonus::PERMANENT, Bonus::MORALE, Bonus::ARMY, 0, -1);
|
||||
@ -7063,7 +7064,7 @@ void CArmedInstance::updateMoraleBonusFromArmy()
|
||||
if(!validTypes(false)) //object not randomized, don't bother
|
||||
return;
|
||||
|
||||
Bonus *b = getBonusList().getFirst(Selector::sourceType(Bonus::ARMY) && Selector::type(Bonus::MORALE));
|
||||
Bonus *b = getBonusList().getFirst(Selector::sourceType(Bonus::ARMY).And(Selector::type(Bonus::MORALE)));
|
||||
if(!b)
|
||||
{
|
||||
b = new Bonus(Bonus::PERMANENT, Bonus::MORALE, Bonus::ARMY, 0, -1);
|
||||
|
@ -311,7 +311,7 @@ void BonusList::insert(std::vector<Bonus*>::iterator position, std::vector<Bonus
|
||||
|
||||
int IBonusBearer::valOfBonuses(Bonus::BonusType type, const CSelector &selector) const
|
||||
{
|
||||
return valOfBonuses(Selector::type(type) && selector);
|
||||
return valOfBonuses(Selector::type(type).And(selector));
|
||||
}
|
||||
|
||||
int IBonusBearer::valOfBonuses(Bonus::BonusType type, int subtype /*= -1*/) const
|
||||
@ -321,7 +321,7 @@ int IBonusBearer::valOfBonuses(Bonus::BonusType type, int subtype /*= -1*/) cons
|
||||
|
||||
CSelector s = Selector::type(type);
|
||||
if(subtype != -1)
|
||||
s = s && Selector::subtype(subtype);
|
||||
s = s.And(Selector::subtype(subtype));
|
||||
|
||||
return valOfBonuses(s, cachingStr.str());
|
||||
}
|
||||
@ -344,7 +344,7 @@ bool IBonusBearer::hasBonusOfType(Bonus::BonusType type, int subtype /*= -1*/) c
|
||||
|
||||
CSelector s = Selector::type(type);
|
||||
if(subtype != -1)
|
||||
s = s && Selector::subtype(subtype);
|
||||
s = s.And(Selector::subtype(subtype));
|
||||
|
||||
return hasBonus(s, cachingStr.str());
|
||||
}
|
||||
@ -451,13 +451,13 @@ ui32 IBonusBearer::getMinDamage() const
|
||||
{
|
||||
std::stringstream cachingStr;
|
||||
cachingStr << "type_" << Bonus::CREATURE_DAMAGE << "s_0Otype_" << Bonus::CREATURE_DAMAGE << "s_1";
|
||||
return valOfBonuses(Selector::typeSubtype(Bonus::CREATURE_DAMAGE, 0) || Selector::typeSubtype(Bonus::CREATURE_DAMAGE, 1), cachingStr.str());
|
||||
return valOfBonuses(Selector::typeSubtype(Bonus::CREATURE_DAMAGE, 0).Or(Selector::typeSubtype(Bonus::CREATURE_DAMAGE, 1)), cachingStr.str());
|
||||
}
|
||||
ui32 IBonusBearer::getMaxDamage() const
|
||||
{
|
||||
std::stringstream cachingStr;
|
||||
cachingStr << "type_" << Bonus::CREATURE_DAMAGE << "s_0Otype_" << Bonus::CREATURE_DAMAGE << "s_2";
|
||||
return valOfBonuses(Selector::typeSubtype(Bonus::CREATURE_DAMAGE, 0) || Selector::typeSubtype(Bonus::CREATURE_DAMAGE, 2), cachingStr.str());
|
||||
return valOfBonuses(Selector::typeSubtype(Bonus::CREATURE_DAMAGE, 0).Or(Selector::typeSubtype(Bonus::CREATURE_DAMAGE, 2)), cachingStr.str());
|
||||
}
|
||||
|
||||
si32 IBonusBearer::manaLimit() const
|
||||
@ -490,7 +490,9 @@ bool IBonusBearer::isLiving() const //TODO: theoreticaly there exists "LIVING" b
|
||||
{
|
||||
std::stringstream cachingStr;
|
||||
cachingStr << "type_" << Bonus::UNDEAD << "s_-1Otype_" << Bonus::NON_LIVING << "s_-11type_" << Bonus::SIEGE_WEAPON; //I don't relaly get what string labels mean?
|
||||
return(!hasBonus(Selector::type(Bonus::UNDEAD) || Selector::type(Bonus::NON_LIVING) || Selector::type(Bonus::SIEGE_WEAPON), cachingStr.str()));
|
||||
return !hasBonus(Selector::type(Bonus::UNDEAD)
|
||||
.Or(Selector::type(Bonus::NON_LIVING))
|
||||
.Or(Selector::type(Bonus::SIEGE_WEAPON)), cachingStr.str());
|
||||
}
|
||||
|
||||
const TBonusListPtr IBonusBearer::getSpellBonuses() const
|
||||
@ -1171,50 +1173,43 @@ Bonus * Bonus::addPropagator(TPropagatorPtr Propagator)
|
||||
return this;
|
||||
}
|
||||
|
||||
CSelector DLL_LINKAGE operator&&(const CSelector &first, const CSelector &second)
|
||||
{
|
||||
return CSelectorsConjunction(first, second);
|
||||
}
|
||||
CSelector DLL_LINKAGE operator||(const CSelector &first, const CSelector &second)
|
||||
{
|
||||
return CSelectorsAlternative(first, second);
|
||||
}
|
||||
|
||||
namespace Selector
|
||||
{
|
||||
DLL_LINKAGE CSelectFieldEqual<Bonus::BonusType> type(&Bonus::type, Bonus::NONE);
|
||||
DLL_LINKAGE CSelectFieldEqual<TBonusSubtype> subtype(&Bonus::subtype, 0);
|
||||
DLL_LINKAGE CSelectFieldEqual<si32> info(&Bonus::additionalInfo, 0);
|
||||
DLL_LINKAGE CSelectFieldEqual<ui16> duration(&Bonus::duration, 0);
|
||||
DLL_LINKAGE CSelectFieldEqual<Bonus::BonusSource> sourceType(&Bonus::source, Bonus::OTHER);
|
||||
DLL_LINKAGE CSelectFieldEqual<Bonus::LimitEffect> effectRange(&Bonus::effectRange, Bonus::NO_LIMIT);
|
||||
DLL_LINKAGE CSelectFieldEqual<Bonus::BonusType> type(&Bonus::type);
|
||||
DLL_LINKAGE CSelectFieldEqual<TBonusSubtype> subtype(&Bonus::subtype);
|
||||
DLL_LINKAGE CSelectFieldEqual<si32> info(&Bonus::additionalInfo);
|
||||
DLL_LINKAGE CSelectFieldEqual<ui16> duration(&Bonus::duration);
|
||||
DLL_LINKAGE CSelectFieldEqual<Bonus::BonusSource> sourceType(&Bonus::source);
|
||||
DLL_LINKAGE CSelectFieldEqual<Bonus::LimitEffect> effectRange(&Bonus::effectRange);
|
||||
DLL_LINKAGE CWillLastTurns turns;
|
||||
DLL_LINKAGE CSelectFieldAny<Bonus::LimitEffect> anyRange (&Bonus::effectRange);
|
||||
DLL_LINKAGE CSelectFieldEqualOrEvery<TBonusSubtype> everySubtype (&Bonus::subtype, 0);
|
||||
DLL_LINKAGE CSelectFieldAny<Bonus::LimitEffect> anyRange(&Bonus::effectRange);
|
||||
|
||||
CSelector DLL_LINKAGE typeSubtype(Bonus::BonusType Type, TBonusSubtype Subtype)
|
||||
{
|
||||
return type(Type) && subtype(Subtype);
|
||||
return type(Type).And(subtype(Subtype));
|
||||
}
|
||||
|
||||
CSelector DLL_LINKAGE typeSubtypeInfo(Bonus::BonusType type, TBonusSubtype subtype, si32 info)
|
||||
{
|
||||
return CSelectFieldEqual<Bonus::BonusType>(&Bonus::type, type) && CSelectFieldEqual<TBonusSubtype>(&Bonus::subtype, subtype) && CSelectFieldEqual<si32>(&Bonus::additionalInfo, info);
|
||||
return CSelectFieldEqual<Bonus::BonusType>(&Bonus::type)(type)
|
||||
.And(CSelectFieldEqual<TBonusSubtype>(&Bonus::subtype)(subtype))
|
||||
.And(CSelectFieldEqual<si32>(&Bonus::additionalInfo)(info));
|
||||
}
|
||||
|
||||
CSelector DLL_LINKAGE source(Bonus::BonusSource source, ui32 sourceID)
|
||||
{
|
||||
return CSelectFieldEqual<Bonus::BonusSource>(&Bonus::source, source) && CSelectFieldEqual<ui32>(&Bonus::sid, sourceID);
|
||||
return CSelectFieldEqual<Bonus::BonusSource>(&Bonus::source)(source)
|
||||
.And(CSelectFieldEqual<ui32>(&Bonus::sid)(sourceID));
|
||||
}
|
||||
|
||||
CSelector DLL_EXPORT durationType(ui16 duration)
|
||||
{
|
||||
return CSelectFieldEqual<ui16>(&Bonus::duration, duration);
|
||||
return CSelectFieldEqual<ui16>(&Bonus::duration)(duration);
|
||||
}
|
||||
|
||||
CSelector DLL_LINKAGE sourceTypeSel(Bonus::BonusSource source)
|
||||
{
|
||||
return CSelectFieldEqual<Bonus::BonusSource>(&Bonus::source, source);
|
||||
return CSelectFieldEqual<Bonus::BonusSource>(&Bonus::source)(source);
|
||||
}
|
||||
|
||||
bool DLL_LINKAGE matchesType(const CSelector &sel, Bonus::BonusType type)
|
||||
|
@ -27,7 +27,45 @@ typedef std::vector<std::pair<int,std::string> > TModDescr; //modifiers values a
|
||||
typedef std::set<CBonusSystemNode*> TNodes;
|
||||
typedef std::set<const CBonusSystemNode*> TCNodes;
|
||||
typedef std::vector<CBonusSystemNode *> TNodesVector;
|
||||
typedef std::function<bool(const Bonus*)> CSelector;
|
||||
|
||||
class CSelector : std::function<bool(const Bonus*)>
|
||||
{
|
||||
typedef std::function<bool(const Bonus*)> TBase;
|
||||
public:
|
||||
CSelector() {}
|
||||
template<typename T>
|
||||
CSelector(const T &t, //SFINAE trick -> include this c-tor in overload resolution only if parameter is class
|
||||
//(includes functors, lambdas) or function. Without that VC is going mad about ambiguities.
|
||||
typename std::enable_if < boost::mpl::or_ < std::is_class<T>, std::is_function<T >> ::value>::type *dummy = nullptr)
|
||||
: TBase(t)
|
||||
{}
|
||||
|
||||
CSelector(std::nullptr_t)
|
||||
{}
|
||||
//CSelector(std::function<bool(const Bonus*)> f) : std::function<bool(const Bonus*)>(std::move(f)) {}
|
||||
|
||||
CSelector And(CSelector rhs) const
|
||||
{
|
||||
//lambda may likely outlive "this" (it can be even a temporary) => we copy the OBJECT (not pointer)
|
||||
auto thisCopy = *this;
|
||||
return [thisCopy, rhs](const Bonus *b) mutable { return thisCopy(b) && rhs(b); };
|
||||
}
|
||||
CSelector Or(CSelector rhs) const
|
||||
{
|
||||
auto thisCopy = *this;
|
||||
return [thisCopy, rhs](const Bonus *b) mutable { return thisCopy(b) && rhs(b); };
|
||||
}
|
||||
|
||||
bool operator()(const Bonus *b) const
|
||||
{
|
||||
return TBase::operator()(b);
|
||||
}
|
||||
|
||||
operator bool() const
|
||||
{
|
||||
return !!static_cast<const TBase&>(*this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -694,55 +732,21 @@ inline Bonus * makeFeature(Bonus::BonusType type, ui8 duration, si16 subtype, si
|
||||
return new Bonus(makeFeatureVal(type, duration, subtype, value, source, turnsRemain, additionalInfo));
|
||||
}
|
||||
|
||||
|
||||
class DLL_LINKAGE CSelectorsConjunction
|
||||
{
|
||||
const CSelector first, second;
|
||||
public:
|
||||
CSelectorsConjunction(const CSelector &First, const CSelector &Second)
|
||||
:first(First), second(Second)
|
||||
{
|
||||
}
|
||||
bool operator()(const Bonus *bonus) const
|
||||
{
|
||||
return first(bonus) && second(bonus);
|
||||
}
|
||||
};
|
||||
CSelector DLL_LINKAGE operator&&(const CSelector &first, const CSelector &second);
|
||||
|
||||
class DLL_LINKAGE CSelectorsAlternative
|
||||
{
|
||||
const CSelector first, second;
|
||||
public:
|
||||
CSelectorsAlternative(const CSelector &First, const CSelector &Second)
|
||||
:first(First), second(Second)
|
||||
{
|
||||
}
|
||||
bool operator()(const Bonus *bonus) const
|
||||
{
|
||||
return first(bonus) || second(bonus);
|
||||
}
|
||||
};
|
||||
CSelector DLL_LINKAGE operator||(const CSelector &first, const CSelector &second);
|
||||
|
||||
template<typename T>
|
||||
class CSelectFieldEqual
|
||||
{
|
||||
T Bonus::*ptr;
|
||||
T val;
|
||||
|
||||
public:
|
||||
CSelectFieldEqual(T Bonus::*Ptr, const T &Val)
|
||||
: ptr(Ptr), val(Val)
|
||||
CSelectFieldEqual(T Bonus::*Ptr)
|
||||
: ptr(Ptr)
|
||||
{
|
||||
}
|
||||
bool operator()(const Bonus *bonus) const
|
||||
|
||||
CSelector operator()(const T &valueToCompareAgainst) const
|
||||
{
|
||||
return bonus->*ptr == val;
|
||||
}
|
||||
CSelectFieldEqual& operator()(const T &setVal)
|
||||
{
|
||||
val = setVal;
|
||||
return *this;
|
||||
auto ptr2 = ptr; //We need a COPY because we don't want to reference this (might be outlived by lambda)
|
||||
return [ptr2, valueToCompareAgainst](const Bonus *bonus) { return bonus->*ptr2 == valueToCompareAgainst; };
|
||||
}
|
||||
};
|
||||
|
||||
@ -944,7 +948,6 @@ namespace Selector
|
||||
extern DLL_LINKAGE CSelectFieldEqual<Bonus::LimitEffect> effectRange;
|
||||
extern DLL_LINKAGE CWillLastTurns turns;
|
||||
extern DLL_LINKAGE CSelectFieldAny<Bonus::LimitEffect> anyRange;
|
||||
extern DLL_LINKAGE CSelectFieldEqualOrEvery<TBonusSubtype> everySubtype;
|
||||
|
||||
CSelector DLL_LINKAGE typeSubtype(Bonus::BonusType Type, TBonusSubtype Subtype);
|
||||
CSelector DLL_LINKAGE typeSubtypeInfo(Bonus::BonusType type, TBonusSubtype subtype, si32 info);
|
||||
|
@ -54,7 +54,9 @@ DLL_LINKAGE void SetPrimSkill::applyGs( CGameState *gs )
|
||||
|
||||
if(which < PrimarySkill::EXPERIENCE)
|
||||
{
|
||||
Bonus *skill = hero->getBonusLocalFirst(Selector::type(Bonus::PRIMARY_SKILL) && Selector::subtype(which) && Selector::sourceType(Bonus::HERO_BASE_SKILL));
|
||||
Bonus *skill = hero->getBonusLocalFirst(Selector::type(Bonus::PRIMARY_SKILL)
|
||||
.And(Selector::subtype(which))
|
||||
.And(Selector::sourceType(Bonus::HERO_BASE_SKILL)));
|
||||
assert(skill);
|
||||
|
||||
if(abs)
|
||||
@ -1069,7 +1071,8 @@ DLL_LINKAGE void BattleTriggerEffect::applyGs( CGameState *gs )
|
||||
}
|
||||
case Bonus::POISON:
|
||||
{
|
||||
Bonus * b = st->getBonusLocalFirst(Selector::source(Bonus::SPELL_EFFECT, 71) && Selector::type(Bonus::STACK_HEALTH));
|
||||
Bonus * b = st->getBonusLocalFirst(Selector::source(Bonus::SPELL_EFFECT, 71)
|
||||
.And(Selector::type(Bonus::STACK_HEALTH)));
|
||||
if (b)
|
||||
b->val = val;
|
||||
break;
|
||||
@ -1365,7 +1368,7 @@ DLL_LINKAGE void SetStackEffect::applyGs( CGameState *gs )
|
||||
CStack *s = gs->curB->getStack(para.first);
|
||||
if (s)
|
||||
{
|
||||
if (!s->hasBonus(Selector::source(Bonus::SPELL_EFFECT, spellid) && Selector::typeSubtype(para.second.type, para.second.subtype)))
|
||||
if (!s->hasBonus(Selector::source(Bonus::SPELL_EFFECT, spellid).And(Selector::typeSubtype(para.second.type, para.second.subtype))))
|
||||
s->addNewBonus(new Bonus(para.second));
|
||||
else
|
||||
actualizeEffect(s, effect);
|
||||
|
@ -342,9 +342,11 @@ void CCampaignScenario::prepareCrossoverHeroes( std::vector<CGHeroInstance *> he
|
||||
{
|
||||
for(int g=0; g<GameConstants::PRIMARY_SKILLS; ++g)
|
||||
{
|
||||
cgh->getBonusLocalFirst(Selector::type(Bonus::PRIMARY_SKILL) &&
|
||||
Selector::subtype(g) && Selector::sourceType(Bonus::HERO_BASE_SKILL) )->val
|
||||
= cgh->type->heroClass->primarySkillInitial[g];
|
||||
auto sel = Selector::type(Bonus::PRIMARY_SKILL)
|
||||
.And(Selector::subtype(g))
|
||||
.And(Selector::sourceType(Bonus::HERO_BASE_SKILL));
|
||||
|
||||
cgh->getBonusLocalFirst(sel)->val = cgh->type->heroClass->primarySkillInitial[g];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,14 @@ CMapInfo::CMapInfo() : scenarioOpts(nullptr), playerAmnt(0), humanPlayers(0),
|
||||
|
||||
}
|
||||
|
||||
#define STEAL(x) x(std::move(tmp.x))
|
||||
|
||||
CMapInfo::CMapInfo(CMapInfo && tmp)
|
||||
: STEAL(mapHeader), STEAL(campaignHeader), STEAL(scenarioOpts), STEAL(fileURI), STEAL(date),
|
||||
STEAL(playerAmnt), STEAL(humanPlayers), STEAL(actualHumanPlayers), STEAL(isRandomMap)
|
||||
{}
|
||||
|
||||
|
||||
void CMapInfo::mapInit(const std::string & fname)
|
||||
{
|
||||
fileURI = fname;
|
||||
|
@ -31,6 +31,8 @@ public:
|
||||
bool isRandomMap; // true if the map will be created randomly, false if not
|
||||
|
||||
CMapInfo();
|
||||
CMapInfo(CMapInfo && tmp);
|
||||
|
||||
void mapInit(const std::string & fname);
|
||||
void campaignInit();
|
||||
void countPlayers();
|
||||
|
@ -1137,13 +1137,13 @@ void CGameHandler::newTurn()
|
||||
n.specialWeek = NewTurn::DOUBLE_GROWTH;
|
||||
if (VLC->modh->settings.ALL_CREATURES_GET_DOUBLE_MONTHS)
|
||||
{
|
||||
std::pair<int,CreatureID> newMonster(54, VLC->creh->pickRandomMonster(std::ref(rand)));
|
||||
std::pair<int, CreatureID> newMonster(54, VLC->creh->pickRandomMonster([]{ return rand(); }));
|
||||
n.creatureid = newMonster.second;
|
||||
}
|
||||
else if(VLC->creh->doubledCreatures.size())
|
||||
{
|
||||
const std::vector<CreatureID> doubledCreatures (VLC->creh->doubledCreatures.begin(), VLC->creh->doubledCreatures.end());
|
||||
n.creatureid = vstd::pickRandomElementOf (doubledCreatures, std::ref(rand));
|
||||
n.creatureid = vstd::pickRandomElementOf(doubledCreatures, []{ return rand(); });
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1159,7 +1159,7 @@ void CGameHandler::newTurn()
|
||||
if (monthType < 25)
|
||||
{
|
||||
n.specialWeek = NewTurn::BONUS_GROWTH; //+5
|
||||
std::pair<int, CreatureID> newMonster (54, VLC->creh->pickRandomMonster(std::ref(rand)));
|
||||
std::pair<int, CreatureID> newMonster(54, VLC->creh->pickRandomMonster([]{ return rand(); }));
|
||||
//TODO do not pick neutrals
|
||||
n.creatureid = newMonster.second;
|
||||
}
|
||||
@ -3409,7 +3409,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
|
||||
//attack
|
||||
|
||||
int totalAttacks = 1 + stack->getBonuses(Selector::type (Bonus::ADDITIONAL_ATTACK),
|
||||
(Selector::effectRange (Bonus::NO_LIMIT) || Selector::effectRange(Bonus::ONLY_MELEE_FIGHT)))->totalValue(); //all unspicified attacks + melee attacks
|
||||
(Selector::effectRange(Bonus::NO_LIMIT).Or(Selector::effectRange(Bonus::ONLY_MELEE_FIGHT))))->totalValue(); //all unspicified attacks + melee attacks
|
||||
|
||||
for (int i = 0; i < totalAttacks; ++i)
|
||||
{
|
||||
@ -3479,7 +3479,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
|
||||
//allow more than one additional attack
|
||||
|
||||
int additionalAttacks = stack->getBonuses(Selector::type (Bonus::ADDITIONAL_ATTACK),
|
||||
(Selector::effectRange (Bonus::NO_LIMIT) || Selector::effectRange(Bonus::ONLY_DISTANCE_FIGHT)))->totalValue();
|
||||
(Selector::effectRange(Bonus::NO_LIMIT).Or(Selector::effectRange(Bonus::ONLY_DISTANCE_FIGHT))))->totalValue();
|
||||
for (int i = 0; i < additionalAttacks; ++i)
|
||||
{
|
||||
if(
|
||||
@ -4494,7 +4494,7 @@ void CGameHandler::stackTurnTrigger(const CStack * st)
|
||||
|
||||
if(st->hasBonusOfType(Bonus::POISON))
|
||||
{
|
||||
const Bonus * b = st->getBonusLocalFirst(Selector::source(Bonus::SPELL_EFFECT, SpellID::POISON) && Selector::type(Bonus::STACK_HEALTH));
|
||||
const Bonus * b = st->getBonusLocalFirst(Selector::source(Bonus::SPELL_EFFECT, SpellID::POISON).And(Selector::type(Bonus::STACK_HEALTH)));
|
||||
if (b) //TODO: what if not?...
|
||||
{
|
||||
bte.val = std::max (b->val - 10, -(st->valOfBonuses(Bonus::POISON)));
|
||||
|
Loading…
Reference in New Issue
Block a user