1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Load obstacle sets from json in mods

This commit is contained in:
Tomasz Zieliński 2024-04-05 08:31:05 +02:00
parent b1a5693612
commit 305e2bdf2f
6 changed files with 102 additions and 5 deletions

View File

@ -16,6 +16,9 @@
"additionalProperties" : true, // Not validated on its own - instead data copied to main object and validated as part of it
"type" : "object"
},
"biome" : {
"type" : "object"
},
"rmg" : {
"additionalProperties" : false,
"type" : "object",

View File

@ -36,6 +36,45 @@ bool CObstacleConstructor::isStaticObject()
return true;
}
void CObstacleConstructor::initTypeData(const JsonNode & input)
{
if (!input["biome"].isNull())
{
obstacleType = ObstacleSet::typeFromString(input["biome"]["objectType"].String());
}
else
{
obstacleType = ObstacleSet::EObstacleType::INVALID;
}
}
void CObstacleConstructor::afterLoadFinalization()
{
if (obstacleType == ObstacleSet::EObstacleType::INVALID)
return;
auto templates = getTemplates();
logGlobal->info("Loaded %d templates for %s", templates.size(), getJsonKey());
if (!templates.empty())
{
auto terrains = templates.front()->getAllowedTerrains();
// FIXME: 0 terrains
logGlobal->info("Found %d terrains for %s", terrains.size(), getJsonKey());
// For now assume that all templates are from the same biome
for (auto terrain : terrains)
{
ObstacleSet os(obstacleType, terrain);
for (auto tmpl : templates)
{
os.addObstacle(tmpl);
}
VLC->biomeHandler->addObstacleSet(os);
logGlobal->info("Loaded obstacle set from mod %s, terrain: %s", getJsonKey(), terrain.encode(terrain.getNum()));
}
}
}
bool CreatureInstanceConstructor::hasNameTextID() const
{
return true;

View File

@ -14,6 +14,7 @@
#include "../mapObjects/MiscObjects.h"
#include "../mapObjects/CGCreature.h"
#include "../mapObjects/ObstacleSetHandler.h"
VCMI_LIB_NAMESPACE_BEGIN
@ -28,11 +29,17 @@ class CBank;
class CGBoat;
class CFaction;
class CStackBasicDescriptor;
class ObstacleSet;
class CObstacleConstructor : public CDefaultObjectTypeHandler<CGObjectInstance>
{
public:
bool isStaticObject() override;
void initTypeData(const JsonNode & input) override;
void afterLoadFinalization() override;
protected:
ObstacleSet::EObstacleType obstacleType;
};
class CreatureInstanceConstructor : public CDefaultObjectTypeHandler<CGCreature>

View File

@ -66,7 +66,6 @@ ObstacleSet::EObstacleType ObstacleSetHandler::convertObstacleClass(MapObjectID
switch (id)
{
case Obj::MOUNTAIN:
case Obj::SAND_DUNE:
case Obj::VOLCANIC_VENT:
case Obj::VOLCANO:
case Obj::REEF:
@ -94,6 +93,7 @@ ObstacleSet::EObstacleType ObstacleSetHandler::convertObstacleClass(MapObjectID
case Obj::MOUND:
case Obj::OUTCROPPING:
case Obj::ROCK:
case Obj::SAND_DUNE:
case Obj::STALAGMITE:
return ObstacleSet::ROCKS;
case Obj::BUSH:
@ -115,6 +115,30 @@ ObstacleSet::EObstacleType ObstacleSetHandler::convertObstacleClass(MapObjectID
}
}
ObstacleSet::EObstacleType ObstacleSet::typeFromString(const std::string &str)
{
static const std::map<std::string, EObstacleType> OBSTACLE_TYPE_NAMES =
{
{"mountain", MOUNTAINS},
{"tree", TREES},
{"lake", LAKES},
{"crater", CRATERS},
{"rock", ROCKS},
{"plant", PLANTS},
{"structure", STRUCTURES},
{"animal", ANIMALS},
{"other", OTHER}
};
if (OBSTACLE_TYPE_NAMES.find(str) != OBSTACLE_TYPE_NAMES.end())
{
return OBSTACLE_TYPE_NAMES.at(str);
}
// TODO: How to handle that?
throw std::runtime_error("Invalid obstacle type: " + str);
}
std::vector<ObstacleSet::EObstacleType> ObstacleSetFilter::getAllowedTypes() const
{
return allowedTypes;
@ -149,5 +173,24 @@ TObstacleTypes ObstacleSetHandler::getObstacles( const ObstacleSetFilter &filter
return result;
}
/*
ObstacleSet ObstacleSetHandler::loadObject(std::string scope, std::string name, const JsonNode & data)
{
// TODO: Merge by name with existing obstacle sets?
const JsonNode & biome = json["biome"];
auto objectType = ObstacleSet::typeFromString(biome["objectType"].String());
for (const JsonNode & type : data["types"])
{
for (const JsonNode & obstacle : type["templates"])
{
// TODO: Reuse templates (pointers) parsed by CObjectClassesHandler
}
}
}
*/
VCMI_LIB_NAMESPACE_END

View File

@ -26,7 +26,8 @@ public:
enum EObstacleType
{
MOUNTAINS,
INVALID = -1,
MOUNTAINS = 0,
TREES,
LAKES, // Inluding dry or lava lakes
CRATERS, // Chasms, Canyons, etc.
@ -36,7 +37,6 @@ public:
ANIMALS, // Living, or bones
OTHER // Crystals, shipwrecks, barrels, etc.
};
explicit ObstacleSet(EObstacleType type, TerrainId terrain);
void addObstacle(std::shared_ptr<const ObjectTemplate> obstacle);
@ -45,6 +45,8 @@ public:
EObstacleType getType() const;
TerrainId getTerrain() const;
static EObstacleType typeFromString(const std::string &str);
private:
EObstacleType type;
TerrainId terrain;

View File

@ -177,7 +177,10 @@ bool ObstacleProxy::prepareBiome(TerrainId terrain, CRandomGenerator & rand)
// Copy this set to our possible obstacles
if (selectedSets >= MINIMUM_SETS)
// if (selectedSets >= MINIMUM_SETS)
if (selectedSets >= MINIMUM_SETS ||
(terrain == TerrainId::WATER && selectedSets > 0))
{
obstaclesBySize.clear();
for (const auto & os : obstacleSets)
@ -200,7 +203,7 @@ bool ObstacleProxy::prepareBiome(TerrainId terrain, CRandomGenerator & rand)
{
return p1.first > p2.first; //bigger obstacles first
});
return true;
}
else