1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-13 19:54:17 +02:00

Additional properties for limiter

This commit is contained in:
nordsoft
2023-10-09 04:19:12 +02:00
parent 937a8d63c7
commit 6a7b23c007
6 changed files with 105 additions and 4 deletions

View File

@@ -72,7 +72,7 @@ Rewardable object is defined similarly to other objects, with key difference bei
// additional list of conditions. Limiter will be valid if any of these conditions are true // additional list of conditions. Limiter will be valid if any of these conditions are true
"anyOf" : [ "anyOf" : [
{ {
// See "Configurable Properties" section for additiona parameters // See "Configurable Properties" section for additional parameters
<additional properties> <additional properties>
} }
] ]
@@ -80,12 +80,12 @@ Rewardable object is defined similarly to other objects, with key difference bei
// additional list of conditions. Limiter will be valid only if none of these conditions are true // additional list of conditions. Limiter will be valid only if none of these conditions are true
"noneOf" : [ "noneOf" : [
{ {
// See "Configurable Properties" section for additiona parameters // See "Configurable Properties" section for additional parameters
<additional properties> <additional properties>
} }
] ]
// See "Configurable Properties" section for additiona parameters // See "Configurable Properties" section for additional parameters
<additional properties> <additional properties>
} }
@@ -95,7 +95,7 @@ Rewardable object is defined similarly to other objects, with key difference bei
// object will be disappeared after taking reward is set to true // object will be disappeared after taking reward is set to true
"removeObject": false "removeObject": false
// See "Configurable Properties" section for additiona parameters // See "Configurable Properties" section for additional parameters
<additional properties> <additional properties>
} }
], ],
@@ -450,4 +450,32 @@ Keep in mind, that all randomization is performed on map load and on object rese
"spell" : "townPortal", "spell" : "townPortal",
"schoolLevel": 3 "schoolLevel": 3
} }
```
### Player color
- Can be used as limiter
- Can NOT be used as reward
- Only players with specific color can pass the limiter
- If not specified or empty all colors may pass the limiter
```jsonc
"colors" : [ "red", "blue", "tan", "green", "orange", "purple", "teal", "pink" ]
```
### Hero types
- Can be used as limiter
- Can NOT be used as reward
- Only specific heroes can pass the limiter
```jsonc
"heroes" : [ "orrin" ]
```
### Hero classes
- Can be used as limiter
- Can NOT be used as reward
- Only heroes belonging to specific classes can pass the limiter
```jsonc
"heroClasses" : [ "battlemage" ]
``` ```

View File

@@ -22,6 +22,7 @@
#include "CCreatureSet.h" #include "CCreatureSet.h"
#include "spells/CSpellHandler.h" #include "spells/CSpellHandler.h"
#include "CSkillHandler.h" #include "CSkillHandler.h"
#include "CHeroHandler.h"
#include "IGameCallback.h" #include "IGameCallback.h"
#include "mapObjects/IObjectInterface.h" #include "mapObjects/IObjectInterface.h"
#include "modding/IdentifierStorage.h" #include "modding/IdentifierStorage.h"
@@ -282,6 +283,46 @@ namespace JsonRandom
return ret; return ret;
} }
std::vector<PlayerColor> loadColors(const JsonNode & value, CRandomGenerator & rng)
{
std::vector<PlayerColor> ret;
std::set<std::string> def;
for(auto & color : GameConstants::PLAYER_COLOR_NAMES)
def.insert(color);
for(auto & entry : value.Vector())
{
auto key = loadKey(entry, rng, def);
auto pos = vstd::find_pos(GameConstants::PLAYER_COLOR_NAMES, key);
if(pos < 0)
logMod->warn("Unable to determine player color %s", key);
else
ret.emplace_back(pos);
}
return ret;
}
std::vector<HeroTypeID> loadHeroes(const JsonNode & value, CRandomGenerator & rng)
{
std::vector<HeroTypeID> ret;
for(auto & entry : value.Vector())
{
ret.push_back(VLC->heroTypes()->getByIndex(VLC->identifiers()->getIdentifier("hero", entry.String()).value())->getId());
}
return ret;
}
std::vector<HeroClassID> loadHeroClasses(const JsonNode & value, CRandomGenerator & rng)
{
std::vector<HeroClassID> ret;
for(auto & entry : value.Vector())
{
ret.push_back(VLC->heroClasses()->getByIndex(VLC->identifiers()->getIdentifier("heroClass", entry.String()).value())->getId());
}
return ret;
}
CStackBasicDescriptor loadCreature(const JsonNode & value, CRandomGenerator & rng) CStackBasicDescriptor loadCreature(const JsonNode & value, CRandomGenerator & rng)
{ {
CStackBasicDescriptor stack; CStackBasicDescriptor stack;

View File

@@ -48,6 +48,10 @@ namespace JsonRandom
DLL_LINKAGE std::vector<CStackBasicDescriptor> loadCreatures(const JsonNode & value, CRandomGenerator & rng); DLL_LINKAGE std::vector<CStackBasicDescriptor> loadCreatures(const JsonNode & value, CRandomGenerator & rng);
DLL_LINKAGE std::vector<RandomStackInfo> evaluateCreatures(const JsonNode & value); DLL_LINKAGE std::vector<RandomStackInfo> evaluateCreatures(const JsonNode & value);
DLL_LINKAGE std::vector<PlayerColor> loadColors(const JsonNode & value, CRandomGenerator & rng);
DLL_LINKAGE std::vector<HeroTypeID> loadHeroes(const JsonNode & value, CRandomGenerator & rng);
DLL_LINKAGE std::vector<HeroClassID> loadHeroClasses(const JsonNode & value, CRandomGenerator & rng);
DLL_LINKAGE std::vector<Bonus> loadBonuses(const JsonNode & value); DLL_LINKAGE std::vector<Bonus> loadBonuses(const JsonNode & value);
//DLL_LINKAGE std::vector<Component> loadComponents(const JsonNode & value); //DLL_LINKAGE std::vector<Component> loadComponents(const JsonNode & value);
} }

View File

@@ -122,6 +122,10 @@ void Rewardable::Info::configureLimiter(Rewardable::Configuration & object, CRan
limiter.artifacts = JsonRandom::loadArtifacts(source["artifacts"], rng); limiter.artifacts = JsonRandom::loadArtifacts(source["artifacts"], rng);
limiter.spells = JsonRandom::loadSpells(source["spells"], rng, spells); limiter.spells = JsonRandom::loadSpells(source["spells"], rng, spells);
limiter.creatures = JsonRandom::loadCreatures(source["creatures"], rng); limiter.creatures = JsonRandom::loadCreatures(source["creatures"], rng);
limiter.players = JsonRandom::loadColors(source["colors"], rng);
limiter.heroes = JsonRandom::loadHeroes(source["heroes"], rng);
limiter.heroClasses = JsonRandom::loadHeroClasses(source["heroClasses"], rng);
limiter.allOf = configureSublimiters(object, rng, source["allOf"] ); limiter.allOf = configureSublimiters(object, rng, source["allOf"] );
limiter.anyOf = configureSublimiters(object, rng, source["anyOf"] ); limiter.anyOf = configureSublimiters(object, rng, source["anyOf"] );

View File

@@ -16,6 +16,7 @@
#include "../mapObjects/CGHeroInstance.h" #include "../mapObjects/CGHeroInstance.h"
#include "../serializer/JsonSerializeFormat.h" #include "../serializer/JsonSerializeFormat.h"
#include "../constants/StringConstants.h" #include "../constants/StringConstants.h"
#include "../CHeroHandler.h"
#include "../CSkillHandler.h" #include "../CSkillHandler.h"
#include "../ArtifactUtils.h" #include "../ArtifactUtils.h"
@@ -112,6 +113,16 @@ bool Rewardable::Limiter::heroAllowed(const CGHeroInstance * hero) const
return false; return false;
} }
if(!players.empty() && !vstd::contains(players, hero->getOwner()))
return false;
if(!heroes.empty() && !vstd::contains(heroes, hero->type->getId()))
return false;
if(!heroClasses.empty() && !vstd::contains(heroClasses, hero->type->heroClass->getId()))
return false;
for(const auto & sublimiter : noneOf) for(const auto & sublimiter : noneOf)
{ {
if (sublimiter->heroAllowed(hero)) if (sublimiter->heroAllowed(hero))
@@ -143,6 +154,9 @@ void Rewardable::Limiter::serializeJson(JsonSerializeFormat & handler)
handler.serializeInt("manaPercentage", manaPercentage); handler.serializeInt("manaPercentage", manaPercentage);
handler.serializeInt("heroExperience", heroExperience); handler.serializeInt("heroExperience", heroExperience);
handler.serializeInt("heroLevel", heroLevel); handler.serializeInt("heroLevel", heroLevel);
handler.serializeIdArray("hero", heroes);
handler.serializeIdArray("heroClass", heroClasses);
handler.serializeIdArray("color", players);
handler.serializeInt("manaPoints", manaPoints); handler.serializeInt("manaPoints", manaPoints);
handler.serializeIdArray("artifacts", artifacts); handler.serializeIdArray("artifacts", artifacts);
handler.enterArray("creatures").serializeStruct(creatures); handler.enterArray("creatures").serializeStruct(creatures);

View File

@@ -60,6 +60,13 @@ struct DLL_LINKAGE Limiter
/// creatures that hero needs to have /// creatures that hero needs to have
std::vector<CStackBasicDescriptor> creatures; std::vector<CStackBasicDescriptor> creatures;
/// only heroes/hero classes from list could pass limiter
std::vector<HeroTypeID> heroes;
std::vector<HeroClassID> heroClasses;
/// only player colors can pass limiter
std::vector<PlayerColor> players;
/// sub-limiters, all must pass for this limiter to pass /// sub-limiters, all must pass for this limiter to pass
LimitersList allOf; LimitersList allOf;
@@ -91,6 +98,9 @@ struct DLL_LINKAGE Limiter
h & allOf; h & allOf;
h & anyOf; h & anyOf;
h & noneOf; h & noneOf;
h & heroes;
h & heroClasses;
h & players;
} }
void serializeJson(JsonSerializeFormat & handler); void serializeJson(JsonSerializeFormat & handler);