1
0

Merged branch 'master' into GrownBiomes.

This commit is contained in:
Mattes D 2014-10-28 22:29:46 +01:00
commit 791f891212
27 changed files with 693 additions and 478 deletions

View File

@ -123,35 +123,47 @@ return
cSplashPotionEntity = cSplashPotionEntity =
{ {
Desc = "", Desc = [[
Functions = {}, Represents a thrown splash potion.
]],
Functions =
{
GetEntityEffect = { Params = "", Return = "{{cEntityEffect}}", Notes = "Returns the entity effect in this potion" },
GetEntityEffectType = { Params = "", Return = "{{cEntityEffect|Entity effect type}}", Notes = "Returns the effect type of this potion" },
GetPotionColor = { Params = "", Return = "number", Notes = "Returns the color index of the particles emitted by this potion" },
SetEntityEffect = { Params = "{{cEntityEffect}}", Return = "", Notes = "Sets the entity effect for this potion" },
SetEntityEffectType = { Params = "{{cEntityEffect|Entity effect type}}", Return = "", Notes = "Sets the effect type of this potion" },
SetPotionColor = { Params = "number", Return = "", Notes = "Sets the color index of the particles for this potion" },
},
Inherits = "cProjectileEntity", Inherits = "cProjectileEntity",
}, -- cSplashPotionEntity }, -- cSplashPotionEntity
cThrownEggEntity = cThrownEggEntity =
{ {
Desc = "", Desc = [[
Represents a thrown egg.
]],
Functions = {}, Functions = {},
Inherits = "cProjectileEntity", Inherits = "cProjectileEntity",
}, -- cThrownEggEntity }, -- cThrownEggEntity
cThrownEnderPearlEntity = cThrownEnderPearlEntity =
{ {
Desc = "", Desc = "Represents a thrown ender pearl.",
Functions = {}, Functions = {},
Inherits = "cProjectileEntity", Inherits = "cProjectileEntity",
}, -- cThrownEnderPearlEntity }, -- cThrownEnderPearlEntity
cThrownSnowballEntity = cThrownSnowballEntity =
{ {
Desc = "", Desc = "Represents a thrown snowball.",
Functions = {}, Functions = {},
Inherits = "cProjectileEntity", Inherits = "cProjectileEntity",
}, -- cThrownSnowballEntity }, -- cThrownSnowballEntity
cWitherSkullEntity = cWitherSkullEntity =
{ {
Desc = "", Desc = "Represents a wither skull being shot.",
Functions = {}, Functions = {},
Inherits = "cProjectileEntity", Inherits = "cProjectileEntity",
}, -- cWitherSkullEntity }, -- cWitherSkullEntity

View File

@ -12,7 +12,7 @@ Installation
For Linux there is an easy installation method, just run this in your terminal: For Linux there is an easy installation method, just run this in your terminal:
curl -s https://raw.githubusercontent.com/mc-server/MCServer/master/easyinstall.sh | sh curl -s https://raw.github.com/mc-server/MCServer/master/easyinstall.sh | sh
For Windows, you just need to download a file and extract it: For Windows, you just need to download a file and extract it:

View File

@ -1,8 +1,8 @@
#include "Globals.h" #include "Globals.h"
#include "BiomeView.h" #include "BiomeView.h"
#include "QtChunk.h"
#include <QPainter> #include <QPainter>
#include <QResizeEvent> #include <QResizeEvent>
#include "Region.h"
@ -14,6 +14,116 @@ static const int DELTA_STEP = 120; // The normal per-notch wheel delta
/** Map for converting biome values to colors. Initialized from biomeColors[]. */
static uchar biomeToColor[256 * 4];
/** Map for converting biome values to colors. Used to initialize biomeToColor[].*/
static struct
{
EMCSBiome m_Biome;
uchar m_Color[3];
} biomeColors[] =
{
{ biOcean, { 0x00, 0x00, 0x70 }, },
{ biPlains, { 0x8d, 0xb3, 0x60 }, },
{ biDesert, { 0xfa, 0x94, 0x18 }, },
{ biExtremeHills, { 0x60, 0x60, 0x60 }, },
{ biForest, { 0x05, 0x66, 0x21 }, },
{ biTaiga, { 0x0b, 0x66, 0x59 }, },
{ biSwampland, { 0x2f, 0xff, 0xda }, },
{ biRiver, { 0x30, 0x30, 0xaf }, },
{ biHell, { 0x7f, 0x00, 0x00 }, },
{ biSky, { 0x00, 0x7f, 0xff }, },
{ biFrozenOcean, { 0xa0, 0xa0, 0xdf }, },
{ biFrozenRiver, { 0xa0, 0xa0, 0xff }, },
{ biIcePlains, { 0xff, 0xff, 0xff }, },
{ biIceMountains, { 0xa0, 0xa0, 0xa0 }, },
{ biMushroomIsland, { 0xff, 0x00, 0xff }, },
{ biMushroomShore, { 0xa0, 0x00, 0xff }, },
{ biBeach, { 0xfa, 0xde, 0x55 }, },
{ biDesertHills, { 0xd2, 0x5f, 0x12 }, },
{ biForestHills, { 0x22, 0x55, 0x1c }, },
{ biTaigaHills, { 0x16, 0x39, 0x33 }, },
{ biExtremeHillsEdge, { 0x7f, 0x8f, 0x7f }, },
{ biJungle, { 0x53, 0x7b, 0x09 }, },
{ biJungleHills, { 0x2c, 0x42, 0x05 }, },
{ biJungleEdge, { 0x62, 0x8b, 0x17 }, },
{ biDeepOcean, { 0x00, 0x00, 0x30 }, },
{ biStoneBeach, { 0xa2, 0xa2, 0x84 }, },
{ biColdBeach, { 0xfa, 0xf0, 0xc0 }, },
{ biBirchForest, { 0x30, 0x74, 0x44 }, },
{ biBirchForestHills, { 0x1f, 0x5f, 0x32 }, },
{ biRoofedForest, { 0x40, 0x51, 0x1a }, },
{ biColdTaiga, { 0x31, 0x55, 0x4a }, },
{ biColdTaigaHills, { 0x59, 0x7d, 0x72 }, },
{ biMegaTaiga, { 0x59, 0x66, 0x51 }, },
{ biMegaTaigaHills, { 0x59, 0x66, 0x59 }, },
{ biExtremeHillsPlus, { 0x50, 0x70, 0x50 }, },
{ biSavanna, { 0xbd, 0xb2, 0x5f }, },
{ biSavannaPlateau, { 0xa7, 0x9d, 0x64 }, },
{ biMesa, { 0xd9, 0x45, 0x15 }, },
{ biMesaPlateauF, { 0xb0, 0x97, 0x65 }, },
{ biMesaPlateau, { 0xca, 0x8c, 0x65 }, },
// M variants:
{ biSunflowerPlains, { 0xb5, 0xdb, 0x88 }, },
{ biDesertM, { 0xff, 0xbc, 0x40 }, },
{ biExtremeHillsM, { 0x88, 0x88, 0x88 }, },
{ biFlowerForest, { 0x2d, 0x8e, 0x49 }, },
{ biTaigaM, { 0x33, 0x8e, 0x81 }, },
{ biSwamplandM, { 0x07, 0xf9, 0xb2 }, },
{ biIcePlainsSpikes, { 0xb4, 0xdc, 0xdc }, },
{ biJungleM, { 0x7b, 0xa3, 0x31 }, },
{ biJungleEdgeM, { 0x62, 0x8b, 0x17 }, },
{ biBirchForestM, { 0x58, 0x9c, 0x6c }, },
{ biBirchForestHillsM, { 0x47, 0x87, 0x5a }, },
{ biRoofedForestM, { 0x68, 0x79, 0x42 }, },
{ biColdTaigaM, { 0x24, 0x3f, 0x36 }, },
{ biMegaSpruceTaiga, { 0x45, 0x4f, 0x3e }, },
{ biMegaSpruceTaigaHills, { 0x45, 0x4f, 0x4e }, },
{ biExtremeHillsPlusM, { 0x78, 0x98, 0x78 }, },
{ biSavannaM, { 0xe5, 0xda, 0x87 }, },
{ biSavannaPlateauM, { 0xa7, 0x9d, 0x74 }, },
{ biMesaBryce, { 0xff, 0x6d, 0x3d }, },
{ biMesaPlateauFM, { 0xd8, 0xbf, 0x8d }, },
{ biMesaPlateauM, { 0xf2, 0xb4, 0x8d }, },
} ;
static class BiomeColorsInitializer
{
public:
BiomeColorsInitializer(void)
{
// Reset all colors to gray:
for (size_t i = 0; i < ARRAYCOUNT(biomeToColor); i++)
{
biomeToColor[i] = 0x7f;
}
// Set known biomes to their colors:
for (size_t i = 0; i < ARRAYCOUNT(biomeColors); i++)
{
uchar * color = &biomeToColor[4 * biomeColors[i].m_Biome];
color[0] = biomeColors[i].m_Color[2];
color[1] = biomeColors[i].m_Color[1];
color[2] = biomeColors[i].m_Color[0];
color[3] = 0xff;
}
}
} biomeColorInitializer;
////////////////////////////////////////////////////////////////////////////////
// BiomeView:
BiomeView::BiomeView(QWidget * parent) : BiomeView::BiomeView(QWidget * parent) :
super(parent), super(parent),
m_X(0), m_X(0),
@ -40,7 +150,7 @@ BiomeView::BiomeView(QWidget * parent) :
redraw(); redraw();
// Add a chunk-update callback mechanism: // Add a chunk-update callback mechanism:
connect(&m_Cache, SIGNAL(chunkAvailable(int, int)), this, SLOT(chunkAvailable(int, int))); connect(&m_Cache, SIGNAL(regionAvailable(int, int)), this, SLOT(regionAvailable(int, int)));
// Allow mouse and keyboard interaction: // Allow mouse and keyboard interaction:
setFocusPolicy(Qt::StrongFocus); setFocusPolicy(Qt::StrongFocus);
@ -143,9 +253,15 @@ void BiomeView::redraw()
void BiomeView::chunkAvailable(int a_ChunkX, int a_ChunkZ) void BiomeView::regionAvailable(int a_RegionX, int a_RegionZ)
{ {
drawChunk(a_ChunkX, a_ChunkZ); for (int z = 0; z < 32; z++)
{
for (int x = 0; x < 32; x++)
{
drawChunk(a_RegionX * 32 + x, a_RegionZ * 32 + z);
}
}
update(); update();
} }
@ -175,8 +291,11 @@ void BiomeView::drawChunk(int a_ChunkX, int a_ChunkZ)
return; return;
} }
//fetch the chunk: // Fetch the region:
ChunkPtr chunk = m_Cache.fetch(a_ChunkX, a_ChunkZ); int regionX;
int regionZ;
Region::chunkToRegion(a_ChunkX, a_ChunkZ, regionX, regionZ);
RegionPtr region = m_Cache.fetch(regionX, regionZ);
// Figure out where on the screen this chunk should be drawn: // Figure out where on the screen this chunk should be drawn:
// first find the center chunk // first find the center chunk
@ -194,11 +313,10 @@ void BiomeView::drawChunk(int a_ChunkX, int a_ChunkZ)
centerx += (a_ChunkX - centerchunkx) * chunksize; centerx += (a_ChunkX - centerchunkx) * chunksize;
centery += (a_ChunkZ - centerchunkz) * chunksize; centery += (a_ChunkZ - centerchunkz) * chunksize;
int srcoffset = 0;
uchar * bits = m_Image.bits(); uchar * bits = m_Image.bits();
int imgstride = m_Image.bytesPerLine(); int imgstride = m_Image.bytesPerLine();
int skipx = 0,skipy = 0; int skipx = 0, skipy = 0;
int blockwidth = chunksize, blockheight = chunksize; int blockwidth = chunksize, blockheight = chunksize;
// now if we're off the screen we need to crop // now if we're off the screen we need to crop
if (centerx < 0) if (centerx < 0)
@ -227,29 +345,52 @@ void BiomeView::drawChunk(int a_ChunkX, int a_ChunkZ)
int imgoffset = centerx * 4 + centery * imgstride; int imgoffset = centerx * 4 + centery * imgstride;
// If the chunk is valid, use its data; otherwise use the empty placeholder: // If the chunk is valid, use its data; otherwise use the empty placeholder:
const uchar * src = m_EmptyChunkImage; const short * src = m_EmptyChunkBiomes;
if (chunk.get() != nullptr) if (region.get() != nullptr)
{ {
src = chunk->getImage(); int relChunkX = a_ChunkX - regionX * 32;
int relChunkZ = a_ChunkZ - regionZ * 32;
Chunk & chunk = region->getRelChunk(relChunkX, relChunkZ);
if (chunk.isValid())
{
src = chunk.getBiomes();
}
} }
// Blit or scale-blit the image: // Scale-blit the image:
for (int z = skipy; z < blockheight; z++, imgoffset += imgstride) for (int z = skipy; z < blockheight; z++, imgoffset += imgstride)
{ {
srcoffset = floor((double)z / m_Zoom) * 16 * 4; size_t srcoffset = static_cast<size_t>(std::floor((double)z / m_Zoom)) * 16;
if (m_Zoom == 1.0) int imgxoffset = imgoffset;
for (int x = skipx; x < blockwidth; x++)
{ {
memcpy(bits + imgoffset, src + srcoffset + skipx * 4, (blockwidth - skipx) * 4); short biome = src[srcoffset + static_cast<size_t>(std::floor((double)x / m_Zoom))];
} const uchar * color;
else if (biome < 0)
{
int xofs = 0;
for (int x = skipx; x < blockwidth; x++, xofs +=4)
{ {
memcpy(bits + imgoffset + xofs, src + srcoffset + (int)floor((double)x / m_Zoom) * 4, 4); static const uchar emptyBiome1[] = { 0x44, 0x44, 0x44, 0xff };
static const uchar emptyBiome2[] = { 0x88, 0x88, 0x88, 0xff };
color = ((x & 8) ^ (z & 8)) ? emptyBiome1 : emptyBiome2;
} }
} else
} {
if (biome * 4 >= ARRAYCOUNT(biomeToColor))
{
static const uchar errorImage[] = { 0xff, 0x00, 0x00, 0xff };
color = errorImage;
}
else
{
color = biomeToColor + biome * 4;
}
}
bits[imgxoffset] = color[0];
bits[imgxoffset + 1] = color[1];
bits[imgxoffset + 2] = color[2];
bits[imgxoffset + 3] = color[3];
imgxoffset += 4;
} // for x
} // for z
} }
@ -317,11 +458,12 @@ void BiomeView::mouseMoveEvent(QMouseEvent * a_Event)
// Update the status bar info text: // Update the status bar info text:
int blockX = floor((a_Event->x() - width() / 2) / m_Zoom + m_X); int blockX = floor((a_Event->x() - width() / 2) / m_Zoom + m_X);
int blockZ = floor((a_Event->y() - height() / 2) / m_Zoom + m_Z); int blockZ = floor((a_Event->y() - height() / 2) / m_Zoom + m_Z);
int chunkX, chunkZ; int regionX, regionZ;
int relX = blockX, relY, relZ = blockZ; Region::blockToRegion(blockX, blockZ, regionX, regionZ);
cChunkDef::AbsoluteToRelative(relX, relY, relZ, chunkX, chunkZ); int relX = blockX - regionX * 512;
auto chunk = m_Cache.fetch(chunkX, chunkZ); int relZ = blockZ - regionZ * 512;
int biome = (chunk.get() != nullptr) ? chunk->getBiome(relX, relZ) : biInvalidBiome; auto region = m_Cache.fetch(regionX, regionZ);
int biome = (region.get() != nullptr) ? region->getRelBiome(relX, relZ) : biInvalidBiome;
emit hoverChanged(blockX, blockZ, biome); emit hoverChanged(blockX, blockZ, biome);
} }

View File

@ -2,7 +2,7 @@
#include <QWidget> #include <QWidget>
#include <memory> #include <memory>
#include "ChunkCache.h" #include "RegionCache.h"
#include "ChunkSource.h" #include "ChunkSource.h"
@ -51,8 +51,8 @@ public slots:
/** Redraw the entire widget area. */ /** Redraw the entire widget area. */
void redraw(); void redraw();
/** A specified chunk has become available, redraw it. */ /** A specified region has become available, redraw it. */
void chunkAvailable(int a_ChunkX, int a_ChunkZ); void regionAvailable(int a_RegionX, int a_RegionZ);
/** Reloads the current chunk source and redraws the entire workspace. */ /** Reloads the current chunk source and redraws the entire workspace. */
void reload(); void reload();
@ -62,7 +62,7 @@ protected:
double m_Zoom; double m_Zoom;
/** Cache for the loaded chunk data. */ /** Cache for the loaded chunk data. */
ChunkCache m_Cache; RegionCache m_Cache;
/** The entire view's contents in an offscreen image. */ /** The entire view's contents in an offscreen image. */
QImage m_Image; QImage m_Image;
@ -79,6 +79,9 @@ protected:
/** Data used for rendering a chunk that hasn't been loaded yet */ /** Data used for rendering a chunk that hasn't been loaded yet */
uchar m_EmptyChunkImage[16 * 16 * 4]; uchar m_EmptyChunkImage[16 * 16 * 4];
/** Data placeholder for chunks that aren't valid. */
short m_EmptyChunkBiomes[16 * 16];
/** Draws the specified chunk into m_Image */ /** Draws the specified chunk into m_Image */
void drawChunk(int a_ChunkX, int a_ChunkZ); void drawChunk(int a_ChunkX, int a_ChunkZ);

View File

@ -1,126 +0,0 @@
#include "Globals.h"
#include "ChunkCache.h"
#include <QMutexLocker>
#include <QThreadPool>
#include "ChunkSource.h"
#include "ChunkLoader.h"
ChunkCache::ChunkCache(QObject * parent) :
super(parent)
{
m_Cache.setMaxCost(1024 * 1024 * 1024); // 1 GiB of memory for the cache
}
ChunkPtr ChunkCache::fetch(int a_ChunkX, int a_ChunkZ)
{
// Retrieve from the cache:
quint32 hash = getChunkHash(a_ChunkX, a_ChunkZ);
ChunkPtr * res;
{
QMutexLocker lock(&m_Mtx);
res = m_Cache[hash];
// If succesful and chunk loaded, return the retrieved value:
if ((res != nullptr) && (*res)->isValid())
{
return *res;
}
}
// If the chunk is in cache but not valid, it means it has been already queued for rendering, do nothing now:
if (res != nullptr)
{
return ChunkPtr(nullptr);
}
// There's no such item in the cache, create it now:
res = new ChunkPtr(new Chunk);
if (res == nullptr)
{
return ChunkPtr(nullptr);
}
{
QMutexLocker lock(&m_Mtx);
m_Cache.insert(hash, res, sizeof(Chunk));
}
// Queue the chunk for rendering:
queueChunkRender(a_ChunkX, a_ChunkZ, *res);
// Return failure, the chunk is not yet rendered:
return ChunkPtr(nullptr);
}
void ChunkCache::setChunkSource(std::shared_ptr<ChunkSource> a_ChunkSource)
{
// Replace the chunk source:
m_ChunkSource = a_ChunkSource;
// Clear the cache:
QMutexLocker lock(&m_Mtx);
m_Cache.clear();
}
void ChunkCache::reload()
{
assert(m_ChunkSource.get() != nullptr);
// Reload the chunk source:
m_ChunkSource->reload();
// Clear the cache:
QMutexLocker lock(&m_Mtx);
m_Cache.clear();
}
void ChunkCache::gotChunk(int a_ChunkX, int a_ChunkZ)
{
emit chunkAvailable(a_ChunkX, a_ChunkZ);
}
quint32 ChunkCache::getChunkHash(int a_ChunkX, int a_ChunkZ)
{
// Simply join the two coords into a single int
// The coords will never be larger than 16-bits, so we can do this safely
return (((static_cast<quint32>(a_ChunkX) & 0xffff) << 16) | (static_cast<quint32>(a_ChunkZ) & 0xffff));
}
void ChunkCache::queueChunkRender(int a_ChunkX, int a_ChunkZ, ChunkPtr & a_Chunk)
{
// Create a new loader task:
ChunkLoader * loader = new ChunkLoader(a_ChunkX, a_ChunkZ, a_Chunk, m_ChunkSource);
connect(loader, SIGNAL(loaded(int, int)), this, SLOT(gotChunk(int, int)));
QThreadPool::globalInstance()->start(loader);
}

View File

@ -1,29 +0,0 @@
#include "Globals.h"
#include "ChunkLoader.h"
#include "ChunkSource.h"
ChunkLoader::ChunkLoader(int a_ChunkX, int a_ChunkZ, ChunkPtr a_Chunk, ChunkSourcePtr a_ChunkSource) :
m_ChunkX(a_ChunkX),
m_ChunkZ(a_ChunkZ),
m_Chunk(a_Chunk),
m_ChunkSource(a_ChunkSource)
{
}
void ChunkLoader::run()
{
m_ChunkSource->getChunkBiomes(m_ChunkX, m_ChunkZ, m_Chunk);
emit loaded(m_ChunkX, m_ChunkZ);
}

View File

@ -1,45 +0,0 @@
#pragma once
#include <QObject>
#include <QRunnable>
#include <memory>
// fwd:
class Chunk;
typedef std::shared_ptr<Chunk> ChunkPtr;
class ChunkSource;
typedef std::shared_ptr<ChunkSource> ChunkSourcePtr;
class ChunkLoader :
public QObject,
public QRunnable
{
Q_OBJECT
public:
ChunkLoader(int a_ChunkX, int a_ChunkZ, ChunkPtr a_Chunk, ChunkSourcePtr a_ChunkSource);
virtual ~ChunkLoader() {}
signals:
void loaded(int a_ChunkX, int a_ChunkZ);
protected:
virtual void run() override;
private:
int m_ChunkX, m_ChunkZ;
ChunkPtr m_Chunk;
ChunkSourcePtr m_ChunkSource;
};

View File

@ -24,14 +24,14 @@ BioGenSource::BioGenSource(cIniFilePtr a_IniFile) :
void BioGenSource::getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChunk) void BioGenSource::getChunkBiomes(int a_ChunkX, int a_ChunkZ, Chunk & a_DestChunk)
{ {
cChunkDef::BiomeMap biomes; cChunkDef::BiomeMap biomes;
{ {
QMutexLocker lock(&m_Mtx); QMutexLocker lock(&m_Mtx);
m_BiomeGen->GenBiomes(a_ChunkX, a_ChunkZ, biomes); m_BiomeGen->GenBiomes(a_ChunkX, a_ChunkZ, biomes);
} }
a_DestChunk->setBiomes(biomes); a_DestChunk.setBiomes(biomes);
} }
@ -160,7 +160,7 @@ AnvilSource::AnvilSource(QString a_WorldRegionFolder) :
void AnvilSource::getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChunk) void AnvilSource::getChunkBiomes(int a_ChunkX, int a_ChunkZ, Chunk & a_DestChunk)
{ {
// Load the compressed data: // Load the compressed data:
AString compressedChunkData = getCompressedChunkData(a_ChunkX, a_ChunkZ); AString compressedChunkData = getCompressedChunkData(a_ChunkX, a_ChunkZ);
@ -200,7 +200,7 @@ void AnvilSource::getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChun
{ {
biomeMap[i] = (EMCSBiome)GetBEInt(beBiomes + 4 * i); biomeMap[i] = (EMCSBiome)GetBEInt(beBiomes + 4 * i);
} }
a_DestChunk->setBiomes(biomeMap); a_DestChunk.setBiomes(biomeMap);
return; return;
} }
@ -216,7 +216,7 @@ void AnvilSource::getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChun
{ {
biomeMap[i] = EMCSBiome(vanillaBiomes[i]); biomeMap[i] = EMCSBiome(vanillaBiomes[i]);
} }
a_DestChunk->setBiomes(biomeMap); a_DestChunk.setBiomes(biomeMap);
} }
@ -260,7 +260,7 @@ AnvilSource::AnvilFilePtr AnvilSource::getAnvilFile(int a_ChunkX, int a_ChunkZ)
// Search the cache for the file: // Search the cache for the file:
QMutexLocker lock(&m_Mtx); QMutexLocker lock(&m_Mtx);
for (auto itr = m_Files.cbegin(), end = m_Files.cend(); itr != end; ++itr) for (auto itr = m_Files.begin(), end = m_Files.end(); itr != end; ++itr)
{ {
if (((*itr)->m_RegionX == RegionX) && ((*itr)->m_RegionZ == RegionZ)) if (((*itr)->m_RegionX == RegionX) && ((*itr)->m_RegionZ == RegionZ))
{ {

View File

@ -10,7 +10,7 @@
// fwd: // fwd:
class cBiomeGen; class cBiomeGen;
typedef std::shared_ptr<cBiomeGen> cBiomeGenPtr; typedef SharedPtr<cBiomeGen> cBiomeGenPtr;
class cIniFile; class cIniFile;
typedef std::shared_ptr<cIniFile> cIniFilePtr; typedef std::shared_ptr<cIniFile> cIniFilePtr;
@ -26,7 +26,7 @@ public:
/** Fills the a_DestChunk with the biomes for the specified coords. /** Fills the a_DestChunk with the biomes for the specified coords.
It is expected to be thread-safe and re-entrant. Usually QThread::idealThreadCount() threads are used. */ It is expected to be thread-safe and re-entrant. Usually QThread::idealThreadCount() threads are used. */
virtual void getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChunk) = 0; virtual void getChunkBiomes(int a_ChunkX, int a_ChunkZ, Chunk & a_DestChunk) = 0;
/** Forces a fresh reload of the source. Useful mainly for the generator, whose underlying definition file may have been changed. */ /** Forces a fresh reload of the source. Useful mainly for the generator, whose underlying definition file may have been changed. */
virtual void reload() = 0; virtual void reload() = 0;
@ -45,7 +45,7 @@ public:
BioGenSource(cIniFilePtr a_IniFile); BioGenSource(cIniFilePtr a_IniFile);
// ChunkSource overrides: // ChunkSource overrides:
virtual void getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChunk) override; virtual void getChunkBiomes(int a_ChunkX, int a_ChunkZ, Chunk & a_DestChunk) override;
virtual void reload(void) override; virtual void reload(void) override;
protected: protected:
@ -70,7 +70,7 @@ public:
AnvilSource(QString a_WorldRegionFolder); AnvilSource(QString a_WorldRegionFolder);
// ChunkSource overrides: // ChunkSource overrides:
virtual void getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChunk) override; virtual void getChunkBiomes(int a_ChunkX, int a_ChunkZ, Chunk & a_DestChunk) override;
virtual void reload() override; virtual void reload() override;
protected: protected:

View File

@ -8,12 +8,13 @@
#include <QSettings> #include <QSettings>
#include <QDirIterator> #include <QDirIterator>
#include <QStatusBar> #include <QStatusBar>
#include "src/IniFile.h"
#include "ChunkSource.h" #include "ChunkSource.h"
#include "src/IniFile.h"
#include "src/Generating/BioGen.h" #include "src/Generating/BioGen.h"
#include "src/StringCompression.h" #include "src/StringCompression.h"
#include "src/WorldStorage/FastNBT.h" #include "src/WorldStorage/FastNBT.h"
#include "GeneratorSetup.h" #include "GeneratorSetup.h"
#include "RegionLoader.h"
@ -70,7 +71,7 @@ MainWindow::MainWindow(QWidget * parent) :
MainWindow::~MainWindow() MainWindow::~MainWindow()
{ {
RegionLoader::shutdown();
} }
@ -172,7 +173,8 @@ void MainWindow::setViewZoom()
{ {
return; return;
} }
double newZoom = m_ViewZooms[action->data().toInt()]; m_CurrentZoomLevel = action->data().toInt();
double newZoom = m_ViewZooms[m_CurrentZoomLevel];
m_BiomeView->setZoomLevel(newZoom); m_BiomeView->setZoomLevel(newZoom);
action->setChecked(true); action->setChecked(true);
} }

View File

@ -12,7 +12,7 @@ TARGET = QtBiomeVisualiser
TEMPLATE = app TEMPLATE = app
SOURCES +=\ SOURCES += \
MainWindow.cpp \ MainWindow.cpp \
BiomeView.cpp \ BiomeView.cpp \
../../src/Generating/BioGen.cpp \ ../../src/Generating/BioGen.cpp \
@ -26,9 +26,6 @@ SOURCES +=\
../../src/OSSupport/CriticalSection.cpp \ ../../src/OSSupport/CriticalSection.cpp \
../../src/OSSupport/IsThread.cpp \ ../../src/OSSupport/IsThread.cpp \
../../src/BiomeDef.cpp \ ../../src/BiomeDef.cpp \
ChunkCache.cpp \
ChunkSource.cpp \
ChunkLoader.cpp \
../../src/StringCompression.cpp \ ../../src/StringCompression.cpp \
../../src/WorldStorage/FastNBT.cpp \ ../../src/WorldStorage/FastNBT.cpp \
../../lib/zlib/adler32.c \ ../../lib/zlib/adler32.c \
@ -48,13 +45,20 @@ SOURCES +=\
../../lib/zlib/zutil.c \ ../../lib/zlib/zutil.c \
GeneratorSetup.cpp \ GeneratorSetup.cpp \
QtBiomeVisualiser.cpp \ QtBiomeVisualiser.cpp \
QtChunk.cpp QtChunk.cpp \
RegionCache.cpp \
Region.cpp \
ChunkSource.cpp \
RegionLoader.cpp
HEADERS += MainWindow.h \
HEADERS += \
MainWindow.h \
QtChunk.h \
Globals.h \ Globals.h \
BiomeView.h \ BiomeView.h \
../../src/Generating/BioGen.h \ ../../src/Generating/BioGen.h \
../../src/Generating/IntGen.h \
../../src/VoronoiMap.h \ ../../src/VoronoiMap.h \
../../src/Noise.h \ ../../src/Noise.h \
../../src/StringUtils.h \ ../../src/StringUtils.h \
@ -65,9 +69,6 @@ HEADERS += MainWindow.h \
../../src/OSSupport/CriticalSection.h \ ../../src/OSSupport/CriticalSection.h \
../../src/OSSupport/IsThread.h \ ../../src/OSSupport/IsThread.h \
../../src/BiomeDef.h \ ../../src/BiomeDef.h \
ChunkCache.h \
ChunkSource.h \
ChunkLoader.h \
../../src/StringCompression.h \ ../../src/StringCompression.h \
../../src/WorldStorage/FastNBT.h \ ../../src/WorldStorage/FastNBT.h \
../../lib/zlib/crc32.h \ ../../lib/zlib/crc32.h \
@ -82,7 +83,13 @@ HEADERS += MainWindow.h \
../../lib/zlib/zlib.h \ ../../lib/zlib/zlib.h \
../../lib/zlib/zutil.h \ ../../lib/zlib/zutil.h \
GeneratorSetup.h \ GeneratorSetup.h \
QtChunk.h QtChunk.h \
RegionCache.h \
Region.h \
ChunkSource.h \
RegionLoader.h
INCLUDEPATH += $$_PRO_FILE_PWD_ \ INCLUDEPATH += $$_PRO_FILE_PWD_ \
$$_PRO_FILE_PWD_/../../lib \ $$_PRO_FILE_PWD_/../../lib \

View File

@ -5,138 +5,6 @@
/** Map for converting biome values to colors. Initialized from biomeColors[]. */
static uchar biomeToColor[256 * 4];
/** Map for converting biome values to colors. Used to initialize biomeToColor[].*/
static struct
{
EMCSBiome m_Biome;
uchar m_Color[3];
} biomeColors[] =
{
{ biOcean, { 0x00, 0x00, 0x70 }, },
{ biPlains, { 0x8d, 0xb3, 0x60 }, },
{ biDesert, { 0xfa, 0x94, 0x18 }, },
{ biExtremeHills, { 0x60, 0x60, 0x60 }, },
{ biForest, { 0x05, 0x66, 0x21 }, },
{ biTaiga, { 0x0b, 0x66, 0x59 }, },
{ biSwampland, { 0x2f, 0xff, 0xda }, },
{ biRiver, { 0x30, 0x30, 0xaf }, },
{ biHell, { 0x7f, 0x00, 0x00 }, },
{ biSky, { 0x00, 0x7f, 0xff }, },
{ biFrozenOcean, { 0xa0, 0xa0, 0xdf }, },
{ biFrozenRiver, { 0xa0, 0xa0, 0xff }, },
{ biIcePlains, { 0xff, 0xff, 0xff }, },
{ biIceMountains, { 0xa0, 0xa0, 0xa0 }, },
{ biMushroomIsland, { 0xff, 0x00, 0xff }, },
{ biMushroomShore, { 0xa0, 0x00, 0xff }, },
{ biBeach, { 0xfa, 0xde, 0x55 }, },
{ biDesertHills, { 0xd2, 0x5f, 0x12 }, },
{ biForestHills, { 0x22, 0x55, 0x1c }, },
{ biTaigaHills, { 0x16, 0x39, 0x33 }, },
{ biExtremeHillsEdge, { 0x7f, 0x8f, 0x7f }, },
{ biJungle, { 0x53, 0x7b, 0x09 }, },
{ biJungleHills, { 0x2c, 0x42, 0x05 }, },
{ biJungleEdge, { 0x62, 0x8b, 0x17 }, },
{ biDeepOcean, { 0x00, 0x00, 0x30 }, },
{ biStoneBeach, { 0xa2, 0xa2, 0x84 }, },
{ biColdBeach, { 0xfa, 0xf0, 0xc0 }, },
{ biBirchForest, { 0x30, 0x74, 0x44 }, },
{ biBirchForestHills, { 0x1f, 0x5f, 0x32 }, },
{ biRoofedForest, { 0x40, 0x51, 0x1a }, },
{ biColdTaiga, { 0x31, 0x55, 0x4a }, },
{ biColdTaigaHills, { 0x59, 0x7d, 0x72 }, },
{ biMegaTaiga, { 0x59, 0x66, 0x51 }, },
{ biMegaTaigaHills, { 0x59, 0x66, 0x59 }, },
{ biExtremeHillsPlus, { 0x50, 0x70, 0x50 }, },
{ biSavanna, { 0xbd, 0xb2, 0x5f }, },
{ biSavannaPlateau, { 0xa7, 0x9d, 0x64 }, },
{ biMesa, { 0xd9, 0x45, 0x15 }, },
{ biMesaPlateauF, { 0xb0, 0x97, 0x65 }, },
{ biMesaPlateau, { 0xca, 0x8c, 0x65 }, },
// M variants:
{ biSunflowerPlains, { 0xb5, 0xdb, 0x88 }, },
{ biDesertM, { 0xff, 0xbc, 0x40 }, },
{ biExtremeHillsM, { 0x88, 0x88, 0x88 }, },
{ biFlowerForest, { 0x2d, 0x8e, 0x49 }, },
{ biTaigaM, { 0x33, 0x8e, 0x81 }, },
{ biSwamplandM, { 0x07, 0xf9, 0xb2 }, },
{ biIcePlainsSpikes, { 0xb4, 0xdc, 0xdc }, },
{ biJungleM, { 0x7b, 0xa3, 0x31 }, },
{ biJungleEdgeM, { 0x62, 0x8b, 0x17 }, },
{ biBirchForestM, { 0x58, 0x9c, 0x6c }, },
{ biBirchForestHillsM, { 0x47, 0x87, 0x5a }, },
{ biRoofedForestM, { 0x68, 0x79, 0x42 }, },
{ biColdTaigaM, { 0x24, 0x3f, 0x36 }, },
{ biMegaSpruceTaiga, { 0x45, 0x4f, 0x3e }, },
{ biMegaSpruceTaigaHills, { 0x45, 0x4f, 0x4e }, },
{ biExtremeHillsPlusM, { 0x78, 0x98, 0x78 }, },
{ biSavannaM, { 0xe5, 0xda, 0x87 }, },
{ biSavannaPlateauM, { 0xa7, 0x9d, 0x74 }, },
{ biMesaBryce, { 0xff, 0x6d, 0x3d }, },
{ biMesaPlateauFM, { 0xd8, 0xbf, 0x8d }, },
{ biMesaPlateauM, { 0xf2, 0xb4, 0x8d }, },
} ;
static class BiomeColorsInitializer
{
public:
BiomeColorsInitializer(void)
{
// Reset all colors to gray:
for (size_t i = 0; i < ARRAYCOUNT(biomeToColor); i++)
{
biomeToColor[i] = 0x7f;
}
// Set known biomes to their colors:
for (size_t i = 0; i < ARRAYCOUNT(biomeColors); i++)
{
uchar * color = &biomeToColor[4 * biomeColors[i].m_Biome];
color[0] = biomeColors[i].m_Color[2];
color[1] = biomeColors[i].m_Color[1];
color[2] = biomeColors[i].m_Color[0];
color[3] = 0xff;
}
}
} biomeColorInitializer;
/** Converts biomes in an array into the chunk image data. */
static void biomesToImage(const cChunkDef::BiomeMap & a_Biomes, Chunk::Image & a_Image)
{
// Make sure the two arrays are of the same size, compile-time.
// Note that a_Image is actually 4 items per pixel, so the array is 4 times bigger:
static const char Check1[4 * ARRAYCOUNT(a_Biomes) - ARRAYCOUNT(a_Image) + 1] = {};
static const char Check2[ARRAYCOUNT(a_Image) - 4 * ARRAYCOUNT(a_Biomes) + 1] = {};
// Convert the biomes into color:
for (size_t i = 0; i < ARRAYCOUNT(a_Biomes); i++)
{
a_Image[4 * i + 0] = biomeToColor[4 * a_Biomes[i] + 0];
a_Image[4 * i + 1] = biomeToColor[4 * a_Biomes[i] + 1];
a_Image[4 * i + 2] = biomeToColor[4 * a_Biomes[i] + 2];
a_Image[4 * i + 3] = biomeToColor[4 * a_Biomes[i] + 3];
}
}
////////////////////////////////////////////////////////////////////////////////
// Chunk:
Chunk::Chunk() : Chunk::Chunk() :
m_IsValid(false) m_IsValid(false)
{ {
@ -146,20 +14,12 @@ Chunk::Chunk() :
const uchar * Chunk::getImage(void) const
{
ASSERT(m_IsValid);
return m_Image;
}
void Chunk::setBiomes(const cChunkDef::BiomeMap & a_Biomes) void Chunk::setBiomes(const cChunkDef::BiomeMap & a_Biomes)
{ {
memcpy(m_Biomes, a_Biomes, sizeof(m_Biomes)); for (size_t idx = 0; idx < ARRAYCOUNT(a_Biomes); ++idx)
renderBiomes(); {
m_Biomes[idx] = static_cast<short>(a_Biomes[idx]);
}
m_IsValid = true; m_IsValid = true;
} }
@ -173,16 +33,7 @@ EMCSBiome Chunk::getBiome(int a_RelX, int a_RelZ)
{ {
return biInvalidBiome; return biInvalidBiome;
} }
return cChunkDef::GetBiome(m_Biomes, a_RelX, a_RelZ); return static_cast<EMCSBiome>(m_Biomes[a_RelX + 16 * a_RelZ]);
}
void Chunk::renderBiomes()
{
biomesToImage(m_Biomes, m_Image);
} }

View File

@ -18,9 +18,6 @@ public:
/** Returns true iff the chunk data is valid - loaded or generated. */ /** Returns true iff the chunk data is valid - loaded or generated. */
bool isValid(void) const { return m_IsValid; } bool isValid(void) const { return m_IsValid; }
/** Returns the image of the chunk's biomes. Assumes that the chunk is valid. */
const uchar * getImage(void) const;
/** Sets the biomes to m_Biomes and renders them into m_Image. */ /** Sets the biomes to m_Biomes and renders them into m_Image. */
void setBiomes(const cChunkDef::BiomeMap & a_Biomes); void setBiomes(const cChunkDef::BiomeMap & a_Biomes);
@ -28,19 +25,16 @@ public:
Coords must be valid inside this chunk. */ Coords must be valid inside this chunk. */
EMCSBiome getBiome(int a_RelX, int a_RelZ); EMCSBiome getBiome(int a_RelX, int a_RelZ);
/** Returns the raw biome data for this chunk. */
const short * getBiomes(void) const { return m_Biomes; }
protected: protected:
/** Flag that specifies if the chunk data is valid - loaded or generated. */ /** Flag that specifies if the chunk data is valid - loaded or generated. */
bool m_IsValid; bool m_IsValid;
/** Cached rendered image of this chunk's biomes. Updated in render(). */ /** Biomes comprising the chunk, in the X + 16 * Z ordering.
Image m_Image; Typed as short to save on memory, converted automatically when needed. */
short m_Biomes[16 * 16];
/** Biomes comprising the chunk, in the X + 16 * Z ordering. */
cChunkDef::BiomeMap m_Biomes;
/** Renders biomes from m_Biomes into m_Image. */
void renderBiomes();
}; };
typedef std::shared_ptr<Chunk> ChunkPtr; typedef std::shared_ptr<Chunk> ChunkPtr;

View File

@ -0,0 +1,72 @@
#include "Globals.h"
#include "Region.h"
Region::Region()
{
}
Chunk & Region::getRelChunk(int a_RelChunkX, int a_RelChunkZ)
{
ASSERT(a_RelChunkX >= 0);
ASSERT(a_RelChunkZ >= 0);
ASSERT(a_RelChunkX < 32);
ASSERT(a_RelChunkZ < 32);
return m_Chunks[a_RelChunkX + a_RelChunkZ * 32];
}
int Region::getRelBiome(int a_RelBlockX, int a_RelBlockZ)
{
ASSERT(a_RelBlockX >= 0);
ASSERT(a_RelBlockZ >= 0);
ASSERT(a_RelBlockX < 512);
ASSERT(a_RelBlockZ < 512);
int chunkX = a_RelBlockX / 16;
int chunkZ = a_RelBlockZ / 16;
Chunk & chunk = m_Chunks[chunkX + 32 * chunkZ];
if (chunk.isValid())
{
return chunk.getBiome(a_RelBlockX - 16 * chunkX, a_RelBlockZ - 16 * chunkZ);
}
else
{
return biInvalidBiome;
}
}
void Region::blockToRegion(int a_BlockX, int a_BlockZ, int & a_RegionX, int & a_RegionZ)
{
a_RegionX = static_cast<int>(std::floor(static_cast<float>(a_BlockX) / 512));
a_RegionZ = static_cast<int>(std::floor(static_cast<float>(a_BlockZ) / 512));
}
void Region::chunkToRegion(int a_ChunkX, int a_ChunkZ, int & a_RegionX, int & a_RegionZ)
{
a_RegionX = static_cast<int>(std::floor(static_cast<float>(a_ChunkX) / 32));
a_RegionZ = static_cast<int>(std::floor(static_cast<float>(a_ChunkZ) / 32));
}

View File

@ -0,0 +1,46 @@
#pragma once
#include "QtChunk.h"
class Region
{
public:
Region();
/** Retrieves the chunk with the specified relative coords. */
Chunk & getRelChunk(int a_RelChunkX, int a_RelChunkZ);
/** Returns true iff the chunk data for all chunks has been loaded.
This doesn't mean that all the chunks are valid, only that the entire region has been processed and should
be displayed. */
bool isValid(void) const { return m_IsValid; }
/** Returns the biome in the block coords relative to this region.
Returns biInvalidBiome if the underlying chunk is not valid. */
int getRelBiome(int a_RelBlockX, int a_RelBlockZ);
/** Converts block coordinates into region coordinates. */
static void blockToRegion(int a_BlockX, int a_BlockZ, int & a_RegionX, int & a_RegionZ);
/** Converts chunk coordinates into region coordinates. */
static void chunkToRegion(int a_ChunkX, int a_ChunkZ, int & a_RegionX, int & a_RegionZ);
protected:
friend class RegionLoader;
Chunk m_Chunks[32 * 32];
/** True iff the data for all the chunks has been loaded.
This doesn't mean that all the chunks are valid, only that the entire region has been processed and should
be displayed. */
bool m_IsValid;
};

View File

@ -0,0 +1,138 @@
#include "Globals.h"
#include "RegionCache.h"
#include <QMutexLocker>
#include <QThreadPool>
#include "ChunkSource.h"
#include "RegionLoader.h"
#include "Region.h"
RegionCache::RegionCache(QObject * parent) :
super(parent)
{
m_Cache.setMaxCost(1024 * 1024 * 1024); // 1 GiB of memory for the cache
}
RegionPtr RegionCache::fetch(int a_RegionX, int a_RegionZ)
{
// Retrieve from the cache:
quint32 hash = getRegionHash(a_RegionX, a_RegionZ);
RegionPtr * res;
{
QMutexLocker lock(&m_Mtx);
res = m_Cache[hash];
// If succesful and region loaded, return the retrieved value:
if ((res != nullptr) && (*res)->isValid())
{
return *res;
}
}
// If the region is in cache but not valid, it means it has been already queued for rendering, do nothing now:
if (res != nullptr)
{
return RegionPtr(nullptr);
}
// There's no such item in the cache, create it now:
try
{
res = new RegionPtr(new Region);
}
catch (const std::bad_alloc &)
{
/* Allocation failed (32-bit process hit the 2 GiB barrier?)
This may happen even with the cache set to 1 GiB, because it contains shared ptrs and so they may be
held by another place in the code even when they are removed from cache.
*/
return RegionPtr(nullptr);
}
if (res == nullptr)
{
return RegionPtr(nullptr);
}
{
QMutexLocker lock(&m_Mtx);
m_Cache.insert(hash, res, sizeof(Region));
}
// Queue the region for rendering:
queueRegionRender(a_RegionX, a_RegionZ, *res);
// Return failure, the region is not yet rendered:
return RegionPtr(nullptr);
}
void RegionCache::setChunkSource(std::shared_ptr<ChunkSource> a_ChunkSource)
{
// Replace the chunk source:
m_ChunkSource = a_ChunkSource;
// Clear the cache:
QMutexLocker lock(&m_Mtx);
m_Cache.clear();
}
void RegionCache::reload()
{
assert(m_ChunkSource.get() != nullptr);
// Reload the chunk source:
m_ChunkSource->reload();
// Clear the cache:
QMutexLocker lock(&m_Mtx);
m_Cache.clear();
}
void RegionCache::gotRegion(int a_RegionX, int a_RegionZ)
{
emit regionAvailable(a_RegionX, a_RegionZ);
}
quint32 RegionCache::getRegionHash(int a_RegionX, int a_RegionZ)
{
// Simply join the two coords into a single int
// The coords will never be larger than 16-bits, so we can do this safely
return (((static_cast<quint32>(a_RegionX) & 0xffff) << 16) | (static_cast<quint32>(a_RegionZ) & 0xffff));
}
void RegionCache::queueRegionRender(int a_RegionX, int a_RegionZ, RegionPtr & a_Region)
{
// Create a new loader task:
RegionLoader * loader = new RegionLoader(a_RegionX, a_RegionZ, a_Region, m_ChunkSource);
connect(loader, SIGNAL(loaded(int, int)), this, SLOT(gotRegion(int, int)));
QThreadPool::globalInstance()->start(loader);
}

View File

@ -9,8 +9,9 @@
class Chunk; // fwd:
typedef std::shared_ptr<Chunk> ChunkPtr; class Region;
typedef std::shared_ptr<Region> RegionPtr;
class ChunkSource; class ChunkSource;
@ -18,19 +19,19 @@ class ChunkSource;
/** Caches chunk data for reuse */ /** Caches regions' chunk data for reuse */
class ChunkCache : class RegionCache :
public QObject public QObject
{ {
typedef QObject super; typedef QObject super;
Q_OBJECT Q_OBJECT
public: public:
explicit ChunkCache(QObject * parent = NULL); explicit RegionCache(QObject * parent = NULL);
/** Retrieves the specified chunk from the cache. /** Retrieves the specified region from the cache.
Only returns valid chunks; if the chunk is invalid, queues it for rendering and returns an empty ptr. */ Only returns valid regions; if the region is invalid, queues it for rendering and returns an empty ptr. */
ChunkPtr fetch(int a_ChunkX, int a_ChunkZ); RegionPtr fetch(int a_RegionX, int a_RegionZ);
/** Replaces the chunk source used by the biome view to get the chunk biome data. /** Replaces the chunk source used by the biome view to get the chunk biome data.
The cache is then invalidated. */ The cache is then invalidated. */
@ -43,16 +44,16 @@ public:
void reload(); void reload();
signals: signals:
void chunkAvailable(int a_ChunkX, int a_ChunkZ); void regionAvailable(int a_RegionX, int a_RegionZ);
protected slots: protected slots:
void gotChunk(int a_ChunkX, int a_ChunkZ); void gotRegion(int a_RegionX, int a_RegionZ);
protected: protected:
/** The cache of the chunks */ /** The cache of the chunks */
QCache<quint32, ChunkPtr> m_Cache; QCache<quint32, RegionPtr> m_Cache;
/** Locks te cache against multithreaded access */ /** Locks the cache against multithreaded access */
QMutex m_Mtx; QMutex m_Mtx;
/** The source used to get the biome data. */ /** The source used to get the biome data. */
@ -60,10 +61,10 @@ protected:
/** Returns the hash used by the chunk in the cache */ /** Returns the hash used by the chunk in the cache */
quint32 getChunkHash(int a_ChunkX, int a_ChunkZ); quint32 getRegionHash(int a_RegionX, int a_RegionZ);
/** Queues the specified chunk for rendering by m_ChunkSource. */ /** Queues the specified region for rendering by m_RegionSource. */
void queueChunkRender(int a_ChunkX, int a_ChunkZ, ChunkPtr & a_Chunk); void queueRegionRender(int a_RegionX, int a_RegionZ, RegionPtr & a_Region);
}; };

View File

@ -0,0 +1,49 @@
#include "Globals.h"
#include "RegionLoader.h"
#include "ChunkSource.h"
#include "Region.h"
volatile bool RegionLoader::m_IsShuttingDown = false;
RegionLoader::RegionLoader(int a_RegionX, int a_RegionZ, RegionPtr a_Region, ChunkSourcePtr a_ChunkSource) :
m_RegionX(a_RegionX),
m_RegionZ(a_RegionZ),
m_Region(a_Region),
m_ChunkSource(a_ChunkSource)
{
}
void RegionLoader::run()
{
// Load all the chunks in this region:
for (int z = 0; z < 32; z++)
{
for (int x = 0; x < 32; x++)
{
m_ChunkSource->getChunkBiomes(m_RegionX * 32 + x, m_RegionZ * 32 + z, m_Region->getRelChunk(x, z));
if (m_IsShuttingDown)
{
return;
}
}
}
m_Region->m_IsValid = true;
emit loaded(m_RegionX, m_RegionZ);
}

View File

@ -0,0 +1,56 @@
#pragma once
#include <QObject>
#include <QRunnable>
#include <memory>
// fwd:
class Region;
typedef std::shared_ptr<Region> RegionPtr;
class ChunkSource;
typedef std::shared_ptr<ChunkSource> ChunkSourcePtr;
class RegionLoader :
public QObject,
public QRunnable
{
Q_OBJECT
public:
RegionLoader(int a_RegionX, int a_RegionZ, RegionPtr a_Region, ChunkSourcePtr a_ChunkSource);
virtual ~RegionLoader() {}
/** Signals to all loaders that the app is shutting down and the loading should be aborted. */
static void shutdown() { m_IsShuttingDown = true; }
signals:
void loaded(int a_RegionX, int a_RegionZ);
protected:
virtual void run() override;
private:
/** Coords of the region to be loaded. */
int m_RegionX, m_RegionZ;
/** The region to be loaded. */
RegionPtr m_Region;
/** The chunk source to be used for individual chunks within the region. */
ChunkSourcePtr m_ChunkSource;
/** Flag that is set upon app exit to terminate the queued loaders faster. */
static volatile bool m_IsShuttingDown;
};

View File

@ -1,7 +1,13 @@
#pragma once #pragma once
// The following hackery is to allow typed C++ enum for C++ code, yet have ToLua process the values.
// ToLua doesn't understand typed enums, so we use preprocessor to hide it from ToLua.
enum ENUM_BLOCK_ID : BLOCKTYPE
#if 0
enum ENUM_BLOCK_ID // tolua_export
#endif
// tolua_begin // tolua_begin
enum ENUM_BLOCK_ID
{ {
E_BLOCK_AIR = 0, E_BLOCK_AIR = 0,
E_BLOCK_STONE = 1, E_BLOCK_STONE = 1,
@ -221,6 +227,10 @@ enum ENUM_BLOCK_ID
}; };
// tolua_end // tolua_end
// tolua_begin // tolua_begin
enum ENUM_ITEM_ID enum ENUM_ITEM_ID
{ {

View File

@ -184,7 +184,7 @@ void cChunkSender::Execute(void)
while (!m_ShouldTerminate) while (!m_ShouldTerminate)
{ {
cCSLock Lock(m_CS); cCSLock Lock(m_CS);
while (m_ChunksReady.empty() && m_SendChunksLowPriority.empty() && m_SendChunksHighPriority.empty()) while (m_ChunksReady.empty() && m_SendChunksLowPriority.empty() && m_SendChunksMediumPriority.empty() && m_SendChunksHighPriority.empty())
{ {
int RemoveCount = m_RemoveCount; int RemoveCount = m_RemoveCount;
m_RemoveCount = 0; m_RemoveCount = 0;

View File

@ -227,15 +227,15 @@ const cDistortedHeightmap::sGenParam cDistortedHeightmap::m_GenParam[256] =
/* biMesaPlateau */ { 2.0f, 2.0f}, // 39 /* biMesaPlateau */ { 2.0f, 2.0f}, // 39
// biomes 40 .. 128 are unused, 89 empty placeholders here: // biomes 40 .. 128 are unused, 89 empty placeholders here:
{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, // 40 .. 49 {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, // 40 .. 49
{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, // 50 .. 59 {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, // 50 .. 59
{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, // 60 .. 69 {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, // 60 .. 69
{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, // 70 .. 79 {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, // 70 .. 79
{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, // 80 .. 89 {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, // 80 .. 89
{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, // 90 .. 99 {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, // 90 .. 99
{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, // 100 .. 109 {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, // 100 .. 109
{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, // 110 .. 119 {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, // 110 .. 119
{}, {}, {}, {}, {}, {}, {}, {}, {}, // 120 .. 128 {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, // 120 .. 128
// Release 1.7 /* biome variants: // Release 1.7 /* biome variants:
/* biSunflowerPlains */ { 1.0f, 1.0f}, // 129 /* biSunflowerPlains */ { 1.0f, 1.0f}, // 129
@ -246,22 +246,22 @@ const cDistortedHeightmap::sGenParam cDistortedHeightmap::m_GenParam[256] =
/* biSwamplandM */ { 0.0f, 0.0f}, // 134 /* biSwamplandM */ { 0.0f, 0.0f}, // 134
// Biomes 135 .. 139 unused, 5 empty placeholders here: // Biomes 135 .. 139 unused, 5 empty placeholders here:
{}, {}, {}, {}, {}, // 135 .. 139 {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, // 135 .. 139
/* biIcePlainsSpikes */ { 1.0f, 1.0f}, // 140 /* biIcePlainsSpikes */ { 1.0f, 1.0f}, // 140
// Biomes 141 .. 148 unused, 8 empty placeholders here: // Biomes 141 .. 148 unused, 8 empty placeholders here:
{}, {}, {}, {}, {}, {}, {}, {}, // 141 .. 148 {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, // 141 .. 148
/* biJungleM */ { 4.0f, 4.0f}, // 149 /* biJungleM */ { 4.0f, 4.0f}, // 149
{}, // 150 {0.0f, 0.0f}, // 150
/* biJungleEdgeM */ { 3.0f, 3.0f}, // 151 /* biJungleEdgeM */ { 3.0f, 3.0f}, // 151
{}, {}, {}, // 152 .. 154 {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, // 152 .. 154
/* biBirchForestM */ { 3.0f, 3.0f}, // 155 /* biBirchForestM */ { 3.0f, 3.0f}, // 155
/* biBirchForestHillsM */ { 5.0f, 5.0f}, // 156 /* biBirchForestHillsM */ { 5.0f, 5.0f}, // 156
/* biRoofedForestM */ { 2.0f, 2.0f}, // 157 /* biRoofedForestM */ { 2.0f, 2.0f}, // 157
/* biColdTaigaM */ { 1.0f, 1.0f}, // 158 /* biColdTaigaM */ { 1.0f, 1.0f}, // 158
{}, // 159 {0.0f, 0.0f}, // 159
/* biMegaSpruceTaiga */ { 3.0f, 3.0f}, // 160 /* biMegaSpruceTaiga */ { 3.0f, 3.0f}, // 160
/* biMegaSpruceTaigaHills */ { 3.0f, 3.0f}, // 161 /* biMegaSpruceTaigaHills */ { 3.0f, 3.0f}, // 161
/* biExtremeHillsPlusM */ {32.0f, 32.0f}, // 162 /* biExtremeHillsPlusM */ {32.0f, 32.0f}, // 162

View File

@ -414,6 +414,11 @@ void cFinishGenSnow::GenFinish(cChunkDesc & a_ChunkDesc)
} }
break; break;
} }
default:
{
// There's no snow in the other biomes.
break;
}
} }
} }
} // for z } // for z
@ -454,6 +459,11 @@ void cFinishGenIce::GenFinish(cChunkDesc & a_ChunkDesc)
} }
break; break;
} }
default:
{
// No icy water in other biomes.
break;
}
} }
} }
} // for z } // for z

View File

@ -430,15 +430,15 @@ const cHeiGenBiomal::sGenParam cHeiGenBiomal::m_GenParam[256] =
/* biMesaPlateau */ { 0.1f, 1.0f, 0.05f, 1.5f, 0.01f, 4.0f, 80}, /* biMesaPlateau */ { 0.1f, 1.0f, 0.05f, 1.5f, 0.01f, 4.0f, 80},
// biomes 40 .. 128 are unused, 89 empty placeholders here: // biomes 40 .. 128 are unused, 89 empty placeholders here:
{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, // 40 .. 49 {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, // 40 .. 49
{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, // 50 .. 59 {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, // 50 .. 59
{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, // 60 .. 69 {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, // 60 .. 69
{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, // 70 .. 79 {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, // 70 .. 79
{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, // 80 .. 89 {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, // 80 .. 89
{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, // 90 .. 99 {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, // 90 .. 99
{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, // 100 .. 109 {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, // 100 .. 109
{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, // 110 .. 119 {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, // 110 .. 119
{}, {}, {}, {}, {}, {}, {}, {}, {}, // 120 .. 128 {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, // 120 .. 128
/* biSunflowerPlains */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 129 /* biSunflowerPlains */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 129
/* biDesertM */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 130 /* biDesertM */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 130
@ -448,22 +448,22 @@ const cHeiGenBiomal::sGenParam cHeiGenBiomal::m_GenParam[256] =
/* biSwamplandM */ { 1.0f, 3.0f, 1.10f, 7.0f, 0.01f, 0.01f, 60}, // 134 /* biSwamplandM */ { 1.0f, 3.0f, 1.10f, 7.0f, 0.01f, 0.01f, 60}, // 134
// Biomes 135 .. 139 unused, 5 empty placeholders here: // Biomes 135 .. 139 unused, 5 empty placeholders here:
{}, {}, {}, {}, {}, // 135 .. 139 {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, // 135 .. 139
/* biIcePlainsSpikes */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 140 /* biIcePlainsSpikes */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 140
// Biomes 141 .. 148 unused, 8 empty placeholders here: // Biomes 141 .. 148 unused, 8 empty placeholders here:
{}, {}, {}, {}, {}, {}, {}, {}, // 141 .. 148 {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, // 141 .. 148
/* biJungleM */ { 0.1f, 3.0f, 0.05f, 6.0f, 0.01f, 6.0f, 70}, // 149 /* biJungleM */ { 0.1f, 3.0f, 0.05f, 6.0f, 0.01f, 6.0f, 70}, // 149
{}, // 150 {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, // 150
/* biJungleEdgeM */ { 0.1f, 3.0f, 0.05f, 6.0f, 0.01f, 6.0f, 70}, // 151 /* biJungleEdgeM */ { 0.1f, 3.0f, 0.05f, 6.0f, 0.01f, 6.0f, 70}, // 151
{}, {}, {}, // 152 .. 154 {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, // 152 .. 154
/* biBirchForestM */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 70}, // 155 /* biBirchForestM */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 70}, // 155
/* biBirchForestHillsM */ { 0.2f, 2.0f, 0.05f, 10.0f, 0.01f, 8.0f, 80}, // 156 /* biBirchForestHillsM */ { 0.2f, 2.0f, 0.05f, 10.0f, 0.01f, 8.0f, 80}, // 156
/* biRoofedForestM */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 70}, // 157 /* biRoofedForestM */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 70}, // 157
/* biColdTaigaM */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 70}, // 158 /* biColdTaigaM */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 70}, // 158
{}, // 159 {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, // 159
/* biMegaSpruceTaiga */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 70}, // 160 /* biMegaSpruceTaiga */ { 0.1f, 1.0f, 0.05f, 2.0f, 0.01f, 4.0f, 70}, // 160
/* biMegaSpruceTaigaHills */ { 0.2f, 2.0f, 0.05f, 10.0f, 0.01f, 8.0f, 80}, // 161 /* biMegaSpruceTaigaHills */ { 0.2f, 2.0f, 0.05f, 10.0f, 0.01f, 8.0f, 80}, // 161
/* biExtremeHillsPlusM */ { 0.2f, 4.0f, 0.05f, 20.0f, 0.01f, 16.0f, 120}, // 162 /* biExtremeHillsPlusM */ { 0.2f, 4.0f, 0.05f, 20.0f, 0.01f, 16.0f, 120}, // 162

View File

@ -9,7 +9,7 @@
// Email: Shane.Hill@dsto.defence.gov.au // Email: Shane.Hill@dsto.defence.gov.au
// Reason: Remove dependancy on MFC. Code should compile on any // Reason: Remove dependancy on MFC. Code should compile on any
// platform. // platform.
////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/* /*
!! MODIFIED BY FAKETRUTH and xoft !! !! MODIFIED BY FAKETRUTH and xoft !!
@ -79,7 +79,7 @@ bool cIniFile::ReadFile(const AString & a_FileName, bool a_AllowExampleRedirect)
} }
} }
bool IsFirstLine = true; bool IsFirstLine = true;
while (getline(f, line)) while (getline(f, line))
{ {
@ -866,7 +866,7 @@ AString cIniFile::CheckCase(const AString & s) const
void cIniFile::RemoveBom(AString & a_line) const void cIniFile::RemoveBom(AString & a_line) const
{ {
// The BOM sequence for UTF-8 is 0xEF,0xBB,0xBF // The BOM sequence for UTF-8 is 0xEF, 0xBB, 0xBF
static unsigned const char BOM[] = { 0xEF, 0xBB, 0xBF }; static unsigned const char BOM[] = { 0xEF, 0xBB, 0xBF };
// The BOM sequence, if present, is always th e first three characters of the input. // The BOM sequence, if present, is always th e first three characters of the input.

View File

@ -9,7 +9,7 @@
// Email: Shane.Hill@dsto.defence.gov.au // Email: Shane.Hill@dsto.defence.gov.au
// Reason: Remove dependancy on MFC. Code should compile on any // Reason: Remove dependancy on MFC. Code should compile on any
// platform. Tested on Windows/Linux/Irix // platform. Tested on Windows/Linux/Irix
////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/* /*
!! MODIFIED BY FAKETRUTH and madmaxoft!! !! MODIFIED BY FAKETRUTH and madmaxoft!!

View File

@ -604,6 +604,28 @@ void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster)
m_Writer.AddByte("IsConverting", (((const cZombie *)a_Monster)->IsConverting() ? 1 : 0)); m_Writer.AddByte("IsConverting", (((const cZombie *)a_Monster)->IsConverting() ? 1 : 0));
break; break;
} }
case mtInvalidType:
case mtBlaze:
case mtCaveSpider:
case mtChicken:
case mtCow:
case mtEnderDragon:
case mtGhast:
case mtGiant:
case mtIronGolem:
case mtMooshroom:
case mtOcelot:
case mtPig:
case mtSilverfish:
case mtSnowGolem:
case mtSpider:
case mtSquid:
case mtWitch:
case mtZombiePigman:
{
// Other mobs have no special tags.
break;
}
} }
m_Writer.EndCompound(); m_Writer.EndCompound();
} }