mirror of
https://github.com/vcmi/vcmi.git
synced 2025-07-17 01:32:21 +02:00
Exposed more of existing limiters for modders (#449)
* Exposed alignment, faction and terrain limiters * Limiters toString() use now boost:format
This commit is contained in:
committed by
ArseniyShestakov
parent
ad2c429d8f
commit
d9d01f0b68
3
AUTHORS
3
AUTHORS
@ -69,3 +69,6 @@ Piotr Wójcik aka Chocimier, <chocimier@tlen.pl>
|
|||||||
|
|
||||||
Henning Koehler, <henning.koehler.nz@gmail.com>
|
Henning Koehler, <henning.koehler.nz@gmail.com>
|
||||||
* skill modding, bonus updaters
|
* skill modding, bonus updaters
|
||||||
|
|
||||||
|
Andrzej Żak aka godric3
|
||||||
|
* minor bug fixes and modding features
|
||||||
|
@ -34,6 +34,7 @@ MODS:
|
|||||||
* Map object sounds can now be configured via json
|
* Map object sounds can now be configured via json
|
||||||
* Added bonus updaters for hero specialties
|
* Added bonus updaters for hero specialties
|
||||||
* Added allOf, anyOf and noneOf qualifiers for bonus limiters
|
* Added allOf, anyOf and noneOf qualifiers for bonus limiters
|
||||||
|
* Added bonus limiters: alignment, faction and terrain
|
||||||
|
|
||||||
SOUND:
|
SOUND:
|
||||||
* Fixed many mising or wrong pickup and visit sounds for map objects
|
* Fixed many mising or wrong pickup and visit sounds for map objects
|
||||||
|
@ -282,6 +282,16 @@ bool CStack::canBeHealed() const
|
|||||||
&& !hasBonusOfType(Bonus::SIEGE_WEAPON);
|
&& !hasBonusOfType(Bonus::SIEGE_WEAPON);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CStack::isOnNativeTerrain() const
|
||||||
|
{
|
||||||
|
return type->isItNativeTerrain(battle->getTerrainType());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CStack::isOnTerrain(int terrain) const
|
||||||
|
{
|
||||||
|
return battle->getTerrainType() == terrain;
|
||||||
|
}
|
||||||
|
|
||||||
const CCreature * CStack::unitType() const
|
const CCreature * CStack::unitType() const
|
||||||
{
|
{
|
||||||
return type;
|
return type;
|
||||||
|
@ -47,6 +47,8 @@ public:
|
|||||||
std::string getName() const; //plural or singular
|
std::string getName() const; //plural or singular
|
||||||
|
|
||||||
bool canBeHealed() const; //for first aid tent - only harmed stacks that are not war machines
|
bool canBeHealed() const; //for first aid tent - only harmed stacks that are not war machines
|
||||||
|
bool isOnNativeTerrain() const;
|
||||||
|
bool isOnTerrain(int terrain) const;
|
||||||
|
|
||||||
ui32 level() const;
|
ui32 level() const;
|
||||||
si32 magicResistance() const override; //include aura of resistance
|
si32 magicResistance() const override; //include aura of resistance
|
||||||
|
@ -16,11 +16,13 @@
|
|||||||
#include "CCreatureHandler.h"
|
#include "CCreatureHandler.h"
|
||||||
#include "CCreatureSet.h"
|
#include "CCreatureSet.h"
|
||||||
#include "CHeroHandler.h"
|
#include "CHeroHandler.h"
|
||||||
|
#include "CTownHandler.h"
|
||||||
#include "CGeneralTextHandler.h"
|
#include "CGeneralTextHandler.h"
|
||||||
#include "CSkillHandler.h"
|
#include "CSkillHandler.h"
|
||||||
#include "CStack.h"
|
#include "CStack.h"
|
||||||
#include "CArtHandler.h"
|
#include "CArtHandler.h"
|
||||||
#include "StringConstants.h"
|
#include "StringConstants.h"
|
||||||
|
#include "battle/BattleInfo.h"
|
||||||
|
|
||||||
#define FOREACH_PARENT(pname) TNodes lparents; getParents(lparents); for(CBonusSystemNode *pname : lparents)
|
#define FOREACH_PARENT(pname) TNodes lparents; getParents(lparents); for(CBonusSystemNode *pname : lparents)
|
||||||
#define FOREACH_CPARENT(pname) TCNodes lparents; getParents(lparents); for(const CBonusSystemNode *pname : lparents)
|
#define FOREACH_CPARENT(pname) TCNodes lparents; getParents(lparents); for(const CBonusSystemNode *pname : lparents)
|
||||||
@ -68,7 +70,8 @@ const std::map<std::string, TLimiterPtr> bonusLimiterMap =
|
|||||||
{
|
{
|
||||||
{"SHOOTER_ONLY", std::make_shared<HasAnotherBonusLimiter>(Bonus::SHOOTER)},
|
{"SHOOTER_ONLY", std::make_shared<HasAnotherBonusLimiter>(Bonus::SHOOTER)},
|
||||||
{"DRAGON_NATURE", std::make_shared<HasAnotherBonusLimiter>(Bonus::DRAGON_NATURE)},
|
{"DRAGON_NATURE", std::make_shared<HasAnotherBonusLimiter>(Bonus::DRAGON_NATURE)},
|
||||||
{"IS_UNDEAD", std::make_shared<HasAnotherBonusLimiter>(Bonus::UNDEAD)}
|
{"IS_UNDEAD", std::make_shared<HasAnotherBonusLimiter>(Bonus::UNDEAD)},
|
||||||
|
{"CREATURE_NATIVE_TERRAIN", std::make_shared<CreatureTerrainLimiter>()}
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::map<std::string, TPropagatorPtr> bonusPropagatorMap =
|
const std::map<std::string, TPropagatorPtr> bonusPropagatorMap =
|
||||||
@ -1623,11 +1626,9 @@ void CCreatureTypeLimiter::setCreature (CreatureID id)
|
|||||||
|
|
||||||
std::string CCreatureTypeLimiter::toString() const
|
std::string CCreatureTypeLimiter::toString() const
|
||||||
{
|
{
|
||||||
char buf[100];
|
boost::format fmt("CCreatureTypeLimiter(creature=%s, includeUpgrades=%s)");
|
||||||
sprintf(buf, "CCreatureTypeLimiter(creature=%s, includeUpgrades=%s)",
|
fmt % creature->identifier % (includeUpgrades ? "true" : "false");
|
||||||
creature->identifier.c_str(),
|
return fmt.str();
|
||||||
(includeUpgrades ? "true" : "false"));
|
|
||||||
return std::string(buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonNode CCreatureTypeLimiter::toJsonNode() const
|
JsonNode CCreatureTypeLimiter::toJsonNode() const
|
||||||
@ -1671,15 +1672,19 @@ int HasAnotherBonusLimiter::limit(const BonusLimitationContext &context) const
|
|||||||
|
|
||||||
std::string HasAnotherBonusLimiter::toString() const
|
std::string HasAnotherBonusLimiter::toString() const
|
||||||
{
|
{
|
||||||
char buf[100];
|
|
||||||
|
|
||||||
std::string typeName = vstd::findKey(bonusNameMap, type);
|
std::string typeName = vstd::findKey(bonusNameMap, type);
|
||||||
if(isSubtypeRelevant)
|
if(isSubtypeRelevant)
|
||||||
sprintf(buf, "HasAnotherBonusLimiter(type=%s, subtype=%d)", typeName.c_str(), subtype);
|
{
|
||||||
|
boost::format fmt("HasAnotherBonusLimiter(type=%s, subtype=%d)");
|
||||||
|
fmt % typeName % subtype;
|
||||||
|
return fmt.str();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
sprintf(buf, "HasAnotherBonusLimiter(type=%s)", typeName.c_str());
|
{
|
||||||
|
boost::format fmt("HasAnotherBonusLimiter(type=%s)");
|
||||||
return std::string(buf);
|
fmt % typeName;
|
||||||
|
return fmt.str();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonNode HasAnotherBonusLimiter::toJsonNode() const
|
JsonNode HasAnotherBonusLimiter::toJsonNode() const
|
||||||
@ -1721,24 +1726,48 @@ bool CPropagatorNodeType::shouldBeAttached(CBonusSystemNode *dest)
|
|||||||
return nodeType == dest->getNodeType();
|
return nodeType == dest->getNodeType();
|
||||||
}
|
}
|
||||||
|
|
||||||
CreatureNativeTerrainLimiter::CreatureNativeTerrainLimiter(int TerrainType)
|
CreatureTerrainLimiter::CreatureTerrainLimiter(int TerrainType)
|
||||||
: terrainType(TerrainType)
|
: terrainType(TerrainType)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CreatureNativeTerrainLimiter::CreatureNativeTerrainLimiter()
|
CreatureTerrainLimiter::CreatureTerrainLimiter()
|
||||||
: terrainType(-1)
|
: terrainType(-1)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int CreatureNativeTerrainLimiter::limit(const BonusLimitationContext &context) const
|
int CreatureTerrainLimiter::limit(const BonusLimitationContext &context) const
|
||||||
{
|
{
|
||||||
const CCreature *c = retrieveCreature(&context.node);
|
const CStack *stack = retrieveStackBattle(&context.node);
|
||||||
return !c || !c->isItNativeTerrain(terrainType); //drop bonus for non-creatures or non-native residents
|
if(stack)
|
||||||
|
{
|
||||||
|
if(terrainType == -1)//terrainType not specified = native
|
||||||
|
return !stack->isOnNativeTerrain();
|
||||||
|
return !stack->isOnTerrain(terrainType);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
//TODO neutral creatues
|
//TODO neutral creatues
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string CreatureTerrainLimiter::toString() const
|
||||||
|
{
|
||||||
|
boost::format fmt("CreatureTerrainLimiter(terrainType=%s)");
|
||||||
|
fmt % (terrainType >= 0 ? GameConstants::TERRAIN_NAMES[terrainType] : "native");
|
||||||
|
return fmt.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonNode CreatureTerrainLimiter::toJsonNode() const
|
||||||
|
{
|
||||||
|
JsonNode root(JsonNode::JsonType::DATA_STRUCT);
|
||||||
|
|
||||||
|
root["type"].String() = "CREATURE_TERRAIN_LIMITER";
|
||||||
|
if(terrainType >= 0)
|
||||||
|
root["parameters"].Vector().push_back(JsonUtils::stringNode(GameConstants::TERRAIN_NAMES[terrainType]));
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
CreatureFactionLimiter::CreatureFactionLimiter(int Faction)
|
CreatureFactionLimiter::CreatureFactionLimiter(int Faction)
|
||||||
: faction(Faction)
|
: faction(Faction)
|
||||||
{
|
{
|
||||||
@ -1755,6 +1784,23 @@ int CreatureFactionLimiter::limit(const BonusLimitationContext &context) const
|
|||||||
return !c || c->faction != faction; //drop bonus for non-creatures or non-native residents
|
return !c || c->faction != faction; //drop bonus for non-creatures or non-native residents
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string CreatureFactionLimiter::toString() const
|
||||||
|
{
|
||||||
|
boost::format fmt("CreatureFactionLimiter(faction=%s)");
|
||||||
|
fmt % VLC->townh->factions[faction]->identifier;
|
||||||
|
return fmt.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonNode CreatureFactionLimiter::toJsonNode() const
|
||||||
|
{
|
||||||
|
JsonNode root(JsonNode::JsonType::DATA_STRUCT);
|
||||||
|
|
||||||
|
root["type"].String() = "CREATURE_FACTION_LIMITER";
|
||||||
|
root["parameters"].Vector().push_back(JsonUtils::stringNode(VLC->townh->factions[faction]->identifier));
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
CreatureAlignmentLimiter::CreatureAlignmentLimiter()
|
CreatureAlignmentLimiter::CreatureAlignmentLimiter()
|
||||||
: alignment(-1)
|
: alignment(-1)
|
||||||
{
|
{
|
||||||
@ -1784,6 +1830,23 @@ int CreatureAlignmentLimiter::limit(const BonusLimitationContext &context) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string CreatureAlignmentLimiter::toString() const
|
||||||
|
{
|
||||||
|
boost::format fmt("CreatureAlignmentLimiter(alignment=%s)");
|
||||||
|
fmt % EAlignment::names[alignment];
|
||||||
|
return fmt.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonNode CreatureAlignmentLimiter::toJsonNode() const
|
||||||
|
{
|
||||||
|
JsonNode root(JsonNode::JsonType::DATA_STRUCT);
|
||||||
|
|
||||||
|
root["type"].String() = "CREATURE_ALIGNMENT_LIMITER";
|
||||||
|
root["parameters"].Vector().push_back(JsonUtils::stringNode(EAlignment::names[alignment]));
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
RankRangeLimiter::RankRangeLimiter(ui8 Min, ui8 Max)
|
RankRangeLimiter::RankRangeLimiter(ui8 Min, ui8 Max)
|
||||||
:minRank(Min), maxRank(Max)
|
:minRank(Min), maxRank(Max)
|
||||||
{
|
{
|
||||||
|
@ -965,14 +965,16 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE CreatureNativeTerrainLimiter : public ILimiter //applies only to creatures that are on their native terrain
|
class DLL_LINKAGE CreatureTerrainLimiter : public ILimiter //applies only to creatures that are on specified terrain, default native terrain
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
int terrainType;
|
int terrainType;
|
||||||
CreatureNativeTerrainLimiter();
|
CreatureTerrainLimiter();
|
||||||
CreatureNativeTerrainLimiter(int TerrainType);
|
CreatureTerrainLimiter(int TerrainType);
|
||||||
|
|
||||||
int limit(const BonusLimitationContext &context) const override;
|
int limit(const BonusLimitationContext &context) const override;
|
||||||
|
virtual std::string toString() const override;
|
||||||
|
virtual JsonNode toJsonNode() const override;
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
@ -989,6 +991,8 @@ public:
|
|||||||
CreatureFactionLimiter(int TerrainType);
|
CreatureFactionLimiter(int TerrainType);
|
||||||
|
|
||||||
int limit(const BonusLimitationContext &context) const override;
|
int limit(const BonusLimitationContext &context) const override;
|
||||||
|
virtual std::string toString() const override;
|
||||||
|
virtual JsonNode toJsonNode() const override;
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
@ -1005,6 +1009,8 @@ public:
|
|||||||
CreatureAlignmentLimiter(si8 Alignment);
|
CreatureAlignmentLimiter(si8 Alignment);
|
||||||
|
|
||||||
int limit(const BonusLimitationContext &context) const override;
|
int limit(const BonusLimitationContext &context) const override;
|
||||||
|
virtual std::string toString() const override;
|
||||||
|
virtual JsonNode toJsonNode() const override;
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "CModHandler.h"
|
#include "CModHandler.h"
|
||||||
#include "CGeneralTextHandler.h"
|
#include "CGeneralTextHandler.h"
|
||||||
#include "JsonDetail.h"
|
#include "JsonDetail.h"
|
||||||
|
#include "StringConstants.h"
|
||||||
|
|
||||||
using namespace JsonDetail;
|
using namespace JsonDetail;
|
||||||
|
|
||||||
@ -645,6 +646,35 @@ std::shared_ptr<ILimiter> JsonUtils::parseLimiter(const JsonNode & limiter)
|
|||||||
return bonusLimiter;
|
return bonusLimiter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(limiterType == "CREATURE_ALIGNMENT_LIMITER")
|
||||||
|
{
|
||||||
|
int alignment = vstd::find_pos(EAlignment::names, parameters[0].String());
|
||||||
|
if(alignment == -1)
|
||||||
|
logMod->error("Error: invalid alignment %s.", parameters[0].String());
|
||||||
|
else
|
||||||
|
return std::make_shared<CreatureAlignmentLimiter>(alignment);
|
||||||
|
}
|
||||||
|
else if(limiterType == "CREATURE_FACTION_LIMITER")
|
||||||
|
{
|
||||||
|
std::shared_ptr<CreatureFactionLimiter> factionLimiter = std::make_shared<CreatureFactionLimiter>();
|
||||||
|
VLC->modh->identifiers.requestIdentifier("faction", parameters[0], [=](si32 faction)
|
||||||
|
{
|
||||||
|
factionLimiter->faction = faction;
|
||||||
|
});
|
||||||
|
return factionLimiter;
|
||||||
|
}
|
||||||
|
else if(limiterType == "CREATURE_TERRAIN_LIMITER")
|
||||||
|
{
|
||||||
|
std::shared_ptr<CreatureTerrainLimiter> terrainLimiter = std::make_shared<CreatureTerrainLimiter>();
|
||||||
|
if(parameters.size())
|
||||||
|
{
|
||||||
|
VLC->modh->identifiers.requestIdentifier("terrain", parameters[0], [=](si32 terrain)
|
||||||
|
{
|
||||||
|
terrainLimiter->terrainType = terrain;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return terrainLimiter;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
logMod->error("Error: invalid customizable limiter type %s.", limiterType);
|
logMod->error("Error: invalid customizable limiter type %s.", limiterType);
|
||||||
|
@ -525,7 +525,7 @@ BattleInfo * BattleInfo::setupBattle(int3 tile, ETerrainType terrain, BFieldType
|
|||||||
//overlay premies given
|
//overlay premies given
|
||||||
|
|
||||||
//native terrain bonuses
|
//native terrain bonuses
|
||||||
auto nativeTerrain = std::make_shared<CreatureNativeTerrainLimiter>(curB->terrainType);
|
auto nativeTerrain = std::make_shared<CreatureTerrainLimiter>();
|
||||||
|
|
||||||
curB->addNewBonus(std::make_shared<Bonus>(Bonus::ONE_BATTLE, Bonus::STACKS_SPEED, Bonus::TERRAIN_NATIVE, 1, 0, 0)->addLimiter(nativeTerrain));
|
curB->addNewBonus(std::make_shared<Bonus>(Bonus::ONE_BATTLE, Bonus::STACKS_SPEED, Bonus::TERRAIN_NATIVE, 1, 0, 0)->addLimiter(nativeTerrain));
|
||||||
curB->addNewBonus(std::make_shared<Bonus>(Bonus::ONE_BATTLE, Bonus::PRIMARY_SKILL, Bonus::TERRAIN_NATIVE, 1, 0, PrimarySkill::ATTACK)->addLimiter(nativeTerrain));
|
curB->addNewBonus(std::make_shared<Bonus>(Bonus::ONE_BATTLE, Bonus::PRIMARY_SKILL, Bonus::TERRAIN_NATIVE, 1, 0, PrimarySkill::ATTACK)->addLimiter(nativeTerrain));
|
||||||
|
@ -185,7 +185,7 @@ void registerTypesMapObjects2(Serializer &s)
|
|||||||
s.template registerType<ILimiter, AllOfLimiter>();
|
s.template registerType<ILimiter, AllOfLimiter>();
|
||||||
s.template registerType<ILimiter, CCreatureTypeLimiter>();
|
s.template registerType<ILimiter, CCreatureTypeLimiter>();
|
||||||
s.template registerType<ILimiter, HasAnotherBonusLimiter>();
|
s.template registerType<ILimiter, HasAnotherBonusLimiter>();
|
||||||
s.template registerType<ILimiter, CreatureNativeTerrainLimiter>();
|
s.template registerType<ILimiter, CreatureTerrainLimiter>();
|
||||||
s.template registerType<ILimiter, CreatureFactionLimiter>();
|
s.template registerType<ILimiter, CreatureFactionLimiter>();
|
||||||
s.template registerType<ILimiter, CreatureAlignmentLimiter>();
|
s.template registerType<ILimiter, CreatureAlignmentLimiter>();
|
||||||
s.template registerType<ILimiter, RankRangeLimiter>();
|
s.template registerType<ILimiter, RankRangeLimiter>();
|
||||||
|
Reference in New Issue
Block a user