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:
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>
|
||||
* 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
|
||||
* 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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
|
@ -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>();
|
||||
|
Loading…
Reference in New Issue
Block a user