1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +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:
godric3 2018-04-17 14:59:30 +02:00 committed by ArseniyShestakov
parent ad2c429d8f
commit d9d01f0b68
9 changed files with 137 additions and 22 deletions

View File

@ -69,3 +69,6 @@ Piotr Wójcik aka Chocimier, <chocimier@tlen.pl>
Henning Koehler, <henning.koehler.nz@gmail.com>
* skill modding, bonus updaters
Andrzej Żak aka godric3
* minor bug fixes and modding features

View File

@ -34,6 +34,7 @@ MODS:
* Map object sounds can now be configured via json
* Added bonus updaters for hero specialties
* Added allOf, anyOf and noneOf qualifiers for bonus limiters
* Added bonus limiters: alignment, faction and terrain
SOUND:
* Fixed many mising or wrong pickup and visit sounds for map objects

View File

@ -282,6 +282,16 @@ bool CStack::canBeHealed() const
&& !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
{
return type;

View File

@ -47,6 +47,8 @@ public:
std::string getName() const; //plural or singular
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;
si32 magicResistance() const override; //include aura of resistance

View File

@ -16,11 +16,13 @@
#include "CCreatureHandler.h"
#include "CCreatureSet.h"
#include "CHeroHandler.h"
#include "CTownHandler.h"
#include "CGeneralTextHandler.h"
#include "CSkillHandler.h"
#include "CStack.h"
#include "CArtHandler.h"
#include "StringConstants.h"
#include "battle/BattleInfo.h"
#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)
@ -68,7 +70,8 @@ const std::map<std::string, TLimiterPtr> bonusLimiterMap =
{
{"SHOOTER_ONLY", std::make_shared<HasAnotherBonusLimiter>(Bonus::SHOOTER)},
{"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 =
@ -1623,11 +1626,9 @@ void CCreatureTypeLimiter::setCreature (CreatureID id)
std::string CCreatureTypeLimiter::toString() const
{
char buf[100];
sprintf(buf, "CCreatureTypeLimiter(creature=%s, includeUpgrades=%s)",
creature->identifier.c_str(),
(includeUpgrades ? "true" : "false"));
return std::string(buf);
boost::format fmt("CCreatureTypeLimiter(creature=%s, includeUpgrades=%s)");
fmt % creature->identifier % (includeUpgrades ? "true" : "false");
return fmt.str();
}
JsonNode CCreatureTypeLimiter::toJsonNode() const
@ -1671,15 +1672,19 @@ int HasAnotherBonusLimiter::limit(const BonusLimitationContext &context) const
std::string HasAnotherBonusLimiter::toString() const
{
char buf[100];
std::string typeName = vstd::findKey(bonusNameMap, type);
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
sprintf(buf, "HasAnotherBonusLimiter(type=%s)", typeName.c_str());
return std::string(buf);
{
boost::format fmt("HasAnotherBonusLimiter(type=%s)");
fmt % typeName;
return fmt.str();
}
}
JsonNode HasAnotherBonusLimiter::toJsonNode() const
@ -1721,24 +1726,48 @@ bool CPropagatorNodeType::shouldBeAttached(CBonusSystemNode *dest)
return nodeType == dest->getNodeType();
}
CreatureNativeTerrainLimiter::CreatureNativeTerrainLimiter(int TerrainType)
CreatureTerrainLimiter::CreatureTerrainLimiter(int TerrainType)
: terrainType(TerrainType)
{
}
CreatureNativeTerrainLimiter::CreatureNativeTerrainLimiter()
CreatureTerrainLimiter::CreatureTerrainLimiter()
: terrainType(-1)
{
}
int CreatureNativeTerrainLimiter::limit(const BonusLimitationContext &context) const
int CreatureTerrainLimiter::limit(const BonusLimitationContext &context) const
{
const CCreature *c = retrieveCreature(&context.node);
return !c || !c->isItNativeTerrain(terrainType); //drop bonus for non-creatures or non-native residents
const CStack *stack = retrieveStackBattle(&context.node);
if(stack)
{
if(terrainType == -1)//terrainType not specified = native
return !stack->isOnNativeTerrain();
return !stack->isOnTerrain(terrainType);
}
return true;
//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)
: 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
}
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()
: 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)
:minRank(Min), maxRank(Max)
{

View File

@ -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:
int terrainType;
CreatureNativeTerrainLimiter();
CreatureNativeTerrainLimiter(int TerrainType);
CreatureTerrainLimiter();
CreatureTerrainLimiter(int TerrainType);
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)
{
@ -989,6 +991,8 @@ public:
CreatureFactionLimiter(int TerrainType);
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)
{
@ -1005,6 +1009,8 @@ public:
CreatureAlignmentLimiter(si8 Alignment);
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)
{

View File

@ -19,6 +19,7 @@
#include "CModHandler.h"
#include "CGeneralTextHandler.h"
#include "JsonDetail.h"
#include "StringConstants.h"
using namespace JsonDetail;
@ -645,6 +646,35 @@ std::shared_ptr<ILimiter> JsonUtils::parseLimiter(const JsonNode & limiter)
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
{
logMod->error("Error: invalid customizable limiter type %s.", limiterType);

View File

@ -525,7 +525,7 @@ BattleInfo * BattleInfo::setupBattle(int3 tile, ETerrainType terrain, BFieldType
//overlay premies given
//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::PRIMARY_SKILL, Bonus::TERRAIN_NATIVE, 1, 0, PrimarySkill::ATTACK)->addLimiter(nativeTerrain));

View File

@ -185,7 +185,7 @@ void registerTypesMapObjects2(Serializer &s)
s.template registerType<ILimiter, AllOfLimiter>();
s.template registerType<ILimiter, CCreatureTypeLimiter>();
s.template registerType<ILimiter, HasAnotherBonusLimiter>();
s.template registerType<ILimiter, CreatureNativeTerrainLimiter>();
s.template registerType<ILimiter, CreatureTerrainLimiter>();
s.template registerType<ILimiter, CreatureFactionLimiter>();
s.template registerType<ILimiter, CreatureAlignmentLimiter>();
s.template registerType<ILimiter, RankRangeLimiter>();