mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Proof of concept with OH3 obstacles
This commit is contained in:
parent
c2f160326c
commit
b1a5693612
@ -121,6 +121,7 @@ set(lib_MAIN_SRCS
|
||||
mapObjects/IObjectInterface.cpp
|
||||
mapObjects/MiscObjects.cpp
|
||||
mapObjects/ObjectTemplate.cpp
|
||||
mapObjects/ObstacleSetHandler.cpp
|
||||
|
||||
mapping/CDrawRoadsOperation.cpp
|
||||
mapping/CMap.cpp
|
||||
@ -482,6 +483,7 @@ set(lib_MAIN_HEADERS
|
||||
mapObjects/MapObjects.h
|
||||
mapObjects/MiscObjects.h
|
||||
mapObjects/ObjectTemplate.h
|
||||
mapObjects/ObstacleSetHandler.h
|
||||
|
||||
mapping/CDrawRoadsOperation.h
|
||||
mapping/CMapDefines.h
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "rmg/CRmgTemplateStorage.h"
|
||||
#include "mapObjectConstructors/CObjectClassesHandler.h"
|
||||
#include "mapObjects/CObjectHandler.h"
|
||||
#include "mapObjects/ObstacleSetHandler.h"
|
||||
#include "mapping/CMapEditManager.h"
|
||||
#include "ScriptHandler.h"
|
||||
#include "BattleFieldHandler.h"
|
||||
@ -223,6 +224,7 @@ void LibClasses::init(bool onlyEssential)
|
||||
createHandler(arth, "Artifact", pomtime);
|
||||
createHandler(creh, "Creature", pomtime);
|
||||
createHandler(townh, "Town", pomtime);
|
||||
createHandler(biomeHandler, "Obstacle set", pomtime);
|
||||
createHandler(objh, "Object", pomtime);
|
||||
createHandler(objtypeh, "Object types information", pomtime);
|
||||
createHandler(spellh, "Spell", pomtime);
|
||||
|
@ -23,6 +23,7 @@ class CSkillHandler;
|
||||
class CBuildingHandler;
|
||||
class CObjectHandler;
|
||||
class CObjectClassesHandler;
|
||||
class ObstacleSetHandler;
|
||||
class CTownHandler;
|
||||
class CGeneralTextHandler;
|
||||
class CModHandler;
|
||||
@ -85,6 +86,7 @@ public:
|
||||
std::shared_ptr<CCreatureHandler> creh;
|
||||
std::shared_ptr<CSpellHandler> spellh;
|
||||
std::shared_ptr<CSkillHandler> skillh;
|
||||
// TODO: Remove ObjectHandler altogether?
|
||||
std::shared_ptr<CObjectHandler> objh;
|
||||
std::shared_ptr<CObjectClassesHandler> objtypeh;
|
||||
std::shared_ptr<CTownHandler> townh;
|
||||
@ -99,6 +101,7 @@ public:
|
||||
std::shared_ptr<BattleFieldHandler> battlefieldsHandler;
|
||||
std::shared_ptr<ObstacleHandler> obstacleHandler;
|
||||
std::shared_ptr<GameSettings> settingsHandler;
|
||||
std::shared_ptr<ObstacleSetHandler> biomeHandler;
|
||||
|
||||
#if SCRIPTING_ENABLED
|
||||
std::shared_ptr<scripting::ScriptHandler> scriptHandler;
|
||||
|
@ -457,7 +457,46 @@ public:
|
||||
WHIRLPOOL = 111,
|
||||
WINDMILL = 112,
|
||||
WITCH_HUT = 113,
|
||||
BRUSH = 114, // TODO: How does it look like?
|
||||
BUSH = 115,
|
||||
CACTUS = 116,
|
||||
CANYON = 117,
|
||||
CRATER = 118,
|
||||
DEAD_VEGETATION = 119,
|
||||
FLOWERS = 120,
|
||||
FROZEN_LAKE = 121,
|
||||
HEDGE = 122,
|
||||
HILL = 123,
|
||||
HOLE = 124,
|
||||
KELP = 125,
|
||||
LAKE = 126,
|
||||
LAVA_FLOW = 127,
|
||||
LAVA_LAKE = 128,
|
||||
MUSHROOMS = 129,
|
||||
LOG = 130,
|
||||
MANDRAKE = 131,
|
||||
MOSS = 132,
|
||||
MOUND = 133,
|
||||
MOUNTAIN = 134,
|
||||
OAK_TREES = 135,
|
||||
OUTCROPPING = 136,
|
||||
PINE_TREES = 137,
|
||||
PLANT = 138,
|
||||
ROCK = 147,
|
||||
SAND_DUNE = 148,
|
||||
SAND_PIT = 149,
|
||||
SHRUB = 150,
|
||||
SKULL = 151,
|
||||
STALAGMITE = 152,
|
||||
STUMP = 153,
|
||||
TAR_PIT = 154,
|
||||
TREES = 155,
|
||||
VINE = 156,
|
||||
VOLCANIC_VENT = 157,
|
||||
VOLCANO = 158,
|
||||
WILLOW_TREES = 159,
|
||||
YUCCA_TREES = 160,
|
||||
REEF = 161,
|
||||
RANDOM_MONSTER_L5 = 162,
|
||||
RANDOM_MONSTER_L6 = 163,
|
||||
RANDOM_MONSTER_L7 = 164,
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "../mapObjects/MiscObjects.h"
|
||||
#include "../mapObjects/CGHeroInstance.h"
|
||||
#include "../mapObjects/CGTownInstance.h"
|
||||
#include "../mapObjects/ObstacleSetHandler.h"
|
||||
#include "../modding/IdentifierStorage.h"
|
||||
#include "../modding/CModHandler.h"
|
||||
#include "../modding/ModScope.h"
|
||||
@ -107,6 +108,8 @@ std::vector<JsonNode> CObjectClassesHandler::loadLegacyData()
|
||||
auto totalNumber = static_cast<size_t>(parser.readNumber()); // first line contains number of objects to read and nothing else
|
||||
parser.endLine();
|
||||
|
||||
std::map<TerrainId, std::map<MapObjectID, std::map<MapObjectSubID, ObstacleSet>>> obstacleSets;
|
||||
|
||||
for (size_t i = 0; i < totalNumber; i++)
|
||||
{
|
||||
auto tmpl = std::make_shared<ObjectTemplate>();
|
||||
@ -116,8 +119,45 @@ std::vector<JsonNode> CObjectClassesHandler::loadLegacyData()
|
||||
|
||||
std::pair key(tmpl->id, tmpl->subid);
|
||||
legacyTemplates.insert(std::make_pair(key, tmpl));
|
||||
|
||||
// Populate ObstacleSetHandler on our way
|
||||
if (!tmpl->isVisitable())
|
||||
{
|
||||
// Create obstacle sets. Group by terrain for now
|
||||
|
||||
for (auto terrain : tmpl->getAllowedTerrains())
|
||||
{
|
||||
auto &obstacleMap = obstacleSets[terrain][tmpl->id];
|
||||
auto it = obstacleMap.find(tmpl->subid);
|
||||
if (it == obstacleMap.end())
|
||||
{
|
||||
// FIXME: This means this set will be available only on one terrain
|
||||
auto type = VLC->biomeHandler->convertObstacleClass(tmpl->id);
|
||||
auto newIt = obstacleMap.insert(std::make_pair(tmpl->subid, ObstacleSet(type, terrain)));
|
||||
newIt.first->second.addObstacle(tmpl);
|
||||
}
|
||||
else
|
||||
{
|
||||
it->second.addObstacle(tmpl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t count = 0;
|
||||
for (auto terrain : obstacleSets)
|
||||
{
|
||||
for (auto obstacleType : terrain.second)
|
||||
{
|
||||
for (auto obstacleSet : obstacleType.second)
|
||||
{
|
||||
VLC->biomeHandler->addObstacleSet(obstacleSet.second);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
logGlobal->info("Obstacle sets loaded: %d", count);
|
||||
|
||||
objects.resize(256);
|
||||
|
||||
std::vector<JsonNode> ret(dataSize);// create storage for 256 objects
|
||||
|
153
lib/mapObjects/ObstacleSetHandler.cpp
Normal file
153
lib/mapObjects/ObstacleSetHandler.cpp
Normal file
@ -0,0 +1,153 @@
|
||||
/*
|
||||
* ObstacleSetHandler.cpp, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
|
||||
#include "StdInc.h"
|
||||
#include "ObstacleSetHandler.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
ObstacleSet::ObstacleSet(EObstacleType type, TerrainId terrain):
|
||||
type(type),
|
||||
terrain(terrain)
|
||||
{
|
||||
}
|
||||
|
||||
void ObstacleSet::addObstacle(std::shared_ptr<const ObjectTemplate> obstacle)
|
||||
{
|
||||
obstacles.push_back(obstacle);
|
||||
}
|
||||
|
||||
ObstacleSetFilter::ObstacleSetFilter(std::vector<ObstacleSet::EObstacleType> allowedTypes, TerrainId terrain = TerrainId::ANY_TERRAIN):
|
||||
allowedTypes(allowedTypes),
|
||||
terrain(terrain)
|
||||
{
|
||||
}
|
||||
|
||||
ObstacleSetFilter::ObstacleSetFilter(ObstacleSet::EObstacleType allowedType, TerrainId terrain = TerrainId::ANY_TERRAIN):
|
||||
allowedTypes({allowedType}),
|
||||
terrain(terrain)
|
||||
{
|
||||
}
|
||||
|
||||
bool ObstacleSetFilter::filter(const ObstacleSet &set) const
|
||||
{
|
||||
return (set.getTerrain() == terrain) || (terrain == TerrainId::ANY_TERRAIN);
|
||||
}
|
||||
|
||||
TerrainId ObstacleSetFilter::getTerrain() const
|
||||
{
|
||||
return terrain;
|
||||
}
|
||||
|
||||
TerrainId ObstacleSet::getTerrain() const
|
||||
{
|
||||
return terrain;
|
||||
}
|
||||
|
||||
ObstacleSet::EObstacleType ObstacleSet::getType() const
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<const ObjectTemplate>> ObstacleSet::getObstacles() const
|
||||
{
|
||||
return obstacles;
|
||||
}
|
||||
|
||||
ObstacleSet::EObstacleType ObstacleSetHandler::convertObstacleClass(MapObjectID id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case Obj::MOUNTAIN:
|
||||
case Obj::SAND_DUNE:
|
||||
case Obj::VOLCANIC_VENT:
|
||||
case Obj::VOLCANO:
|
||||
case Obj::REEF:
|
||||
return ObstacleSet::MOUNTAINS;
|
||||
case Obj::OAK_TREES:
|
||||
case Obj::PINE_TREES:
|
||||
case Obj::TREES:
|
||||
case Obj::DEAD_VEGETATION:
|
||||
case Obj::HEDGE:
|
||||
case Obj::KELP:
|
||||
case Obj::WILLOW_TREES:
|
||||
case Obj::YUCCA_TREES:
|
||||
return ObstacleSet::TREES;
|
||||
case Obj::FROZEN_LAKE:
|
||||
case Obj::LAKE:
|
||||
case Obj::LAVA_FLOW:
|
||||
case Obj::LAVA_LAKE:
|
||||
return ObstacleSet::LAKES;
|
||||
case Obj::CANYON:
|
||||
case Obj::CRATER:
|
||||
case Obj::SAND_PIT:
|
||||
case Obj::TAR_PIT:
|
||||
return ObstacleSet::CRATERS;
|
||||
case Obj::HILL:
|
||||
case Obj::MOUND:
|
||||
case Obj::OUTCROPPING:
|
||||
case Obj::ROCK:
|
||||
case Obj::STALAGMITE:
|
||||
return ObstacleSet::ROCKS;
|
||||
case Obj::BUSH:
|
||||
case Obj::CACTUS:
|
||||
case Obj::FLOWERS:
|
||||
case Obj::MUSHROOMS:
|
||||
case Obj::LOG:
|
||||
case Obj::MANDRAKE:
|
||||
case Obj::MOSS:
|
||||
case Obj::PLANT:
|
||||
case Obj::SHRUB:
|
||||
case Obj::STUMP:
|
||||
case Obj::VINE:
|
||||
return ObstacleSet::PLANTS;
|
||||
case Obj::SKULL:
|
||||
return ObstacleSet::ANIMALS;
|
||||
default:
|
||||
return ObstacleSet::OTHER;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<ObstacleSet::EObstacleType> ObstacleSetFilter::getAllowedTypes() const
|
||||
{
|
||||
return allowedTypes;
|
||||
}
|
||||
|
||||
void ObstacleSetHandler::addObstacleSet(const ObstacleSet &os)
|
||||
{
|
||||
obstacleSets[os.getType()].push_back(os);
|
||||
}
|
||||
|
||||
TObstacleTypes ObstacleSetHandler::getObstacles( const ObstacleSetFilter &filter) const
|
||||
{
|
||||
// TODO: Handle multiple terrains for one obstacle set?
|
||||
auto terrainType = filter.getTerrain();
|
||||
|
||||
TObstacleTypes result;
|
||||
|
||||
for (const auto &allowedType : filter.getAllowedTypes())
|
||||
{
|
||||
auto it = obstacleSets.find(allowedType);
|
||||
if(it != obstacleSets.end())
|
||||
{
|
||||
for (const auto &os : it->second)
|
||||
{
|
||||
if (filter.filter(os))
|
||||
{
|
||||
result.push_back(os);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
99
lib/mapObjects/ObstacleSetHandler.h
Normal file
99
lib/mapObjects/ObstacleSetHandler.h
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* ObstacleSetHandler.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../GameConstants.h"
|
||||
#include "../constants/EntityIdentifiers.h"
|
||||
#include "../IHandlerBase.h"
|
||||
#include "../json/JsonNode.h"
|
||||
#include "ObjectTemplate.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class DLL_LINKAGE ObstacleSet
|
||||
{
|
||||
public:
|
||||
|
||||
// TODO: Create string constants for these
|
||||
|
||||
enum EObstacleType
|
||||
{
|
||||
MOUNTAINS,
|
||||
TREES,
|
||||
LAKES, // Inluding dry or lava lakes
|
||||
CRATERS, // Chasms, Canyons, etc.
|
||||
ROCKS,
|
||||
PLANTS, // Flowers, cacti, mushrooms, logs, shrubs, etc.
|
||||
STRUCTURES, // Buildings, ruins, etc.
|
||||
ANIMALS, // Living, or bones
|
||||
OTHER // Crystals, shipwrecks, barrels, etc.
|
||||
};
|
||||
|
||||
explicit ObstacleSet(EObstacleType type, TerrainId terrain);
|
||||
|
||||
void addObstacle(std::shared_ptr<const ObjectTemplate> obstacle);
|
||||
std::vector<std::shared_ptr<const ObjectTemplate>> getObstacles() const;
|
||||
|
||||
EObstacleType getType() const;
|
||||
TerrainId getTerrain() const;
|
||||
|
||||
private:
|
||||
EObstacleType type;
|
||||
TerrainId terrain;
|
||||
std::vector<std::shared_ptr<const ObjectTemplate>> obstacles;
|
||||
};
|
||||
|
||||
typedef std::vector<ObstacleSet> TObstacleTypes;
|
||||
|
||||
class DLL_LINKAGE ObstacleSetFilter
|
||||
{
|
||||
public:
|
||||
ObstacleSetFilter(ObstacleSet::EObstacleType allowedType, TerrainId terrain);
|
||||
ObstacleSetFilter(std::vector<ObstacleSet::EObstacleType> allowedTypes, TerrainId terrain);
|
||||
|
||||
bool filter(const ObstacleSet &set) const;
|
||||
|
||||
std::vector<ObstacleSet::EObstacleType> getAllowedTypes() const;
|
||||
TerrainId getTerrain() const;
|
||||
|
||||
private:
|
||||
std::vector<ObstacleSet::EObstacleType> allowedTypes;
|
||||
// TODO: Filter by faction, alignment, surface/underground, etc.
|
||||
const TerrainId terrain;
|
||||
};
|
||||
|
||||
// TODO: Instantiate ObstacleSetHandler
|
||||
class DLL_LINKAGE ObstacleSetHandler : public IHandlerBase, boost::noncopyable
|
||||
{
|
||||
public:
|
||||
|
||||
ObstacleSetHandler() = default;
|
||||
~ObstacleSetHandler() = default;
|
||||
|
||||
// FIXME: Not needed at all
|
||||
std::vector<JsonNode> loadLegacyData() override {return {};};
|
||||
virtual void loadObject(std::string scope, std::string name, const JsonNode & data) override {};
|
||||
virtual void loadObject(std::string scope, std::string name, const JsonNode & data, size_t index) override {};
|
||||
|
||||
ObstacleSet::EObstacleType convertObstacleClass(MapObjectID id);
|
||||
|
||||
// TODO: Populate obstacleSets with all the obstacle sets from the game data
|
||||
|
||||
void addObstacleSet(const ObstacleSet &set);
|
||||
|
||||
TObstacleTypes getObstacles(const ObstacleSetFilter &filter) const;
|
||||
|
||||
private:
|
||||
|
||||
std::map<ObstacleSet::EObstacleType, std::vector<ObstacleSet>> obstacleSets;
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
@ -15,6 +15,7 @@
|
||||
#include "../mapObjectConstructors/CObjectClassesHandler.h"
|
||||
#include "../mapObjects/CGObjectInstance.h"
|
||||
#include "../mapObjects/ObjectTemplate.h"
|
||||
#include "../mapObjects/ObstacleSetHandler.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
@ -46,6 +47,170 @@ void ObstacleProxy::collectPossibleObstacles(TerrainId terrain)
|
||||
});
|
||||
}
|
||||
|
||||
bool ObstacleProxy::prepareBiome(TerrainId terrain, CRandomGenerator & rand)
|
||||
{
|
||||
// FIXME: All the mountains have same ID and mostly same subID, how to differentiate them?
|
||||
|
||||
bool isPrepared = false;
|
||||
|
||||
possibleObstacles.clear();
|
||||
|
||||
// TODO: Where to parse these sets?
|
||||
|
||||
std::vector<ObstacleSet> obstacleSets;
|
||||
|
||||
size_t selectedSets = 0;
|
||||
size_t smallSets = 0;
|
||||
const size_t MINIMUM_SETS = 6;
|
||||
const size_t MAXIMUM_SETS = 9;
|
||||
const size_t MIN_SMALL_SETS = 3;
|
||||
const size_t MAX_SMALL_SETS = 5;
|
||||
|
||||
TObstacleTypes mountainSets = VLC->biomeHandler->getObstacles(ObstacleSetFilter(ObstacleSet::EObstacleType::MOUNTAINS, terrain));
|
||||
|
||||
if (!mountainSets.empty())
|
||||
{
|
||||
obstacleSets.push_back(*RandomGeneratorUtil::nextItem(mountainSets, rand));
|
||||
selectedSets++;
|
||||
logGlobal->info("Mountain set added");
|
||||
}
|
||||
else
|
||||
{
|
||||
logGlobal->warn("No mountain sets found for terrain %s", terrain.encode(terrain.getNum()));
|
||||
// FIXME: Do we ever want to generate obstacles without any mountains?
|
||||
}
|
||||
|
||||
TObstacleTypes treeSets = VLC->biomeHandler->getObstacles(ObstacleSetFilter(ObstacleSet::EObstacleType::TREES, terrain));
|
||||
|
||||
// 1 or 2 tree sets
|
||||
size_t treeSetsCount = std::min<size_t>(treeSets.size(), rand.nextInt(1, 2));
|
||||
for (size_t i = 0; i < treeSetsCount; i++)
|
||||
{
|
||||
obstacleSets.push_back(*RandomGeneratorUtil::nextItem(treeSets, rand));
|
||||
selectedSets++;
|
||||
}
|
||||
logGlobal->info("Added %d tree sets", treeSetsCount);
|
||||
|
||||
// Some obstacle types may be completely missing from water, but it's not a problem
|
||||
TObstacleTypes largeSets = VLC->biomeHandler->getObstacles(ObstacleSetFilter({ObstacleSet::EObstacleType::LAKES, ObstacleSet::EObstacleType::CRATERS},
|
||||
terrain));
|
||||
|
||||
// We probably don't want to have lakes and craters at the same time, choose one of them
|
||||
|
||||
if (!largeSets.empty())
|
||||
{
|
||||
obstacleSets.push_back(*RandomGeneratorUtil::nextItem(largeSets, rand));
|
||||
selectedSets++;
|
||||
|
||||
// TODO: Convert to string
|
||||
logGlobal->info("Added large set of type %s", obstacleSets.back().getType());
|
||||
}
|
||||
|
||||
TObstacleTypes rockSets = VLC->biomeHandler->getObstacles(ObstacleSetFilter(ObstacleSet::EObstacleType::ROCKS, terrain));
|
||||
|
||||
size_t rockSetsCount = std::min<size_t>(rockSets.size(), rand.nextInt(1, 2));
|
||||
for (size_t i = 0; i < rockSetsCount; i++)
|
||||
{
|
||||
obstacleSets.push_back(*RandomGeneratorUtil::nextItem(rockSets, rand));
|
||||
selectedSets++;
|
||||
}
|
||||
logGlobal->info("Added %d rock sets", rockSetsCount);
|
||||
|
||||
TObstacleTypes plantSets = VLC->biomeHandler->getObstacles(ObstacleSetFilter(ObstacleSet::EObstacleType::PLANTS, terrain));
|
||||
|
||||
// 1 or 2 sets (3 - rock sets)
|
||||
size_t plantSetsCount = std::min<size_t>(plantSets.size(), rand.nextInt(1, std::max<size_t>(3 - rockSetsCount, 2)));
|
||||
for (size_t i = 0; i < plantSetsCount; i++)
|
||||
{
|
||||
{
|
||||
obstacleSets.push_back(*RandomGeneratorUtil::nextItem(plantSets, rand));
|
||||
selectedSets++;
|
||||
}
|
||||
}
|
||||
logGlobal->info("Added %d plant sets", plantSetsCount);
|
||||
|
||||
//3 to 5 of total small sets (rocks, plants, structures, animals and others)
|
||||
//This gives total of 6 to 9 different sets
|
||||
|
||||
size_t maxSmallSets = std::min<size_t>(MAX_SMALL_SETS, std::max(MIN_SMALL_SETS, MAXIMUM_SETS - selectedSets));
|
||||
|
||||
size_t smallSetsCount = rand.nextInt(MIN_SMALL_SETS, maxSmallSets);
|
||||
|
||||
TObstacleTypes smallObstacleSets = VLC->biomeHandler->getObstacles(ObstacleSetFilter({ObstacleSet::EObstacleType::STRUCTURES, ObstacleSet::EObstacleType::ANIMALS},
|
||||
terrain));
|
||||
RandomGeneratorUtil::randomShuffle(smallObstacleSets, rand);
|
||||
|
||||
TObstacleTypes otherSets = VLC->biomeHandler->getObstacles(ObstacleSetFilter(ObstacleSet::EObstacleType::OTHER,
|
||||
terrain));
|
||||
RandomGeneratorUtil::randomShuffle(otherSets, rand);
|
||||
|
||||
while (smallSetsCount > 0)
|
||||
{
|
||||
if (!smallObstacleSets.empty())
|
||||
{
|
||||
obstacleSets.push_back(smallObstacleSets.back());
|
||||
smallObstacleSets.pop_back();
|
||||
selectedSets++;
|
||||
smallSetsCount--;
|
||||
logGlobal->info("Added small set of type %s", obstacleSets.back().getType());
|
||||
}
|
||||
else if(otherSets.empty())
|
||||
{
|
||||
logGlobal->warn("No other sets found for terrain %s", terrain.encode(terrain.getNum()));
|
||||
break;
|
||||
}
|
||||
|
||||
if (smallSetsCount > 0)
|
||||
{
|
||||
// Fill with whatever's left
|
||||
if (!otherSets.empty())
|
||||
{
|
||||
obstacleSets.push_back(otherSets.back());
|
||||
otherSets.pop_back();
|
||||
selectedSets++;
|
||||
smallSetsCount--;
|
||||
|
||||
logGlobal->info("Added set of other obstacles");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Copy this set to our possible obstacles
|
||||
|
||||
if (selectedSets >= MINIMUM_SETS)
|
||||
{
|
||||
obstaclesBySize.clear();
|
||||
for (const auto & os : obstacleSets)
|
||||
{
|
||||
for (const auto & temp : os.getObstacles())
|
||||
{
|
||||
if(temp->getBlockMapOffset().valid())
|
||||
{
|
||||
obstaclesBySize[temp->getBlockedOffsets().size()].push_back(temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(const auto & o : obstaclesBySize)
|
||||
{
|
||||
possibleObstacles.emplace_back(o);
|
||||
}
|
||||
|
||||
boost::sort(possibleObstacles, [](const ObstaclePair &p1, const ObstaclePair &p2) -> bool
|
||||
{
|
||||
return p1.first > p2.first; //bigger obstacles first
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false; // Proceed with old method
|
||||
}
|
||||
|
||||
return isPrepared;
|
||||
}
|
||||
|
||||
void ObstacleProxy::addBlockedTile(const int3& tile)
|
||||
{
|
||||
blockedArea.add(tile);
|
||||
|
@ -29,6 +29,7 @@ public:
|
||||
virtual ~ObstacleProxy() = default;
|
||||
|
||||
void collectPossibleObstacles(TerrainId terrain);
|
||||
bool prepareBiome(TerrainId terrain, CRandomGenerator & rand);
|
||||
|
||||
void addBlockedTile(const int3 & tile);
|
||||
|
||||
|
@ -34,7 +34,16 @@ void ObstaclePlacer::process()
|
||||
if(!manager)
|
||||
return;
|
||||
|
||||
collectPossibleObstacles(zone.getTerrainType());
|
||||
if (!prepareBiome(zone.getTerrainType(), zone.getRand()))
|
||||
{
|
||||
logGlobal->warn("Failed to prepare biome, using all possible obstacles");
|
||||
// Use all if we fail to create proper biome
|
||||
collectPossibleObstacles(zone.getTerrainType());
|
||||
}
|
||||
else
|
||||
{
|
||||
logGlobal->info("Biome prepared successfully for zone %d", zone.getId());
|
||||
}
|
||||
|
||||
{
|
||||
auto area = zone.area();
|
||||
|
Loading…
Reference in New Issue
Block a user