1
0

Added basic support for loading village prefabs from files.

This commit is contained in:
Mattes D 2015-06-20 15:37:41 +02:00
parent 33d68572a6
commit e06dd8f20e
24 changed files with 18038 additions and 17250 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -835,8 +835,12 @@ bool cLuaState::GetStackValue(int a_StackPos, float & a_ReturnedVal)
cLuaState::cStackValue cLuaState::WalkToValue(const AString & a_Name)
{
auto path = StringSplit(a_Name, ".");
// There needs to be at least one value on the stack:
ASSERT(lua_gettop(m_LuaState) > 0);
// Iterate over path and replace the top of the stack with the walked element
lua_pushvalue(m_LuaState, -1); // Copy the stack value into the "working area"
auto path = StringSplit(a_Name, ".");
for (const auto & elem: path)
{
// If the value is not a table, bail out (error):

View File

@ -104,6 +104,28 @@ enum EMCSBiome
biMaxVariantBiome = biNumVariantBiomes - 1, // The maximum biome value
} ;
// tolua_end
/** Hash for EMCSBiome, so that it can be used in std::unordered_map etc. */
struct BiomeHasher
{
public:
std::size_t operator() (const EMCSBiome a_Biome) const
{
return static_cast<std::size_t>(a_Biome);
}
};
// tolua_begin
/** Translates a biome string to biome enum. Takes either a number or a biome alias (built-in). Returns biInvalidBiome on failure. */
extern EMCSBiome StringToBiome(const AString & a_BiomeString);

View File

@ -618,7 +618,9 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile)
int MaxSize = a_IniFile.GetValueSetI("Generator", "VillageMaxSize", 128);
int MinDensity = a_IniFile.GetValueSetI("Generator", "VillageMinDensity", 50);
int MaxDensity = a_IniFile.GetValueSetI("Generator", "VillageMaxDensity", 80);
m_FinishGens.push_back(std::make_shared<cVillageGen>(Seed, GridSize, MaxOffset, MaxDepth, MaxSize, MinDensity, MaxDensity, m_BiomeGen, m_CompositedHeightCache));
AString PrefabList = a_IniFile.GetValueSet("Generator", "VillagePrefabs", "PlainsVillage, SandVillage");
auto Prefabs = StringSplitAndTrim(PrefabList, ",");
m_FinishGens.push_back(std::make_shared<cVillageGen>(Seed, GridSize, MaxOffset, MaxDepth, MaxSize, MinDensity, MaxDensity, m_BiomeGen, m_CompositedHeightCache, Prefabs));
}
else if (NoCaseCompare(*itr, "Vines") == 0)
{

View File

@ -215,6 +215,9 @@ void cPrefabPiecePool::AddToPerConnectorMap(cPrefab * a_Prefab)
bool cPrefabPiecePool::LoadFromCubesetFileVer1(const AString & a_FileName, cLuaState & a_LuaState, bool a_LogWarnings)
{
// Load the metadata:
ApplyPoolMetadataCubesetVer1(a_FileName, a_LuaState, a_LogWarnings);
// Push the Cubeset.Pieces global value on the stack:
lua_getglobal(a_LuaState, "_G");
cLuaState::cStackValue stk(a_LuaState);
@ -297,7 +300,7 @@ bool cPrefabPiecePool::LoadCubesetPieceVer1(const AString & a_FileName, cLuaStat
prefab->SetAllowedRotations(AllowedRotations);
// Apply the relevant metadata:
if (!ApplyMetadataCubesetVer1(a_FileName, a_LuaState, PieceName, prefab.get(), a_LogWarnings))
if (!ApplyPieceMetadataCubesetVer1(a_FileName, a_LuaState, PieceName, prefab.get(), a_LogWarnings))
{
return false;
}
@ -461,7 +464,7 @@ bool cPrefabPiecePool::ReadConnectorsCubesetVer1(
bool cPrefabPiecePool::ApplyMetadataCubesetVer1(
bool cPrefabPiecePool::ApplyPieceMetadataCubesetVer1(
const AString & a_FileName,
cLuaState & a_LuaState,
const AString & a_PieceName,
@ -499,6 +502,10 @@ bool cPrefabPiecePool::ApplyMetadataCubesetVer1(
);
a_Prefab->SetMergeStrategy(cBlockArea::msSpongePrint);
}
else
{
a_Prefab->SetMergeStrategy(strategy->second);
}
a_Prefab->SetMoveToGround(MoveToGround != 0);
a_Prefab->SetExtendFloor(ShouldExpandFloor != 0);
@ -509,6 +516,73 @@ bool cPrefabPiecePool::ApplyMetadataCubesetVer1(
bool cPrefabPiecePool::ApplyPoolMetadataCubesetVer1(
const AString & a_FileName,
cLuaState & a_LuaState,
bool a_LogWarnings
)
{
// Push the Cubeset.Metadata table on top of the Lua stack:
lua_getglobal(a_LuaState, "_G");
auto md = a_LuaState.WalkToValue("Cubeset.Metadata");
if (!md.IsValid())
{
CONDWARNING(a_LogWarnings, "Cannot load cubeset from file %s: Cubeset.Metadata table is missing", a_FileName.c_str());
return false;
}
// Set the metadata values to defaults:
m_MinDensity = 100;
m_MaxDensity = 100;
m_VillageRoadBlockType = E_BLOCK_GRAVEL;
m_VillageRoadBlockMeta = 0;
m_VillageWaterRoadBlockType = E_BLOCK_PLANKS;
m_VillageWaterRoadBlockMeta = 0;
// Read the metadata values:
a_LuaState.GetNamedValue("IntendedUse", m_IntendedUse);
a_LuaState.GetNamedValue("MaxDensity", m_MaxDensity);
a_LuaState.GetNamedValue("MinDensity", m_MinDensity);
a_LuaState.GetNamedValue("VillageRoadBlockType", m_VillageRoadBlockType);
a_LuaState.GetNamedValue("VillageRoadBlockMeta", m_VillageRoadBlockMeta);
a_LuaState.GetNamedValue("VillageWaterRoadBlockType", m_VillageWaterRoadBlockType);
a_LuaState.GetNamedValue("VillageWaterRoadBlockMeta", m_VillageWaterRoadBlockMeta);
AString allowedBiomes;
if (a_LuaState.GetNamedValue("AllowedBiomes", allowedBiomes))
{
auto biomes = StringSplitAndTrim(allowedBiomes, ",");
for (const auto & biome: biomes)
{
EMCSBiome b = StringToBiome(biome);
if (b == biInvalidBiome)
{
CONDWARNING(a_LogWarnings, "Invalid biome (\"%s\") specified in AllowedBiomes in cubeset file %s. Skipping the biome.",
biome.c_str(), a_FileName.c_str()
);
continue;
}
m_AllowedBiomes.insert(b);
}
}
else
{
// All biomes are allowed:
for (int b = biFirstBiome; b <= biMaxBiome; b++)
{
m_AllowedBiomes.insert(static_cast<EMCSBiome>(b));
}
for (int b = biFirstVariantBiome; b <= biMaxVariantBiome; b++)
{
m_AllowedBiomes.insert(static_cast<EMCSBiome>(b));
}
}
return true;
}
cPieces cPrefabPiecePool::GetPiecesWithConnector(int a_ConnectorType)
{
return m_PiecesByConnector[a_ConnectorType];

View File

@ -9,6 +9,7 @@
#pragma once
#include <unordered_set>
#include "PieceGenerator.h"
#include "Prefab.h"
@ -75,6 +76,26 @@ public:
/** Returns the number of starting pieces. */
size_t GetStartingPiecesCount(void) const { return m_StartingPieces.size(); }
// Metadata accessors:
const AString & GetIntendedUse(void) const { return m_IntendedUse; }
int GetMinDensity(void) const { return m_MinDensity; }
int GetMaxDensity(void) const { return m_MaxDensity; }
BLOCKTYPE GetVillageRoadBlockType (void) const { return m_VillageRoadBlockType; }
NIBBLETYPE GetVillageRoadBlockMeta (void) const { return m_VillageRoadBlockMeta; }
BLOCKTYPE GetVillageWaterRoadBlockType(void) const { return m_VillageWaterRoadBlockType; }
NIBBLETYPE GetVillageWaterRoadBlockMeta(void) const { return m_VillageWaterRoadBlockMeta; }
/** Returns true if a_Biome is among the accepted biomes in the m_AcceptedBiomes metadata member. */
bool IsBiomeAllowed(EMCSBiome a_Biome) const { return (m_AllowedBiomes.find(a_Biome) != m_AllowedBiomes.end()); }
// cPiecePool overrides:
virtual cPieces GetPiecesWithConnector(int a_ConnectorType) override;
virtual cPieces GetStartingPieces(void) override;
virtual int GetPieceWeight(const cPlacedPiece & a_PlacedPiece, const cPiece::cConnector & a_ExistingConnector, const cPiece & a_NewPiece) override;
virtual int GetStartingPieceWeight(const cPiece & a_NewPiece) override;
virtual void PiecePlaced(const cPiece & a_Piece) override;
virtual void Reset(void) override;
protected:
/** The type used to map a connector type to the list of pieces with that connector */
@ -92,6 +113,30 @@ protected:
The pieces are copies out of m_AllPieces and shouldn't be ever delete-d. */
cPiecesMap m_PiecesByConnector;
/** The intended use of this piece pool, as specified by the pool's metadata. */
AString m_IntendedUse;
/** The minimum density, as read from the metadata. */
int m_MinDensity;
/** The maximum density, as read from the metadata. */
int m_MaxDensity;
/** The block type to use for the village roads. */
BLOCKTYPE m_VillageRoadBlockType;
/** The block meta to use for the village roads. */
NIBBLETYPE m_VillageRoadBlockMeta;
/** The block type used for the village roads if the road is on water. */
BLOCKTYPE m_VillageWaterRoadBlockType;
/** The block meta used for the village roads if the road is on water. */
NIBBLETYPE m_VillageWaterRoadBlockMeta;
/** A set of allowed biomes for the pool. The pool will only be used within the specified biomes. */
std::unordered_set<EMCSBiome, BiomeHasher> m_AllowedBiomes;
/** Adds the prefab to the m_PiecesByConnector map for all its connectors. */
void AddToPerConnectorMap(cPrefab * a_Prefab);
@ -142,7 +187,7 @@ protected:
The metadata is applied into the a_Prefab object.
a_PieceName is the identification of the piece, used for logging only.
If a_LogWarnings is true, logs a warning to console when loading fails. */
bool ApplyMetadataCubesetVer1(
bool ApplyPieceMetadataCubesetVer1(
const AString & a_FileName,
cLuaState & a_LuaState,
const AString & a_PieceName,
@ -150,13 +195,15 @@ protected:
bool a_LogWarnings
);
// cPiecePool overrides:
virtual cPieces GetPiecesWithConnector(int a_ConnectorType) override;
virtual cPieces GetStartingPieces(void) override;
virtual int GetPieceWeight(const cPlacedPiece & a_PlacedPiece, const cPiece::cConnector & a_ExistingConnector, const cPiece & a_NewPiece) override;
virtual int GetStartingPieceWeight(const cPiece & a_NewPiece) override;
virtual void PiecePlaced(const cPiece & a_Piece) override;
virtual void Reset(void) override;
/** Reads the metadata for the entire pool from the cubeset file parsed into the specified Lua state.
Returns true on success, false on failure.
The metadata is applied into "this".
If a_LogWarnings is true, logs a warning to console when loading fails. */
bool ApplyPoolMetadataCubesetVer1(
const AString & a_FileName,
cLuaState & a_LuaState,
bool a_LogWarnings
);
} ;

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +0,0 @@
// AlchemistVillagePrefabs.h
// Declares the prefabs in the group AlchemistVillage
#include "../Prefab.h"
extern const cPrefab::sDef g_AlchemistVillagePrefabs[];
extern const cPrefab::sDef g_AlchemistVillageStartingPrefabs[];
extern const size_t g_AlchemistVillagePrefabsCount;
extern const size_t g_AlchemistVillageStartingPrefabsCount;

View File

@ -5,26 +5,18 @@ project (MCServer)
include_directories ("${PROJECT_SOURCE_DIR}/../../")
SET (SRCS
AlchemistVillagePrefabs.cpp
JapaneseVillagePrefabs.cpp
NetherFortPrefabs.cpp
PlainsVillagePrefabs.cpp
RainbowRoadPrefabs.cpp
SandFlatRoofVillagePrefabs.cpp
SandVillagePrefabs.cpp
TestRailsPrefabs.cpp
UnderwaterBasePrefabs.cpp)
UnderwaterBasePrefabs.cpp
)
SET (HDRS
AlchemistVillagePrefabs.h
JapaneseVillagePrefabs.h
NetherFortPrefabs.h
PlainsVillagePrefabs.h
RainbowRoadPrefabs.h
SandFlatRoofVillagePrefabs.h
SandVillagePrefabs.h
TestRailsPrefabs.h
UnderwaterBasePrefabs.h)
UnderwaterBasePrefabs.h
)
if(NOT MSVC)
add_library(Generating_Prefabs ${SRCS} ${HDRS})

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +0,0 @@
// JapaneseVillagePrefabs.h
// Declares the prefabs in the group JapaneseVillage
#include "../Prefab.h"
extern const cPrefab::sDef g_JapaneseVillagePrefabs[];
extern const cPrefab::sDef g_JapaneseVillageStartingPrefabs[];
extern const size_t g_JapaneseVillagePrefabsCount;
extern const size_t g_JapaneseVillageStartingPrefabsCount;

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +0,0 @@
// PlainsVillagePrefabs.h
// Declares the prefabs in the group PlainsVillage
#include "../Prefab.h"
extern const cPrefab::sDef g_PlainsVillagePrefabs[];
extern const cPrefab::sDef g_PlainsVillageStartingPrefabs[];
extern const size_t g_PlainsVillagePrefabsCount;
extern const size_t g_PlainsVillageStartingPrefabsCount;

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +0,0 @@
// SandFlatRoofVillagePrefabs.h
// Declares the prefabs in the group SandFlatRoofVillage
#include "../Prefab.h"
extern const cPrefab::sDef g_SandFlatRoofVillagePrefabs[];
extern const cPrefab::sDef g_SandFlatRoofVillageStartingPrefabs[];
extern const size_t g_SandFlatRoofVillagePrefabsCount;
extern const size_t g_SandFlatRoofVillageStartingPrefabsCount;

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +0,0 @@
// SandVillagePrefabs.h
// Declares the prefabs in the group SandVillage
#include "../Prefab.h"
extern const cPrefab::sDef g_SandVillagePrefabs[];
extern const cPrefab::sDef g_SandVillageStartingPrefabs[];
extern const size_t g_SandVillagePrefabsCount;
extern const size_t g_SandVillageStartingPrefabsCount;

View File

@ -5,11 +5,6 @@
#include "Globals.h"
#include "VillageGen.h"
#include "Prefabs/AlchemistVillagePrefabs.h"
#include "Prefabs/JapaneseVillagePrefabs.h"
#include "Prefabs/PlainsVillagePrefabs.h"
#include "Prefabs/SandVillagePrefabs.h"
#include "Prefabs/SandFlatRoofVillagePrefabs.h"
#include "PieceGenerator.h"
@ -51,6 +46,16 @@ public:
const cPrefab::sDef * a_StartingPieceDefs, size_t a_NumStartingPieceDefs
) :
super(a_PieceDefs, a_NumPieceDefs, a_StartingPieceDefs, a_NumStartingPieceDefs)
{
AddRoadPieces();
}
cVillagePiecePool(void)
{
AddRoadPieces();
}
void AddRoadPieces(void)
{
// Add the road pieces:
for (int len = 27; len < 60; len += 12)
@ -115,10 +120,8 @@ public:
int a_MaxRoadDepth,
int a_MaxSize,
int a_Density,
cPiecePool & a_Prefabs,
cTerrainHeightGenPtr a_HeightGen,
BLOCKTYPE a_RoadBlock,
BLOCKTYPE a_WaterRoadBlock
cVillagePiecePool & a_Prefabs,
cTerrainHeightGenPtr a_HeightGen
) :
super(a_GridX, a_GridZ, a_OriginX, a_OriginZ),
m_Seed(a_Seed),
@ -127,9 +130,7 @@ public:
m_Density(a_Density),
m_Borders(a_OriginX - a_MaxSize, 0, a_OriginZ - a_MaxSize, a_OriginX + a_MaxSize, cChunkDef::Height - 1, a_OriginZ + a_MaxSize),
m_Prefabs(a_Prefabs),
m_HeightGen(a_HeightGen),
m_RoadBlock(a_RoadBlock),
m_WaterRoadBlock(a_WaterRoadBlock)
m_HeightGen(a_HeightGen)
{
// Generate the pieces for this village; don't care about the Y coord:
cBFSPieceGenerator pg(*this, a_Seed);
@ -172,7 +173,7 @@ protected:
cCuboid m_Borders;
/** Prefabs to use for buildings */
cPiecePool & m_Prefabs;
cVillagePiecePool & m_Prefabs;
/** The underlying height generator, used for placing the structures on top of the terrain. */
cTerrainHeightGenPtr m_HeightGen;
@ -180,12 +181,6 @@ protected:
/** The village pieces, placed by the generator. */
cPlacedPieces m_Pieces;
/** The block to use for the roads. */
BLOCKTYPE m_RoadBlock;
/** The block used for the roads if the road is on water. */
BLOCKTYPE m_WaterRoadBlock;
// cGridStructGen::cStructure overrides:
virtual void DrawIntoChunk(cChunkDesc & a_Chunk) override
@ -241,17 +236,21 @@ protected:
int MaxX = std::min(RoadCoords.p2.x - a_Chunk.GetChunkX() * cChunkDef::Width, cChunkDef::Width - 1);
int MinZ = std::max(RoadCoords.p1.z - a_Chunk.GetChunkZ() * cChunkDef::Width, 0);
int MaxZ = std::min(RoadCoords.p2.z - a_Chunk.GetChunkZ() * cChunkDef::Width, cChunkDef::Width - 1);
auto WaterRoadBlockType = m_Prefabs.GetVillageWaterRoadBlockType();
auto WaterRoadBlockMeta = m_Prefabs.GetVillageWaterRoadBlockMeta();
auto RoadBlockType = m_Prefabs.GetVillageRoadBlockType();
auto RoadBlockMeta = m_Prefabs.GetVillageRoadBlockMeta();
for (int z = MinZ; z <= MaxZ; z++)
{
for (int x = MinX; x <= MaxX; x++)
{
if (IsBlockWater(a_Chunk.GetBlockType(x, cChunkDef::GetHeight(a_HeightMap, x, z), z)))
{
a_Chunk.SetBlockType(x, cChunkDef::GetHeight(a_HeightMap, x, z), z, m_WaterRoadBlock);
a_Chunk.SetBlockTypeMeta(x, cChunkDef::GetHeight(a_HeightMap, x, z), z, WaterRoadBlockType, WaterRoadBlockMeta);
}
else
{
a_Chunk.SetBlockType(x, cChunkDef::GetHeight(a_HeightMap, x, z), z, m_RoadBlock);
a_Chunk.SetBlockTypeMeta(x, cChunkDef::GetHeight(a_HeightMap, x, z), z, RoadBlockType, RoadBlockMeta);
}
}
}
@ -336,30 +335,18 @@ protected:
////////////////////////////////////////////////////////////////////////////////
// cVillageGen:
static cVillagePiecePool g_SandVillage(g_SandVillagePrefabs, g_SandVillagePrefabsCount, g_SandVillageStartingPrefabs, g_SandVillageStartingPrefabsCount);
static cVillagePiecePool g_SandFlatRoofVillage(g_SandFlatRoofVillagePrefabs, g_SandFlatRoofVillagePrefabsCount, g_SandFlatRoofVillageStartingPrefabs, g_SandFlatRoofVillageStartingPrefabsCount);
static cVillagePiecePool g_AlchemistVillage(g_AlchemistVillagePrefabs, g_AlchemistVillagePrefabsCount, g_AlchemistVillageStartingPrefabs, g_AlchemistVillageStartingPrefabsCount);
static cVillagePiecePool g_PlainsVillage(g_PlainsVillagePrefabs, g_PlainsVillagePrefabsCount, g_PlainsVillageStartingPrefabs, g_PlainsVillageStartingPrefabsCount);
static cVillagePiecePool g_JapaneseVillage(g_JapaneseVillagePrefabs, g_JapaneseVillagePrefabsCount, g_JapaneseVillageStartingPrefabs, g_JapaneseVillageStartingPrefabsCount);
static cVillagePiecePool * g_DesertVillagePools[] =
{
&g_SandVillage,
&g_SandFlatRoofVillage,
&g_AlchemistVillage,
} ;
static cVillagePiecePool * g_PlainsVillagePools[] =
{
&g_PlainsVillage,
&g_JapaneseVillage,
} ;
cVillageGen::cVillageGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize, int a_MinDensity, int a_MaxDensity, cBiomeGenPtr a_BiomeGen, cTerrainHeightGenPtr a_HeightGen) :
cVillageGen::cVillageGen(
int a_Seed,
int a_GridSize,
int a_MaxOffset,
int a_MaxDepth,
int a_MaxSize,
int a_MinDensity,
int a_MaxDensity,
cBiomeGenPtr a_BiomeGen,
cTerrainHeightGenPtr a_HeightGen,
const AStringVector & a_PrefabsToLoad
) :
super(a_Seed, a_GridSize, a_GridSize, a_MaxOffset, a_MaxOffset, a_MaxSize, a_MaxSize, 100),
m_Noise(a_Seed + 1000),
m_MaxDepth(a_MaxDepth),
@ -369,6 +356,21 @@ cVillageGen::cVillageGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxD
m_BiomeGen(a_BiomeGen),
m_HeightGen(a_HeightGen)
{
for (const auto & toLoad: a_PrefabsToLoad)
{
auto prefabs = std::make_shared<cVillagePiecePool>();
auto fileName = Printf("Prefabs%sVillages%s%s.cubeset", cFile::GetPathSeparator().c_str(), cFile::GetPathSeparator().c_str(), toLoad.c_str());
if (prefabs->LoadFromFile(fileName, true))
{
if (NoCaseCompare(prefabs->GetIntendedUse(), "village") != 0)
{
LOGWARNING("Village generator: File %s is intended for use in \"%s\", rather than villages. Loading the file, but the generator may behave unexpectedly.",
fileName.c_str(), prefabs->GetIntendedUse().c_str()
);
}
m_Pools.push_back(std::move(prefabs));
}
}
}
@ -383,60 +385,48 @@ cGridStructGen::cStructurePtr cVillageGen::CreateStructure(int a_GridX, int a_Gr
cChunkDef::BiomeMap Biomes;
m_BiomeGen->GenBiomes(ChunkX, ChunkZ, Biomes);
// Check if all the biomes are village-friendly:
// If just one is not, no village is created, because it's likely that an unfriendly biome is too close
cVillagePiecePool * VillagePrefabs = nullptr;
BLOCKTYPE RoadBlock = E_BLOCK_GRAVEL;
BLOCKTYPE WaterRoadBlock = E_BLOCK_PLANKS;
int rnd = m_Noise.IntNoise2DInt(a_OriginX, a_OriginZ) / 11;
cVillagePiecePool * PlainsVillage = g_PlainsVillagePools[static_cast<size_t>(rnd) % ARRAYCOUNT(g_PlainsVillagePools)];
cVillagePiecePool * DesertVillage = g_DesertVillagePools[static_cast<size_t>(rnd) % ARRAYCOUNT(g_DesertVillagePools)];
// Get a list of pools that support each biome within the chunk:
// If just one column's biome is not allowed, the pool is not used because it's likely that an unfriendly biome is too close
auto availablePools = m_Pools;
for (size_t i = 0; i < ARRAYCOUNT(Biomes); i++)
{
switch (Biomes[i])
auto biome = Biomes[i];
availablePools.erase(std::remove_if(availablePools.begin(), availablePools.end(),
[biome](SharedPtr<cPrefabPiecePool> a_Pool)
{
return !a_Pool->IsBiomeAllowed(biome);
}),
availablePools.end()
);
// Bail out if no compatible pools left:
if (availablePools.empty())
{
case biDesert:
case biDesertM:
{
// These biomes allow sand villages
VillagePrefabs = DesertVillage;
// RoadBlock = E_BLOCK_SANDSTONE;
break;
}
case biPlains:
case biSavanna:
case biSavannaM:
case biSunflowerPlains:
{
// These biomes allow plains-style villages
VillagePrefabs = PlainsVillage;
break;
}
default:
{
// Village-unfriendly biome, bail out with zero structure:
return cStructurePtr();
}
} // switch (Biomes[i])
} // for i - Biomes[]
return cStructurePtr();
}
}
// Choose density for the village, random between m_MinDensity and m_MaxDensity:
int Density;
if (m_MaxDensity > m_MinDensity)
{
Density = m_MinDensity + rnd % (m_MaxDensity - m_MinDensity);
}
else
{
Density = m_MinDensity;
}
// Create a village based on the chosen prefabs:
if (VillagePrefabs == nullptr)
// Pick one pool from the available pools:
if (availablePools.empty())
{
return cStructurePtr();
}
return cStructurePtr(new cVillage(m_Seed, a_GridX, a_GridZ, a_OriginX, a_OriginZ, m_MaxDepth, m_MaxSize, Density, *VillagePrefabs, m_HeightGen, RoadBlock, WaterRoadBlock));
auto rnd = m_Noise.IntNoise2DInt(a_OriginX, a_OriginZ) / 11;
auto pool = availablePools[static_cast<size_t>(rnd) % availablePools.size()];
rnd /= 137;
// Choose density for the village, random between m_MinDensity and m_MaxDensity:
int Density;
if (pool->GetMaxDensity() > pool->GetMinDensity())
{
Density = pool->GetMinDensity() + rnd % (pool->GetMaxDensity() - pool->GetMinDensity());
}
else
{
Density = pool->GetMinDensity();
}
// Create a village based on the chosen prefabs:
return cStructurePtr(new cVillage(m_Seed, a_GridX, a_GridZ, a_OriginX, a_OriginZ, m_MaxDepth, m_MaxSize, Density, *pool.get(), m_HeightGen));
}

View File

@ -16,15 +16,34 @@
// fwd:
class cVillagePiecePool;
class cVillageGen :
public cGridStructGen
{
typedef cGridStructGen super;
public:
cVillageGen(int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxDepth, int a_MaxSize, int a_MinDensity, int a_MaxDensity, cBiomeGenPtr a_BiomeGen, cTerrainHeightGenPtr a_HeightGen);
/** Creates a new instance of the generator with the specified parameters. */
cVillageGen(
int a_Seed,
int a_GridSize,
int a_MaxOffset,
int a_MaxDepth,
int a_MaxSize,
int a_MinDensity, int a_MaxDensity,
cBiomeGenPtr a_BiomeGen,
cTerrainHeightGenPtr a_HeightGen,
const AStringVector & a_PrefabsToLoad
);
protected:
class cVillage; // fwd: VillageGen.cpp
typedef std::vector<SharedPtr<cVillagePiecePool> > cVillagePiecePools;
/** The noise used for generating random numbers */
cNoise m_Noise;
@ -47,6 +66,9 @@ protected:
/** The underlying height generator, used to position the prefabs crossing chunk borders */
cTerrainHeightGenPtr m_HeightGen;
/** All available prefab sets. Each village gets one of these chosen randomly. */
cVillagePiecePools m_Pools;
// cGridStructGen overrides:
virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) override;

View File

@ -9,6 +9,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR})
add_definitions(-DTEST_GLOBALS=1)
set (SHARED_SRCS
${CMAKE_SOURCE_DIR}/src/BiomeDef.cpp
${CMAKE_SOURCE_DIR}/src/BlockArea.cpp
${CMAKE_SOURCE_DIR}/src/Cuboid.cpp
${CMAKE_SOURCE_DIR}/src/ChunkData.cpp
@ -35,6 +36,7 @@ set (SHARED_SRCS
)
set (SHARED_HDRS
${CMAKE_SOURCE_DIR}/src/BiomeDef.h
${CMAKE_SOURCE_DIR}/src/BlockArea.h
${CMAKE_SOURCE_DIR}/src/Cuboid.h
${CMAKE_SOURCE_DIR}/src/ChunkData.h
@ -73,6 +75,7 @@ set (SRCS
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
add_flags_cxx("-Wno-error=conversion -Wno-error=old-style-cast")
add_flags_cxx("-Wno-error=global-constructors")
add_flags_cxx("-Wno-error=switch-enum")
endif()