Initial nether composition generator
git-svn-id: http://mc-server.googlecode.com/svn/trunk@1266 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
parent
9931b5634b
commit
d2573b84dd
@ -425,3 +425,101 @@ void cCompoGenBiomal::FillColumnPattern(int a_RelX, int a_RelZ, int a_Height, cC
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// cCompoGenNether:
|
||||||
|
|
||||||
|
cCompoGenNether::cCompoGenNether(int a_Seed) :
|
||||||
|
m_Noise1(a_Seed + 10),
|
||||||
|
m_Noise2(a_Seed * a_Seed * 10 + a_Seed * 1000 + 6000),
|
||||||
|
m_Threshold(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cCompoGenNether::ComposeTerrain(
|
||||||
|
int a_ChunkX, int a_ChunkZ,
|
||||||
|
cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated
|
||||||
|
cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated
|
||||||
|
const cChunkDef::HeightMap & a_HeightMap, // The height map to fit
|
||||||
|
const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to
|
||||||
|
cEntityList & a_Entities, // Entitites may be generated along with the terrain
|
||||||
|
cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
HEIGHTTYPE MaxHeight = 0;
|
||||||
|
for (int i = 0; i < ARRAYCOUNT(a_HeightMap); i++)
|
||||||
|
{
|
||||||
|
if (a_HeightMap[i] > MaxHeight)
|
||||||
|
{
|
||||||
|
MaxHeight = a_HeightMap[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const int SEGMENT_HEIGHT = 8;
|
||||||
|
const int INTERPOL_X = 16; // Must be a divisor of 16
|
||||||
|
const int INTERPOL_Z = 16; // Must be a divisor of 16
|
||||||
|
// Interpolate the chunk in 16 * SEGMENT_HEIGHT * 16 "segments", each 8 blocks high and each linearly interpolated separately.
|
||||||
|
// Have two buffers, one for the lowest floor and one for the highest floor, so that Y-interpolation can be done between them
|
||||||
|
// Then swap the buffers and use the previously-top one as the current-bottom, without recalculating it.
|
||||||
|
|
||||||
|
int FloorBuf1[17 * 17];
|
||||||
|
int FloorBuf2[17 * 17];
|
||||||
|
int * FloorHi = FloorBuf1;
|
||||||
|
int * FloorLo = FloorBuf2;
|
||||||
|
int BaseX = a_ChunkX * cChunkDef::Width;
|
||||||
|
int BaseZ = a_ChunkZ * cChunkDef::Width;
|
||||||
|
|
||||||
|
// Interpolate the lowest floor:
|
||||||
|
for (int z = 0; z <= 16 / INTERPOL_Z; z++) for (int x = 0; x <= 16 / INTERPOL_X; x++)
|
||||||
|
{
|
||||||
|
FloorLo[INTERPOL_X * x + 17 * INTERPOL_Z * z] =
|
||||||
|
m_Noise1.IntNoise3DInt(BaseX + INTERPOL_X * x, 0, BaseZ + INTERPOL_Z * z) *
|
||||||
|
m_Noise2.IntNoise3DInt(BaseX + INTERPOL_X * x, 0, BaseZ + INTERPOL_Z * z) /
|
||||||
|
256;
|
||||||
|
} // for x, z - FloorLo[]
|
||||||
|
IntArrayLinearInterpolate2D(FloorLo, 17, 17, INTERPOL_X, INTERPOL_Z);
|
||||||
|
|
||||||
|
// Interpolate segments:
|
||||||
|
for (int Segment = 0; Segment < MaxHeight; Segment += SEGMENT_HEIGHT)
|
||||||
|
{
|
||||||
|
// First update the high floor:
|
||||||
|
for (int z = 0; z <= 16 / INTERPOL_Z; z++) for (int x = 0; x <= 16 / INTERPOL_X; x++)
|
||||||
|
{
|
||||||
|
FloorHi[INTERPOL_X * x + 17 * INTERPOL_Z * z] =
|
||||||
|
m_Noise1.IntNoise3DInt(BaseX + INTERPOL_X * x, Segment + SEGMENT_HEIGHT, BaseZ + INTERPOL_Z * z) *
|
||||||
|
m_Noise2.IntNoise3DInt(BaseX + INTERPOL_Z * x, Segment + SEGMENT_HEIGHT, BaseZ + INTERPOL_Z * z) /
|
||||||
|
256;
|
||||||
|
} // for x, z - FloorLo[]
|
||||||
|
IntArrayLinearInterpolate2D(FloorHi, 17, 17, INTERPOL_X, INTERPOL_Z);
|
||||||
|
|
||||||
|
// Interpolate between FloorLo and FloorHi:
|
||||||
|
for (int z = 0; z < 16; z++) for (int x = 0; x < 16; x++)
|
||||||
|
{
|
||||||
|
int Lo = FloorLo[x + 17 * z] / 256;
|
||||||
|
int Hi = FloorHi[x + 17 * z] / 256;
|
||||||
|
for (int y = 0; y < SEGMENT_HEIGHT; y++)
|
||||||
|
{
|
||||||
|
int Val = Lo + (Hi - Lo) * y / SEGMENT_HEIGHT;
|
||||||
|
cChunkDef::SetBlock(a_BlockTypes, x, y + Segment, z, (Val < m_Threshold) ? E_BLOCK_NETHERRACK : E_BLOCK_AIR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Swap the floors:
|
||||||
|
std::swap(FloorLo, FloorHi);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bedrock at the bottom and at the top:
|
||||||
|
for (int z = 0; z < 16; z++) for (int x = 0; x < 16; x++)
|
||||||
|
{
|
||||||
|
cChunkDef::SetBlock(a_BlockTypes, x, 0, z, E_BLOCK_BEDROCK);
|
||||||
|
cChunkDef::SetBlock(a_BlockTypes, x, cChunkDef::GetHeight(a_HeightMap, x, z), z, E_BLOCK_BEDROCK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -152,3 +152,31 @@ protected:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class cCompoGenNether :
|
||||||
|
public cTerrainCompositionGen
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
cCompoGenNether(int a_Seed);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
cNoise m_Noise1;
|
||||||
|
cNoise m_Noise2;
|
||||||
|
|
||||||
|
int m_Threshold;
|
||||||
|
|
||||||
|
// cTerrainCompositionGen overrides:
|
||||||
|
virtual void ComposeTerrain(
|
||||||
|
int a_ChunkX, int a_ChunkZ,
|
||||||
|
cChunkDef::BlockTypes & a_BlockTypes, // BlockTypes to be generated
|
||||||
|
cChunkDef::BlockNibbles & a_BlockMeta, // BlockMetas to be generated
|
||||||
|
const cChunkDef::HeightMap & a_HeightMap, // The height map to fit
|
||||||
|
const cChunkDef::BiomeMap & a_BiomeMap, // Biomes to adhere to
|
||||||
|
cEntityList & a_Entities, // Entitites may be generated along with the terrain
|
||||||
|
cBlockEntityList & a_BlockEntities // Block entitites may be generated (chests / furnaces / ...)
|
||||||
|
) override;
|
||||||
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -283,6 +283,10 @@ void cComposableGenerator::InitCompositionGen(cIniFile & a_IniFile)
|
|||||||
BlockBeachBottom, BlockSea
|
BlockBeachBottom, BlockSea
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
else if (NoCaseCompare(CompoGenName, "nether") == 0)
|
||||||
|
{
|
||||||
|
m_CompositionGen = new cCompoGenNether(m_ChunkGenerator.GetSeed());
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (NoCaseCompare(CompoGenName, "biomal") != 0)
|
if (NoCaseCompare(CompoGenName, "biomal") != 0)
|
||||||
|
@ -461,7 +461,7 @@ void cProtocol125::SendLogin(const cPlayer & a_Player, const cWorld & a_World)
|
|||||||
WriteString(""); // Username, not used
|
WriteString(""); // Username, not used
|
||||||
WriteString("default"); // Level type
|
WriteString("default"); // Level type
|
||||||
WriteInt ((int)a_Player.GetGameMode());
|
WriteInt ((int)a_Player.GetGameMode());
|
||||||
WriteInt (0); // TODO: Dimension (Nether / Overworld / End)
|
WriteInt ((int)(a_World.GetDimension()));
|
||||||
WriteByte (2); // TODO: Difficulty
|
WriteByte (2); // TODO: Difficulty
|
||||||
WriteByte (0); // Unused
|
WriteByte (0); // Unused
|
||||||
WriteByte (60); // Client list width or something
|
WriteByte (60); // Client list width or something
|
||||||
@ -600,7 +600,7 @@ void cProtocol125::SendRespawn(void)
|
|||||||
{
|
{
|
||||||
cCSLock Lock(m_CSPacket);
|
cCSLock Lock(m_CSPacket);
|
||||||
WriteByte (PACKET_RESPAWN);
|
WriteByte (PACKET_RESPAWN);
|
||||||
WriteInt (0); // TODO: Dimension; 0 = Overworld
|
WriteInt ((int)(m_Client->GetPlayer()->GetWorld()->GetDimension()));
|
||||||
WriteByte (2); // TODO: Difficulty; 2 = Normal
|
WriteByte (2); // TODO: Difficulty; 2 = Normal
|
||||||
WriteByte ((char)m_Client->GetPlayer()->GetGameMode());
|
WriteByte ((char)m_Client->GetPlayer()->GetGameMode());
|
||||||
WriteShort (256); // Current world height
|
WriteShort (256); // Current world height
|
||||||
|
@ -326,7 +326,7 @@ void cProtocol132::SendLogin(const cPlayer & a_Player, const cWorld & a_World)
|
|||||||
WriteInt (a_Player.GetUniqueID()); // EntityID of the player
|
WriteInt (a_Player.GetUniqueID()); // EntityID of the player
|
||||||
WriteString("default"); // Level type
|
WriteString("default"); // Level type
|
||||||
WriteByte ((int)a_Player.GetGameMode());
|
WriteByte ((int)a_Player.GetGameMode());
|
||||||
WriteByte (0); // TODO: Dimension (Nether / Overworld / End)
|
WriteByte ((Byte)(a_World.GetDimension()));
|
||||||
WriteByte (2); // TODO: Difficulty
|
WriteByte (2); // TODO: Difficulty
|
||||||
WriteByte (0); // Unused, used to be world height
|
WriteByte (0); // Unused, used to be world height
|
||||||
WriteByte (8); // Client list width or something
|
WriteByte (8); // Client list width or something
|
||||||
|
@ -201,6 +201,22 @@ cWorld::cWorld(const AString & a_WorldName) :
|
|||||||
|
|
||||||
cIniFile IniFile(m_IniFileName);
|
cIniFile IniFile(m_IniFileName);
|
||||||
IniFile.ReadFile();
|
IniFile.ReadFile();
|
||||||
|
m_Dimension = (eDimension)(IniFile.GetValueSetI("General", "Dimension", 0));
|
||||||
|
switch (m_Dimension)
|
||||||
|
{
|
||||||
|
case dimNether:
|
||||||
|
case dimOverworld:
|
||||||
|
case dimEnd:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
LOGWARNING("Unknown dimension: %d. Setting to Overworld (0)", m_Dimension);
|
||||||
|
m_Dimension = dimOverworld;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} // switch (m_Dimension)
|
||||||
m_SpawnX = IniFile.GetValueSetF("SpawnPosition", "X", m_SpawnX);
|
m_SpawnX = IniFile.GetValueSetF("SpawnPosition", "X", m_SpawnX);
|
||||||
m_SpawnY = IniFile.GetValueSetF("SpawnPosition", "Y", m_SpawnY);
|
m_SpawnY = IniFile.GetValueSetF("SpawnPosition", "Y", m_SpawnY);
|
||||||
m_SpawnZ = IniFile.GetValueSetF("SpawnPosition", "Z", m_SpawnZ);
|
m_SpawnZ = IniFile.GetValueSetF("SpawnPosition", "Z", m_SpawnZ);
|
||||||
|
@ -54,12 +54,17 @@ typedef cItemCallback<cFurnaceEntity> cFurnaceCallback;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// tolua_begin
|
||||||
class cWorld // tolua_export
|
class cWorld
|
||||||
{ // tolua_export
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// tolua_begin
|
enum eDimension
|
||||||
|
{
|
||||||
|
dimNether = -1,
|
||||||
|
dimOverworld = 0,
|
||||||
|
dimEnd = 1,
|
||||||
|
} ;
|
||||||
|
|
||||||
static const char * GetClassStatic(void)
|
static const char * GetClassStatic(void)
|
||||||
{
|
{
|
||||||
@ -93,6 +98,8 @@ public:
|
|||||||
bool IsPVPEnabled(void) const { return m_bEnabledPVP; }
|
bool IsPVPEnabled(void) const { return m_bEnabledPVP; }
|
||||||
bool IsDeepSnowEnabled(void) const { return m_IsDeepSnowEnabled; }
|
bool IsDeepSnowEnabled(void) const { return m_IsDeepSnowEnabled; }
|
||||||
|
|
||||||
|
eDimension GetDimension(void) const { return m_Dimension; }
|
||||||
|
|
||||||
int GetHeight(int a_BlockX, int a_BlockZ);
|
int GetHeight(int a_BlockX, int a_BlockZ);
|
||||||
|
|
||||||
// tolua_end
|
// tolua_end
|
||||||
@ -459,7 +466,10 @@ private:
|
|||||||
|
|
||||||
friend class cRoot;
|
friend class cRoot;
|
||||||
|
|
||||||
// This random generator is to be used only in the Tick() method, and thus only in the World-Tick-thread (MTRand is not exactly thread-safe)
|
/// The dimension of the world, used by the client to provide correct lighting scheme
|
||||||
|
eDimension m_Dimension;
|
||||||
|
|
||||||
|
/// This random generator is to be used only in the Tick() method, and thus only in the World-Tick-thread (MTRand is not exactly thread-safe)
|
||||||
MTRand m_TickRand;
|
MTRand m_TickRand;
|
||||||
|
|
||||||
double m_SpawnX;
|
double m_SpawnX;
|
||||||
|
Loading…
Reference in New Issue
Block a user