summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Tools/AnvilStats/Globals.h11
-rw-r--r--Tools/AnvilStats/Statistics.cpp87
-rw-r--r--Tools/AnvilStats/Statistics.h3
3 files changed, 96 insertions, 5 deletions
diff --git a/Tools/AnvilStats/Globals.h b/Tools/AnvilStats/Globals.h
index df1430cc4..21d54739a 100644
--- a/Tools/AnvilStats/Globals.h
+++ b/Tools/AnvilStats/Globals.h
@@ -241,6 +241,17 @@ public:
+/** Clamp value to the specified range. */
+template <typename T>
+T Clamp(T a_Value, T a_Min, T a_Max)
+{
+ return (a_Value < a_Min) ? a_Min : ((a_Value > a_Max) ? a_Max : a_Value);
+}
+
+
+
+
+
// Common headers (part 2, with macros):
#include "../../src/ChunkDef.h"
#include "../../src/BlockID.h"
diff --git a/Tools/AnvilStats/Statistics.cpp b/Tools/AnvilStats/Statistics.cpp
index f7519fd37..11b9f09c5 100644
--- a/Tools/AnvilStats/Statistics.cpp
+++ b/Tools/AnvilStats/Statistics.cpp
@@ -26,9 +26,11 @@ cStatistics::cStats::cStats(void) :
m_MinChunkZ(0x7fffffff),
m_MaxChunkZ(0x80000000)
{
- memset(m_BiomeCounts, 0, sizeof(m_BiomeCounts));
- memset(m_BlockCounts, 0, sizeof(m_BlockCounts));
- memset(m_SpawnerEntity, 0, sizeof(m_SpawnerEntity));
+ memset(m_BiomeCounts, 0, sizeof(m_BiomeCounts));
+ memset(m_BlockCounts, 0, sizeof(m_BlockCounts));
+ memset(m_PerHeightBlockCounts, 0, sizeof(m_PerHeightBlockCounts));
+ memset(m_PerHeightSpawners, 0, sizeof(m_PerHeightSpawners));
+ memset(m_SpawnerEntity, 0, sizeof(m_SpawnerEntity));
}
@@ -46,6 +48,11 @@ void cStatistics::cStats::Add(const cStatistics::cStats & a_Stats)
for (int j = 0; j <= 255; j++)
{
m_BlockCounts[i][j] += a_Stats.m_BlockCounts[i][j];
+ m_PerHeightBlockCounts[i][j] += a_Stats.m_PerHeightBlockCounts[i][j];
+ }
+ for (int j = 0; j < ARRAYCOUNT(m_PerHeightSpawners[0]); j++)
+ {
+ m_PerHeightSpawners[i][j] += a_Stats.m_PerHeightSpawners[i][j];
}
}
for (int i = 0; i < ARRAYCOUNT(m_SpawnerEntity); i++)
@@ -149,6 +156,7 @@ bool cStatistics::OnSection
for (int y = 0; y < 16; y++)
{
+ int Height = (int)a_Y * 16 + y;
for (int z = 0; z < 16; z++)
{
for (int x = 0; x < 16; x++)
@@ -156,6 +164,7 @@ bool cStatistics::OnSection
unsigned char Biome = m_BiomeData[x + 16 * z]; // Cannot use cChunkDef, different datatype
unsigned char BlockType = cChunkDef::GetBlock(a_BlockTypes, x, y, z);
m_Stats.m_BlockCounts[Biome][BlockType] += 1;
+ m_Stats.m_PerHeightBlockCounts[Height][BlockType] += 1;
}
}
}
@@ -259,16 +268,27 @@ bool cStatistics::OnTileTick(
void cStatistics::OnSpawner(cParsedNBT & a_NBT, int a_TileEntityTag)
{
+ // Get the spawned entity type:
int EntityIDTag = a_NBT.FindChildByName(a_TileEntityTag, "EntityId");
if ((EntityIDTag < 0) || (a_NBT.GetType(EntityIDTag) != TAG_String))
{
return;
}
eEntityType Ent = GetEntityType(a_NBT.GetString(EntityIDTag));
- if (Ent < ARRAYCOUNT(m_Stats.m_SpawnerEntity))
+ if (Ent >= ARRAYCOUNT(m_Stats.m_SpawnerEntity))
+ {
+ return;
+ }
+ m_Stats.m_SpawnerEntity[Ent] += 1;
+
+ // Get the spawner pos:
+ int PosYTag = a_NBT.FindChildByName(a_TileEntityTag, "y");
+ if ((PosYTag < 0) || (a_NBT.GetType(PosYTag) != TAG_Int))
{
- m_Stats.m_SpawnerEntity[Ent] += 1;
+ return;
}
+ int BlockY = Clamp(a_NBT.GetInt(PosYTag), 0, 255);
+ m_Stats.m_PerHeightSpawners[BlockY][Ent] += 1;
}
@@ -316,6 +336,8 @@ cStatisticsFactory::~cStatisticsFactory()
SaveBiomes();
LOG(" BlockTypes.xls");
SaveBlockTypes();
+ LOG(" PerHeightBlockTypes.xls");
+ SavePerHeightBlockTypes();
LOG(" BiomeBlockTypes.xls");
SaveBiomeBlockTypes();
LOG(" Spawners.xls");
@@ -395,6 +417,61 @@ void cStatisticsFactory::SaveBlockTypes(void)
+void cStatisticsFactory::SavePerHeightBlockTypes(void)
+{
+ // Export as two tables: biomes 0-127 and 128-255, because OpenOffice doesn't support more than 256 columns
+
+ cFile f;
+ if (!f.Open("PerHeightBlockTypes.xls", cFile::fmWrite))
+ {
+ LOG("Cannot write to file PerHeightBlockTypes.xls. Statistics not written.");
+ return;
+ }
+
+ // Write header:
+ f.Printf("Blocks 0 - 127:\nHeight\t");
+ for (int i = 0; i < 128; i++)
+ {
+ f.Printf("\t%s(%d)", GetBlockTypeString(i), i);
+ }
+ f.Printf("\n");
+
+ // Write first half:
+ for (int y = 0; y < 256; y++)
+ {
+ f.Printf("%d", y);
+ for (int BlockType = 0; BlockType < 128; BlockType++)
+ {
+ f.Printf("\t%d", m_CombinedStats.m_PerHeightBlockCounts[y][BlockType]);
+ } // for BlockType
+ f.Printf("\n");
+ } // for y - height (0 - 127)
+ f.Printf("\n");
+
+ // Write second header:
+ f.Printf("Blocks 128 - 255:\nHeight\t");
+ for (int i = 128; i < 256; i++)
+ {
+ f.Printf("\t%s(%d)", GetBlockTypeString(i), i);
+ }
+ f.Printf("\n");
+
+ // Write second half:
+ for (int y = 0; y < 256; y++)
+ {
+ f.Printf("%d", y);
+ for (int BlockType = 128; BlockType < 256; BlockType++)
+ {
+ f.Printf("\t%d", m_CombinedStats.m_PerHeightBlockCounts[y][BlockType]);
+ } // for BlockType
+ f.Printf("\n");
+ } // for y - height (0 - 127)
+}
+
+
+
+
+
void cStatisticsFactory::SaveBiomeBlockTypes(void)
{
// Export as two tables: biomes 0-127 and 128-255, because OpenOffice doesn't support more than 256 columns
diff --git a/Tools/AnvilStats/Statistics.h b/Tools/AnvilStats/Statistics.h
index 53e353f22..f6165edd9 100644
--- a/Tools/AnvilStats/Statistics.h
+++ b/Tools/AnvilStats/Statistics.h
@@ -31,6 +31,8 @@ public:
UInt64 m_NumEntities;
UInt64 m_NumTileEntities;
UInt64 m_NumTileTicks;
+ UInt64 m_PerHeightBlockCounts[256][256]; // First dimension is the height, second dimension is BlockType
+ UInt64 m_PerHeightSpawners[256][entMax + 1]; // First dimension is the height, second dimension is spawned entity type
int m_MinChunkX, m_MaxChunkX; // X coords range
int m_MinChunkZ, m_MaxChunkZ; // Z coords range
@@ -128,6 +130,7 @@ protected:
void JoinResults(void);
void SaveBiomes(void);
void SaveBlockTypes(void);
+ void SavePerHeightBlockTypes(void);
void SaveBiomeBlockTypes(void);
void SaveStatistics(void);
void SaveSpawners(void);