summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MCServer/items.ini12
-rw-r--r--MCServer/lang/items_de.ini603
-rw-r--r--Tools/QtBiomeVisualiser/ChunkSource.cpp241
-rw-r--r--Tools/QtBiomeVisualiser/ChunkSource.h34
-rw-r--r--Tools/QtBiomeVisualiser/GeneratorSetupDlg.cpp125
-rw-r--r--Tools/QtBiomeVisualiser/GeneratorSetupDlg.h53
-rw-r--r--Tools/QtBiomeVisualiser/MainWindow.cpp217
-rw-r--r--Tools/QtBiomeVisualiser/MainWindow.h45
-rw-r--r--Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro40
-rw-r--r--src/Entities/Entity.cpp4
-rw-r--r--src/Entities/Minecart.cpp4
-rw-r--r--src/Generating/Caves.cpp2
-rw-r--r--src/Generating/Noise3DGenerator.cpp4
-rw-r--r--src/LineBlockTracer.cpp21
-rw-r--r--src/Tracer.cpp2
-rw-r--r--src/WorldStorage/FastNBT.cpp2
16 files changed, 1358 insertions, 51 deletions
diff --git a/MCServer/items.ini b/MCServer/items.ini
index 380c13e02..daf366654 100644
--- a/MCServer/items.ini
+++ b/MCServer/items.ini
@@ -1,5 +1,6 @@
[Items]
air=0
+stone=1
rock=1
granite=1:1
polishedgranite=1:2
@@ -7,7 +8,6 @@ diorite=1:3
polisheddiorite=1:4
andesite=1:5
polishedandesite=1:6
-stone=1
grass=2
dirt=3
coarseddirt=3:1
@@ -410,7 +410,7 @@ lightgraystainedclay=159:8
lightgreystainedclay=159:8
ltgraystainedclay=159:8
ltgreystainedclay=159:8
-silvertsainedclay=159:8
+silverstainedclay=159:8
cyanstainedclay=159:9
purplestainedclay=159:10
violetstainedclay=159:10
@@ -471,6 +471,7 @@ darkoakwoodstairs=164
bigoakwoodstiars=164
roofedoakwoodstairs=164
slimeblock=165
+barrier=166
irontrapdoor=167
prismarine=168
prismarinebricks=168:1
@@ -525,7 +526,8 @@ redsandstone=179
chiseledredsandstone=179:1
smoothredsandstone=179:2
redsandstonestairs=180
-redsandstoneslab=182
+newstoneslab=182
+redsandstoneslab=182:0
sprucefencegate=183
coniferfencegate=183
pinefencegate=183
@@ -698,7 +700,11 @@ lightdust=348
glowdust=348
fish=349
rawfish=349
+rawsalmon=349:1
+clownfish=349:2
+pufferfish=349:3
cookedfish=350
+cookedsalmon=350:1
dye=351
inksac=351:0
blackdye=351:0
diff --git a/MCServer/lang/items_de.ini b/MCServer/lang/items_de.ini
new file mode 100644
index 000000000..3c2ab87d1
--- /dev/null
+++ b/MCServer/lang/items_de.ini
@@ -0,0 +1,603 @@
+[Items]
+luft=0
+stein=1
+granit=1:1
+poliertergranit=1:2
+diorit=1:3
+polierterdiorit=1:4
+andesit=1:5
+polierterandesit=1:6
+grasblock=2
+erde=3
+grobeerde=3:1
+podsol=3:2
+bruchstein=4
+holzbretter=5
+eichenholzbretter=5:0
+fichtenholzbretter=5:1
+birkenholzbretter=5:2
+tropenholzbretter=5:3
+akazienholzbretter=5:4
+schwarzeichenholzbretter=5:5
+setzling=6
+eichensetzling=6:0
+fichtensetzling=6:1
+birkensetzling=6:2
+tropensetzling=6:3
+akaziensetzling=6:4
+schwarzeichensetzling=6:5
+grundgestein=7
+wasser=8
+fliessendeswasser=8
+stehendeswasser=9
+stilleswasser=9
+swasser=9
+lava=10
+fliessendelava=10
+stehendelava=11
+stillelava=11
+slava=11
+sand=12
+rotersand=12:1
+kies=13
+golderz=14
+eisenerz=15
+kohleerz=16
+stamm=17
+eichenholz=17:0
+fichtenholz=17:1
+birkenholz=17:2
+tropenholz=17:3
+laub=18
+eichenlaub=18:0
+fichtenlaub=18:1
+birkenlaub=18:2
+tropenlaub=18:3
+schwamm=19
+nasserschwamm=19:1
+glas=20
+lapislazulierz=21
+lapislazuliblock=22
+werfer=23
+sandstein=24
+normalersandstein=24:0
+gemeisseltersandstein=24:1
+glattersandstein=24:2
+notenblock=25
+bettblock=26
+antriebsschiene=27
+sensorschiene=28
+klebrigerkolben=29
+spinnenweben=30
+gras=31
+gras=31:1
+farn=31:2
+toterbusch=32
+kolben=33
+kolbenkopf=34
+wolle=35
+weissewolle=35:0
+orangenewolle=35:1
+magentawolle=35:2
+hellblauewolle=35:3
+gelbewolle=35:4
+hellgruene=35:5
+rosawolle=35:6
+grauwool=35:7
+greywool=35:7
+grauewolle=35:7
+hellgrauewolle=35:8
+tuerkisewolle=35:9
+violettewolle=35:10
+blauewolle=35:11
+braunewolle=35:12
+gruenewolle=35:13
+rotewolle=35:14
+schwarzewolle=35:15
+loewenzahn=37
+blume=38
+mohn=38:0
+blaueorchidee=38:1
+sternlauch=38:2
+porzellansternchen=38:3
+rotetulpe=38:4
+orangenetulpe=38:5
+weissetulpe=38:6
+rosatulpe=38:7
+margerite=38:8
+braunerpilz=39
+roterpilz=40
+goldblock=41
+eisenblock=42
+doppelstufe=43
+doppelsteinstufe=43:0
+doppelsandsteinstufe=43:1
+doppelholzstufe=43:2
+doppelbruchsteinstufe=43:3
+doppelziegelstufe=43:4
+doppelsteinziegelstufe=43:5
+doppelnetherziegelstufe=43:6
+doppelquarzstufe=43:7
+stufe=44
+steinstufe=44:0
+sandsteinstufe=44:1
+holzstufe=44:2
+bruchsteinstufe=44:3
+ziegelstufe=44:4
+steinziegelstufe=44:5
+netherziegelstufe=44:6
+quarzstufe=44:7
+ziegelsteine=45
+tnt=46
+buecherregal=47
+bemoosterbruchstein=48
+obsidian=49
+fackel=50
+feuer=51
+monsterspawner=52
+eichenholztreppe=53
+kiste=54
+rotstonekabel=55
+diamanterz=56
+diamantblock=57
+werkbank=58
+ernte=59
+farmland=60
+ofen=61
+brennenderofen=62
+schildblock=63
+holztuerblock=64
+leiter=65
+schiene=66
+bruchsteintreppe=67
+wandschild=68
+schalter=69
+steindruckplatte=70
+eisentuerblock=71
+holzdruckplatte=72
+rotstoneerz=73
+leuchtendesrotstoneerz=74
+erloschenerotstonefackel=75
+rotstonefackel=76
+setinknopf=77
+schnee=78
+eis=79
+schneeblock=80
+kaktus=81
+ton=82
+zuckerrohrblock=83
+plattenspieler=84
+eichenholzzaun=85
+kuerbis=86
+netherstein=87
+selensand=88
+leuchtstein=89
+portal=90
+kürbislaterne=91
+kuchenlock=92
+weissesglas=95
+orangenesglas=95:1
+magentaglas=95:2
+hellblauesglas=95:3
+gelbesglas=95:4
+hellgruenesglas=95:5
+rosagerfaerbtglas=95:6
+grauesglas=95:7
+hellgrauesglas=95:8
+tuerkisesglas=95:9
+violettesglas=95:10
+blauesglas=95:11
+braunesglas=95:12
+gruenesglas=95:13
+rotesglas=95:14
+schwarzesglas=95:15
+falltuer=96
+silberfischblock=97
+steinziegel=98
+bemoostesteinziegel=98:1
+rissigesteinziegel=98:2
+gemeisseltesteinziegel=98:3
+braunerpilzblock=99
+roterpilzblock=100
+eisengitter=101
+glasscheibe=102
+melone=103
+kuerbispflanze=104
+melonenpflanze=105
+ranken=106
+eichenholzzauntor=107
+ziegeltreppe=108
+steinziegeltreppe=109
+myzel=110
+seerosenblatt=111
+netherziegel=112
+netherziegelzaun=113
+netherziegeltreppe=114
+netherwarzenblock=115
+zaubertisch=116
+braustandblock=117
+kesselblock=118
+endportal=119
+endportalrahmen=120
+endstein=121
+drachenei=122
+redstonelampe=123
+erlosscheneredstonelampe=124
+doppelholzstufe=125
+doppeleichenholzstufe=125:0
+doppelfichtenholzstufe=125:1
+doppelbirkenholzstufe=125:2
+doppeltropenholzstufe=125:3
+doppelakazienholzstufe=125:4
+doppelschwarzeichenstufe=125:5
+holzstufe=126
+eichenholzstufe=126:0
+fichtenholzstufe=126:1
+birkenholzstufe=126:2
+tropenholzstufe=126:3
+akazienholzstufe=126:4
+schwarzeichenholzstufe=126:5
+kakaobohnen=127
+sandsteintreppe=128
+smaragderz=129
+endertruhe=130
+haken=131
+stolperdraht=132
+smaragdblock=133
+fichtenholztreppe=134
+birkenholztreppe=135
+tropenholztreppe=136
+kommandoblock=137
+leuchtfeuer=138
+bruchsteinmauer=139
+bemoostebruchsteinmauer=139:1
+blumentopfblock=140
+karottenpflanze=141
+kartoffelpflanze=142
+knopf=143
+skelettschaedel=144
+witherskelettschaedel=144:1
+zombieschaedel=144:2
+schaedel=144:3
+creeperschaedel=144:4
+amboss=145
+redstonetruhe=146
+waegeplatteniedrigegewichte=147 # WTF, that names are so stupid...
+waegeplattehohegewichte=148
+inaktiverkomparator=149
+aktiverkomparator=150
+tageslichtsensor=151
+redstoneblock=152
+netherquarzerz=153
+trichter=154
+quarzblock=155
+gemeisselterquarzblock=155:1
+quarzsaeule=155:2
+quarztreppe=156
+aktivierungsschiene=157
+spender=158
+weissgerfaerbterton=159
+orangegerfaerbterton=159:1
+magentagerfaerbterton=159:2
+hellblaugerfaerbterton=159:3
+gelbgerfaerbterton=159:4
+hellgruengerfaerbterton=159:5
+rosagerfaerbterton=159:6
+graugerfaerbterton=159:7
+hellgraugefaerbterton=159:8
+tuerkisgerfaerbterton=159:9
+purplegerfaerbterton=159:10
+violettegerfaerbterton=159:10
+blaugerfaerbterton=159:11
+braungerfaerbterton=159:12
+gruengerfaerbterton=159:13
+rotgerfaerbterton=159:14
+schwarzgerfaerbterton=159:15
+weisseglasscheibe=160
+orangeneglasscheibe=160:1
+magentaglasscheibe=160:2
+hellblaueglasscheibe=160:3
+gelbeglasscheibe=160:4
+hellgrueneglasscheibe=160:5
+rosaglasscheibe=160:6
+graueglasscheibe=160:7
+hellgraueglasscheibe=160:8
+tuerkiseglasscheibe=160:9
+violetteglasscheibe=160:10
+blaueglasscheibe=160:11
+brauneglasscheibe=160:12
+grueneglasscheibe=160:13
+roteglasscheibe=160:14
+schwarzeglasscheibe=160:15
+neueslaub=161
+akazienlaub=161:0
+schwarzeichenlaub=161:1
+neuestaemme=162
+akazienholz=162:0
+schwarzeichenholz=162:1
+akazientreppe=163
+schwarzeichentreppe=164
+schleimblock=165
+bartriere=166
+eisenfalltür=167
+prismarin=168
+prismarinziegel=168:1
+dunklerprismarin=168:2
+seelaterne=169
+strohballen=170
+teppich=171
+weisserteppich=171:0
+orangenerteppich=171:1
+magentateppich=171:2
+hellblauerteppich=171:3
+gelberteppich=171:4
+hellgruenerteppich=171:5
+rosateppich=171:6
+grauerteppich=171:7
+hellgrauerteppich=171:8
+tuerkiserteppich=171:9
+violetterteppich=171:10
+blauerteppich=171:11
+braunerteppich=171:12
+gruenerteppich=171:13
+roterteppich=171:14
+schwarzerteppich=171:15
+gebrannterton=172
+kohleblock=173
+packeis=174
+doppelpflanze=175
+sonnenblume=175:0
+Flieder=175:1
+hohesgras=175:2
+grosserfarn=175:3
+rosenstrauch=175:4
+pfingstrose=175:5
+rotersandstein=179
+gemeisselterrotersandstein=179:1
+glatterrotersandstein=179:2
+rotesandsteintreppe=180
+neuesteinstufe=182
+rotesandsteinstufe=182:0
+fichtenzauntor=183
+birkenzauntor=184
+tropenzauntor=185
+schwarzeichenzauntor=186
+akazienzauntor=187
+fichtenzaun=188
+birkenzaun=189
+tropenzaun=190
+schwarzeichenzaun=191
+akazienzaun=192
+eisenschaufel=256
+eisenspitzhacke=257
+eisenaxt=258
+feuerzeug=259
+apfel=260
+bogen=261
+pfeil=262
+kohle=263
+holzkohle=263:1
+diamant=264
+eisenbarren=265
+goldbarren=266
+eisenschwert=267
+holzschwert=268
+holzschaufel=269
+holzspitzhacke=270
+holzaxt=271
+steinschwert=272
+steinschaufel=273
+steinspitzhacke=274
+steinaxt=275
+diamantschwert=276
+diamantschaufel=277
+diamantspitzhacke=278
+diamantaxt=279
+stock=280
+schuessel=281
+pilzsuppe=282
+goldschwert=283
+goldschaufel=284
+goldspitzhacke=285
+goldaxt=286
+faden=287
+feder=288
+schwarzpulver=289
+holzhacke=290
+steinhacke=291
+eisenhacke=292
+diamanthacke=293
+goldhacke=294
+samen=295
+weizen=296
+brot=297
+lederkappe=298
+lederjacke=299
+lederhose=300
+lederstiefel=301
+kettenhaube=302
+kettenhemd=303
+kettenhose=304
+kettenstiefel=305
+eisenhelm=306
+eisenbrustplatte=307
+eisenbeinschutz=308
+eisenstiefel=309
+diamanthelm=310
+diamantbrustplatte=311
+diamantbeinschutz=312
+diamantstiefel=313
+goldhelm=314
+goldharnisch=315
+goldbeinschutz=316
+goldstiefel=317
+goldboots=317
+feuerstein=318
+rohesschweinefleisch=319
+gebratenesschweinefleisch=320
+gemaelde=321
+goldenerapfel=322
+goldenerapfel=322:1
+schild=323
+eichenholztuer=324
+eimer=325
+wassereimer=326
+lavaeimer=327
+lore=328
+sattel=329
+eisentuer=330
+redstone=331
+schneeballl=332
+boot=333
+leder=334
+milcht=335
+ziegel=336
+ton=337
+zuckercane=338
+papier=339
+buch=340
+schleimball=341
+gueterlore=342
+angetriebenelore=343
+ei=344
+kompass=345
+angel=346
+uhr=347
+glowstonestaub=348
+fisch=349
+roherfisch=349
+roherlachs=349:1
+clownfisch=349:2
+kugelfisch=349:3
+gebratenerfisch=350
+gebratenerlachs=350:1
+farbe=351
+tintenbeutel=351:0
+rosenrot=351:1
+kaktusgruen=351:2
+kakaobohnen=351:3
+lapislazuli=351:4
+violetterfarbstoff=351:5
+tuerkiserfarbstoff=351:6
+hellgrauerfarbstoff=351:7
+grauerfarbstoff=351:8
+rosafarbstoff=351:9
+hellgruenerfarbstoff=351:10
+gelberfarbstoff=351:11
+hellblauerfarbstoff=351:12
+magentafarbstoff=351:13
+orangenerfarbstoff=351:14
+knochenmehl=351:15
+knochen=352
+zucker=353
+kuchen=354
+bett=355
+redstoneverstaerker=356
+keks=357
+karte=358
+schere=359
+melone=360
+kürbiskerne=361
+melonenkerne=362
+rohesrindfleisch=363
+steak=364
+roheshühnchen=365
+gebrateneshühnchen=366
+verrottetesfleisch=367
+enderperle=368
+lohenrute=369
+ghasttraene=370
+goldnugget=371
+netherwarze=372
+trank=373
+glasflasche=374
+spinnenauge=375
+fermentiertesspinnenauge=376
+lohenstaub=377
+magmacreme=378
+braustand=379
+kessel=380
+enderauge=381
+glitzerndemelone=382
+spawnei=383
+erfahrungsfläschchen=384
+feuerkugel=385
+buchundfeder=386
+beschriebenesbuch=387
+smaragd=388
+rahmen=389
+blumentopf=390
+karotte=391
+kartoffel=392
+ofenkartoffel=393
+giftigekartoffel=394
+leerekarte=395
+goldenekarotte=396
+skelettschaedel=397
+witherschaedel=397:1
+zombieschaedel=397:2
+kopf=397:3
+creeperschaedel=397:4
+karottenrute=398
+netherstern=399
+kuerbiskuchen=400
+feuerwerksrakete=401
+feuerwerksstern=402
+verzauberungsbuch=403
+redstonekomparator=404
+netherziegelitem=405
+netherquarz=406
+tntlore=407
+trichterlore=408
+prismarinscherbe=409
+prismarinkristalle=410
+roheskaninchen=411
+gebrateneskaninchen=412
+kaninchenragout=413
+hasenpfote=414
+kaninchenfell=415
+ruestungsstaender=416
+eisernepferderuestung=417
+goldenepferderuestung=418
+diamantenepferderuestung=419
+leine=420
+namensschild=421
+kommandoblocklore=422
+roheshammelfleisch=423
+gebrateneshammelfleisch=424
+banner=425
+schwarzesbanner=415:0
+rotesbanner=415:1
+gruenesbanner=415:2
+braunbanner=415:3
+blauesbanner=415:4
+violettesbanner=415:5
+tuerkisesbanner=415:6
+hellgrauesbanner=415:7
+grauesbanner=415:8
+rosabanner=415:9
+hellgruenesbanner=415:10
+gelbesbanner=415:11
+hellblauesbanner=415:12
+magentabanner=415:13
+orangenesbanner=415:14
+weissesbanner=415:15
+fichtenholztuer=427
+birkenholztuer=428
+tropentuer=429
+akazientuer=430
+schwarzeichentuer=431
+goldeneschallplatte=2256
+grueneschallplatte=2257
+blocksschallplatte=2258
+chirpschallplatte=2259
+farschallplatte=2260
+mallschallplatte=2261
+mellohischallplatte=2262
+stalschallplatte=2263
+stradschallplatte=2264
+wardschallplatte=2265
+11schallplatte=2266
+
+
+
diff --git a/Tools/QtBiomeVisualiser/ChunkSource.cpp b/Tools/QtBiomeVisualiser/ChunkSource.cpp
index 2235816bc..54da2afe5 100644
--- a/Tools/QtBiomeVisualiser/ChunkSource.cpp
+++ b/Tools/QtBiomeVisualiser/ChunkSource.cpp
@@ -3,6 +3,8 @@
#include <QThread>
#include "Generating/BioGen.h"
#include "inifile/iniFile.h"
+#include "StringCompression.h"
+#include "WorldStorage/FastNBT.h"
@@ -182,3 +184,242 @@ void BioGenSource::reload()
+
+////////////////////////////////////////////////////////////////////////////////
+// AnvilSource::AnvilFile
+
+class AnvilSource::AnvilFile
+{
+public:
+ /** Coordinates of the region file. */
+ int m_RegionX, m_RegionZ;
+
+ /** True iff the file contains proper data. */
+ bool m_IsValid;
+
+
+
+ /** Creates a new instance with the specified region coords. Reads the file header. */
+ AnvilFile(int a_RegionX, int a_RegionZ, const AString & a_WorldPath) :
+ m_RegionX(a_RegionX),
+ m_RegionZ(a_RegionZ),
+ m_IsValid(false)
+ {
+ readFile(Printf("%s/r.%d.%d.mca", a_WorldPath.c_str(), a_RegionX, a_RegionZ));
+ }
+
+
+
+ /** Returns the compressed data of the specified chunk.
+ Returns an empty string when chunk not present. */
+ AString getChunkData(int a_ChunkX, int a_ChunkZ)
+ {
+ if (!m_IsValid)
+ {
+ return "";
+ }
+
+ // Translate to local coords:
+ int RelChunkX = a_ChunkX - m_RegionX * 32;
+ int RelChunkZ = a_ChunkZ - m_RegionZ * 32;
+ ASSERT((RelChunkX >= 0) && (RelChunkX < 32));
+ ASSERT((RelChunkZ >= 0) && (RelChunkZ < 32));
+
+ // Get the chunk data location:
+ UInt32 chunkOffset = m_Header[RelChunkX + 32 * RelChunkZ] >> 8;
+ UInt32 numChunkSectors = m_Header[RelChunkX + 32 * RelChunkZ] & 0xff;
+ if ((chunkOffset < 2) || (numChunkSectors == 0))
+ {
+ return "";
+ }
+
+ // Get the real data size:
+ const char * chunkData = m_FileData.data() + chunkOffset * 4096;
+ UInt32 chunkSize = GetBEInt(chunkData);
+ if ((chunkSize < 2) || (chunkSize / 4096 > numChunkSectors))
+ {
+ // Bad data, bail out
+ return "";
+ }
+
+ // Check the compression method:
+ if (chunkData[4] != 2)
+ {
+ // Chunk is in an unknown compression
+ return "";
+ }
+ chunkSize--;
+
+ // Read the chunk data:
+ return m_FileData.substr(chunkOffset * 4096 + 5, chunkSize);
+ }
+
+protected:
+ AString m_FileData;
+ UInt32 m_Header[2048];
+
+
+ /** Reads the whole specified file contents and parses the header. */
+ void readFile(const AString & a_FileName)
+ {
+ // Read the entire file:
+ m_FileData = cFile::ReadWholeFile(a_FileName);
+ if (m_FileData.size() < sizeof(m_Header))
+ {
+ return;
+ }
+
+ // Parse the header - change endianness:
+ const char * hdr = m_FileData.data();
+ for (size_t i = 0; i < ARRAYCOUNT(m_Header); i++)
+ {
+ m_Header[i] = GetBEInt(hdr + 4 * i);
+ }
+ m_IsValid = true;
+ }
+};
+
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+// AnvilSource:
+
+AnvilSource::AnvilSource(QString a_WorldRegionFolder) :
+ m_WorldRegionFolder(a_WorldRegionFolder)
+{
+}
+
+
+
+
+
+void AnvilSource::getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChunk)
+{
+ // Load the compressed data:
+ AString compressedChunkData = getCompressedChunkData(a_ChunkX, a_ChunkZ);
+ if (compressedChunkData.empty())
+ {
+ return;
+ }
+
+ // Uncompress the chunk data:
+ AString uncompressed;
+ int res = InflateString(compressedChunkData.data(), compressedChunkData.size(), uncompressed);
+ if (res != Z_OK)
+ {
+ return;
+ }
+
+ // Parse the NBT data:
+ cParsedNBT nbt(uncompressed.data(), uncompressed.size());
+ if (!nbt.IsValid())
+ {
+ return;
+ }
+
+ // Get the biomes out of the NBT:
+ int Level = nbt.FindChildByName(0, "Level");
+ if (Level < 0)
+ {
+ return;
+ }
+ cChunkDef::BiomeMap biomeMap;
+ int mcsBiomes = nbt.FindChildByName(Level, "MCSBiomes");
+ if ((mcsBiomes >= 0) && (nbt.GetDataLength(mcsBiomes) == sizeof(biomeMap)))
+ {
+ // Convert the biomes from BigEndian to platform native numbers:
+ const char * beBiomes = nbt.GetData(mcsBiomes);
+ for (size_t i = 0; i < ARRAYCOUNT(biomeMap); i++)
+ {
+ biomeMap[i] = (EMCSBiome)GetBEInt(beBiomes + 4 * i);
+ }
+ // Render the biomes:
+ Chunk::Image img;
+ biomesToImage(biomeMap, img);
+ a_DestChunk->setImage(img);
+ return;
+ }
+
+ // MCS biomes not found, load Vanilla biomes instead:
+ int biomes = nbt.FindChildByName(Level, "Biomes");
+ if ((biomes < 0) || (nbt.GetDataLength(biomes) != ARRAYCOUNT(biomeMap)))
+ {
+ return;
+ }
+ // Convert the biomes from Vanilla to EMCSBiome:
+ const char * vanillaBiomes = nbt.GetData(biomes);
+ for (size_t i = 0; i < ARRAYCOUNT(biomeMap); i++)
+ {
+ biomeMap[i] = EMCSBiome(vanillaBiomes[i]);
+ }
+ // Render the biomes:
+ Chunk::Image img;
+ biomesToImage(biomeMap, img);
+ a_DestChunk->setImage(img);
+}
+
+
+
+
+
+void AnvilSource::reload()
+{
+ // Remove all files from the cache:
+ QMutexLocker lock(&m_Mtx);
+ m_Files.clear();
+}
+
+
+
+
+
+void AnvilSource::chunkToRegion(int a_ChunkX, int a_ChunkZ, int & a_RegionX, int & a_RegionZ)
+{
+ a_RegionX = a_ChunkX >> 5;
+ a_RegionZ = a_ChunkZ >> 5;
+}
+
+
+
+
+
+AString AnvilSource::getCompressedChunkData(int a_ChunkX, int a_ChunkZ)
+{
+ return getAnvilFile(a_ChunkX, a_ChunkZ)->getChunkData(a_ChunkX, a_ChunkZ);
+}
+
+
+
+
+
+AnvilSource::AnvilFilePtr AnvilSource::getAnvilFile(int a_ChunkX, int a_ChunkZ)
+{
+ int RegionX, RegionZ;
+ chunkToRegion(a_ChunkX, a_ChunkZ, RegionX, RegionZ);
+
+ // Search the cache for the file:
+ QMutexLocker lock(&m_Mtx);
+ for (auto itr = m_Files.cbegin(), end = m_Files.cend(); itr != end; ++itr)
+ {
+ if (((*itr)->m_RegionX == RegionX) && ((*itr)->m_RegionZ == RegionZ))
+ {
+ // Found the file in the cache, move it to front and return it:
+ AnvilFilePtr file(*itr);
+ m_Files.erase(itr);
+ m_Files.push_front(file);
+ return file;
+ }
+ }
+
+ // File not in cache, create it:
+ AnvilFilePtr file(new AnvilFile(RegionX, RegionZ, m_WorldRegionFolder.toStdString()));
+ m_Files.push_front(file);
+ return file;
+}
+
+
+
+
+
diff --git a/Tools/QtBiomeVisualiser/ChunkSource.h b/Tools/QtBiomeVisualiser/ChunkSource.h
index 868e4a144..a5612da01 100644
--- a/Tools/QtBiomeVisualiser/ChunkSource.h
+++ b/Tools/QtBiomeVisualiser/ChunkSource.h
@@ -1,4 +1,5 @@
#pragma once
+#include "Globals.h"
#include <QString>
#include <QMutex>
#include "Chunk.h"
@@ -64,11 +65,40 @@ class AnvilSource :
public ChunkSource
{
public:
- // TODO
+ /** Constructs a new AnvilSource based on the world path. */
+ AnvilSource(QString a_WorldRegionFolder);
// ChunkSource overrides:
virtual void getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChunk) override;
- virtual void reload() override {}
+ virtual void reload() override;
+
+protected:
+ class AnvilFile;
+ typedef std::shared_ptr<AnvilFile> AnvilFilePtr;
+
+
+ /** Folder where the individual Anvil Region files are located. */
+ QString m_WorldRegionFolder;
+
+ /** List of currently loaded files. Acts as a cache so that a file is not opened and closed over and over again.
+ Protected against multithreaded access by m_Mtx. */
+ std::list<AnvilFilePtr> m_Files;
+
+ /** Guards m_Files agains multithreaded access. */
+ QMutex m_Mtx;
+
+
+ /** Converts chunk coords to region coords. */
+ void chunkToRegion(int a_ChunkX, int a_ChunkZ, int & a_RegionX, int & a_RegionZ);
+
+ /** Returns the compressed data of the specified chunk.
+ Returns an empty string if the chunk is not available. */
+ AString getCompressedChunkData(int a_ChunkX, int a_ChunkZ);
+
+ /** Returns the file object that contains the specified chunk.
+ The file is taken from the cache if available there, otherwise it is created anew. */
+ AnvilFilePtr getAnvilFile(int a_ChunkX, int a_ChunkZ);
+
};
diff --git a/Tools/QtBiomeVisualiser/GeneratorSetupDlg.cpp b/Tools/QtBiomeVisualiser/GeneratorSetupDlg.cpp
new file mode 100644
index 000000000..e6037fa9b
--- /dev/null
+++ b/Tools/QtBiomeVisualiser/GeneratorSetupDlg.cpp
@@ -0,0 +1,125 @@
+#include "Globals.h"
+#include "GeneratorSetupDlg.h"
+#include <QLabel>
+#include <QLineEdit>
+#include "Generating/BioGen.h"
+#include "inifile/iniFile.h"
+
+
+
+
+
+static const QString s_GeneratorNames[] =
+{
+ QString("Checkerboard"),
+ QString("Constant"),
+ QString("DistortedVoronoi"),
+ QString("MultiStepMap"),
+ QString("TwoLevel"),
+ QString("Voronoi"),
+};
+
+
+
+
+
+GeneratorSetupDlg::GeneratorSetupDlg(const AString & a_IniFileName, QWidget * a_Parent) :
+ super(a_Parent),
+ m_IniFile(new cIniFile())
+{
+ // The generator name is in a separate form layout at the top, always present:
+ m_cbGenerator = new QComboBox();
+ m_cbGenerator->setMinimumWidth(300);
+ for (size_t i = 0; i < ARRAYCOUNT(s_GeneratorNames); i++)
+ {
+ m_cbGenerator->addItem(s_GeneratorNames[i]);
+ }
+ QFormLayout * nameLayout = new QFormLayout();
+ nameLayout->addRow(new QLabel(tr("Generator")), m_cbGenerator);
+
+ // The rest of the controls are in a dynamically created form layout:
+ m_FormLayout = new QFormLayout();
+
+ // The main layout joins these two vertically:
+ m_MainLayout = new QVBoxLayout();
+ m_MainLayout->addLayout(nameLayout);
+ m_MainLayout->addLayout(m_FormLayout);
+ setLayout(m_MainLayout);
+
+ // Load the INI file, if specified, otherwise set defaults:
+ if (!a_IniFileName.empty() && m_IniFile->ReadFile(a_IniFileName))
+ {
+ m_cbGenerator->setCurrentText(QString::fromStdString(m_IniFile->GetValue("Generator", "BiomeGen")));
+ }
+ else
+ {
+ m_IniFile->SetValue("Generator", "Generator", "Composable");
+ m_IniFile->SetValue("Generator", "BiomeGen", m_cbGenerator->currentText().toStdString());
+ bool dummy;
+ delete cBiomeGen::CreateBiomeGen(*m_IniFile, m_Seed, dummy);
+ }
+ updateFromIni();
+
+ // Connect the combo change even only after the data has been loaded:
+ connect(m_cbGenerator, SIGNAL(currentIndexChanged(const QString &)), this, SLOT(generatorChanged(QString)));
+}
+
+
+
+
+
+void GeneratorSetupDlg::generatorChanged(const QString & a_NewName)
+{
+ // Clear the current contents of the form layout by assigning it to a stack temporary:
+ {
+ m_MainLayout->takeAt(1);
+ QWidget().setLayout(m_FormLayout);
+ }
+
+ // Re-create the layout:
+ m_FormLayout = new QFormLayout();
+ m_MainLayout->addLayout(m_FormLayout);
+
+ // Recreate the INI file:
+ m_IniFile->Clear();
+ m_IniFile->SetValue("Generator", "Generator", "Composable");
+ m_IniFile->SetValue("Generator", "BiomeGen", a_NewName.toStdString());
+
+ // Create a dummy biome gen from the INI file, this will create the defaults in the INI file:
+ bool dummy;
+ delete cBiomeGen::CreateBiomeGen(*m_IniFile, m_Seed, dummy);
+
+ // Read all values from the INI file and put them into the form layout:
+ updateFromIni();
+}
+
+
+
+
+
+void GeneratorSetupDlg::updateFromIni()
+{
+ int keyID = m_IniFile->FindKey("Generator");
+ if (keyID <= -1)
+ {
+ return;
+ }
+ int numItems = m_IniFile->GetNumValues(keyID);
+ for (int i = 0; i < numItems; i++)
+ {
+ AString itemName = m_IniFile->GetValueName(keyID, i);
+ AString itemValue = m_IniFile->GetValue(keyID, i);
+ if ((itemName == "Generator") || (itemName == "BiomeGen"))
+ {
+ // These special cases are not to be added
+ continue;
+ }
+ QLineEdit * edit = new QLineEdit();
+ edit->setText(QString::fromStdString(itemValue));
+ m_FormLayout->addRow(new QLabel(QString::fromStdString(itemName)), edit);
+ } // for i - INI values[]
+}
+
+
+
+
diff --git a/Tools/QtBiomeVisualiser/GeneratorSetupDlg.h b/Tools/QtBiomeVisualiser/GeneratorSetupDlg.h
new file mode 100644
index 000000000..d7070e331
--- /dev/null
+++ b/Tools/QtBiomeVisualiser/GeneratorSetupDlg.h
@@ -0,0 +1,53 @@
+#pragma once
+
+#include <memory>
+#include <QDialog>
+#include <QComboBox>
+#include <QVBoxLayout>
+#include <QFormLayout>
+
+
+
+
+
+class cIniFile;
+
+
+
+
+
+class GeneratorSetupDlg :
+ public QDialog
+{
+ typedef QDialog super;
+
+ Q_OBJECT
+
+public:
+ /** Creates the dialog and loads the contents of the INI file, if not empty. */
+ explicit GeneratorSetupDlg(const std::string & a_IniFileName, QWidget * parent = nullptr);
+
+signals:
+
+public slots:
+ /** Called when the user selects a different generator from the top combobox.
+ Re-creates m_IniFile and updates the form layout. */
+ void generatorChanged(const QString & a_NewName);
+
+protected:
+ QComboBox * m_cbGenerator;
+ QVBoxLayout * m_MainLayout;
+ QFormLayout * m_FormLayout;
+
+ std::unique_ptr<cIniFile> m_IniFile;
+
+ int m_Seed;
+
+
+ /** Updates the form layout with the values from m_IniFile. */
+ void updateFromIni();
+};
+
+
+
+
diff --git a/Tools/QtBiomeVisualiser/MainWindow.cpp b/Tools/QtBiomeVisualiser/MainWindow.cpp
index 65d0ccf5e..d2c1ae2c1 100644
--- a/Tools/QtBiomeVisualiser/MainWindow.cpp
+++ b/Tools/QtBiomeVisualiser/MainWindow.cpp
@@ -5,9 +5,14 @@
#include <QMenuBar>
#include <QApplication>
#include <QFileDialog>
+#include <QSettings>
+#include <QDirIterator>
#include "inifile/iniFile.h"
#include "ChunkSource.h"
#include "Generating/BioGen.h"
+#include "StringCompression.h"
+#include "WorldStorage/FastNBT.h"
+#include "GeneratorSetupDlg.h"
@@ -16,6 +21,8 @@
MainWindow::MainWindow(QWidget * parent) :
QMainWindow(parent)
{
+ initMinecraftPath();
+
m_BiomeView = new BiomeView(this);
setCentralWidget(m_BiomeView);
@@ -36,9 +43,37 @@ MainWindow::~MainWindow()
-void MainWindow::generate()
+void MainWindow::newGenerator()
+{
+ // TODO
+
+ // (Re-)open the generator setup dialog:
+ m_GeneratorSetupDlg.reset(new GeneratorSetupDlg(""));
+ m_GeneratorSetupDlg->show();
+ m_GeneratorSetupDlg->raise();
+
+ // TODO
+}
+
+
+
+
+
+void MainWindow::openGenerator()
{
+ // Let the user specify the world.ini file:
QString worldIni = QFileDialog::getOpenFileName(this, tr("Open world.ini"), QString(), tr("world.ini (world.ini)"));
+ if (worldIni.isEmpty())
+ {
+ return;
+ }
+
+ // (Re-)open the generator setup dialog:
+ m_GeneratorSetupDlg.reset(new GeneratorSetupDlg(worldIni.toStdString()));
+ m_GeneratorSetupDlg->show();
+ m_GeneratorSetupDlg->raise();
+
+ // Set the chunk source:
m_BiomeView->setChunkSource(std::shared_ptr<BioGenSource>(new BioGenSource(worldIni)));
m_BiomeView->redraw();
}
@@ -47,9 +82,66 @@ void MainWindow::generate()
-void MainWindow::open()
+void MainWindow::openWorld()
{
- // TODO
+ // Let the user specify the world:
+ QString regionFolder = QFileDialog::getExistingDirectory(this, tr("Select the region folder"), QString());
+ if (regionFolder.isEmpty())
+ {
+ return;
+ }
+
+ // Remove the generator setup dialog, if open:
+ if (m_GeneratorSetupDlg.get() != nullptr)
+ {
+ m_GeneratorSetupDlg->hide();
+ m_GeneratorSetupDlg.reset(nullptr);
+ }
+
+ // Set the chunk source:
+ m_BiomeView->setChunkSource(std::shared_ptr<AnvilSource>(new AnvilSource(regionFolder)));
+ m_BiomeView->redraw();
+}
+
+
+
+
+
+void MainWindow::openVanillaWorld()
+{
+ // The world is stored in the sender action's data, retrieve it:
+ QAction * action = qobject_cast<QAction *>(sender());
+ if (action == nullptr)
+ {
+ return;
+ }
+
+ // Remove the generator setup dialog, if open:
+ if (m_GeneratorSetupDlg.get() != nullptr)
+ {
+ m_GeneratorSetupDlg->hide();
+ m_GeneratorSetupDlg.reset(nullptr);
+ }
+
+ // Set the chunk source:
+ m_BiomeView->setChunkSource(std::shared_ptr<AnvilSource>(new AnvilSource(action->data().toString())));
+ m_BiomeView->redraw();
+}
+
+
+
+
+
+void MainWindow::initMinecraftPath()
+{
+ #ifdef Q_OS_MAC
+ m_MinecraftPath = QDir::homePath() + QDir::toNativeSeparators("/Library/Application Support/minecraft");
+ #elif defined Q_OS_WIN32
+ QSettings ini(QSettings::IniFormat, QSettings::UserScope, ".minecraft", "minecraft1");
+ m_MinecraftPath = QFileInfo(ini.fileName()).absolutePath();
+ #else
+ m_MinecraftPath = QDir::homePath() + QDir::toNativeSeparators("/.minecraft");
+ #endif
}
@@ -58,19 +150,26 @@ void MainWindow::open()
void MainWindow::createActions()
{
- m_actGen = new QAction(tr("&Generate..."), this);
- m_actGen->setShortcut(tr("Ctrl+N"));
- m_actGen->setStatusTip(tr("Open a generator INI file and display the generated biomes"));
- connect(m_actGen, SIGNAL(triggered()), this, SLOT(generate()));
+ createWorldActions();
+
+ m_actNewGen = new QAction(tr("&New generator"), this);
+ m_actNewGen->setShortcut(tr("Ctrl+N"));
+ m_actNewGen->setStatusTip(tr("Open a generator INI file and display the generated biomes"));
+ connect(m_actNewGen, SIGNAL(triggered()), this, SLOT(newGenerator()));
+
+ m_actOpenGen = new QAction(tr("&Open generator..."), this);
+ m_actOpenGen->setShortcut(tr("Ctrl+G"));
+ m_actOpenGen->setStatusTip(tr("Open a generator INI file and display the generated biomes"));
+ connect(m_actOpenGen, SIGNAL(triggered()), this, SLOT(openGenerator()));
- m_actOpen = new QAction(tr("&Open world..."), this);
- m_actOpen->setShortcut(tr("Ctrl+O"));
- m_actOpen->setStatusTip(tr("Open an existing world and display its biomes"));
- connect(m_actOpen, SIGNAL(triggered()), this, SLOT(open()));
+ m_actOpenWorld = new QAction(tr("&Open world..."), this);
+ m_actOpenWorld->setShortcut(tr("Ctrl+O"));
+ m_actOpenWorld->setStatusTip(tr("Open an existing world and display its biomes"));
+ connect(m_actOpenWorld, SIGNAL(triggered()), this, SLOT(openWorld()));
m_actReload = new QAction(tr("&Reload"), this);
m_actReload->setShortcut(tr("F5"));
- m_actReload->setStatusTip(tr("Open an existing world and display its biomes"));
+ m_actReload->setStatusTip(tr("Clear the view cache and force a reload of all the data"));
connect(m_actReload, SIGNAL(triggered()), m_BiomeView, SLOT(reload()));
m_actExit = new QAction(tr("E&xit"), this);
@@ -83,15 +182,95 @@ void MainWindow::createActions()
+void MainWindow::createWorldActions()
+{
+ QDir mc(m_MinecraftPath);
+ if (!mc.cd("saves"))
+ {
+ return;
+ }
+
+ QDirIterator it(mc);
+ int key = 1;
+ while (it.hasNext())
+ {
+ it.next();
+ if (!it.fileInfo().isDir())
+ {
+ continue;
+ }
+ QString name = getWorldName(it.filePath().toStdString());
+ if (name.isEmpty())
+ {
+ continue;
+ }
+ QAction * w = new QAction(this);
+ w->setText(name);
+ w->setData(it.filePath() + "/region");
+ if (key < 10)
+ {
+ w->setShortcut("Ctrl+" + QString::number(key));
+ key++;
+ }
+ connect(w, SIGNAL(triggered()), this, SLOT(openVanillaWorld()));
+ m_WorldActions.append(w);
+ }
+}
+
+
+
+
+
void MainWindow::createMenus()
{
- QMenu * mFile = menuBar()->addMenu(tr("&World"));
- mFile->addAction(m_actGen);
- mFile->addAction(m_actOpen);
- mFile->addSeparator();
- mFile->addAction(m_actReload);
- mFile->addSeparator();
- mFile->addAction(m_actExit);
+ QMenu * file = menuBar()->addMenu(tr("&Map"));
+ file->addAction(m_actNewGen);
+ file->addAction(m_actOpenGen);
+ file->addSeparator();
+ QMenu * worlds = file->addMenu(tr("Open existing"));
+ worlds->addActions(m_WorldActions);
+ if (m_WorldActions.empty())
+ {
+ worlds->setEnabled(false);
+ }
+ file->addAction(m_actOpenWorld);
+ file->addSeparator();
+ file->addAction(m_actReload);
+ file->addSeparator();
+ file->addAction(m_actExit);
+}
+
+
+
+
+
+QString MainWindow::getWorldName(const AString & a_Path)
+{
+ AString levelData = cFile::ReadWholeFile(a_Path + "/level.dat");
+ if (levelData.empty())
+ {
+ // No such file / no data
+ return QString();
+ }
+
+ AString uncompressed;
+ if (UncompressStringGZIP(levelData.data(), levelData.size(), uncompressed) != Z_OK)
+ {
+ return QString();
+ }
+ cParsedNBT nbt(uncompressed.data(), uncompressed.size());
+ if (!nbt.IsValid())
+ {
+ return QString();
+ }
+ AString name = nbt.GetName(1);
+ OutputDebugStringA(name.c_str());
+ int levelNameTag = nbt.FindTagByPath(nbt.GetRoot(), "Data\\LevelName");
+ if ((levelNameTag <= 0) || (nbt.GetType(levelNameTag) != TAG_String))
+ {
+ return QString();
+ }
+ return QString::fromStdString(nbt.GetString(levelNameTag));
}
diff --git a/Tools/QtBiomeVisualiser/MainWindow.h b/Tools/QtBiomeVisualiser/MainWindow.h
index b37bf4120..840e01b0f 100644
--- a/Tools/QtBiomeVisualiser/MainWindow.h
+++ b/Tools/QtBiomeVisualiser/MainWindow.h
@@ -1,5 +1,7 @@
#pragma once
+#include <memory>
+#include <QList>
#include <QMainWindow>
#include "BiomeView.h"
@@ -7,6 +9,13 @@
+// fwd:
+class GeneratorSetupDlg;
+
+
+
+
+
class MainWindow :
public QMainWindow
{
@@ -15,29 +24,55 @@ class MainWindow :
BiomeView * m_BiomeView;
public:
- MainWindow(QWidget *parent = 0);
+ MainWindow(QWidget * parent = nullptr);
~MainWindow();
private slots:
+ /** Creates a generator definition from scratch, lets user modify generator params in realtime. */
+ void newGenerator();
+
/** Opens a generator definition and generates the biomes based on that. */
- void generate();
+ void openGenerator();
/** Opens an existing world and displays the loaded biomes. */
- void open();
+ void openWorld();
+
+ /** Opens a vanilla world that is specified by the calling action. */
+ void openVanillaWorld();
protected:
// Actions:
- QAction * m_actGen;
- QAction * m_actOpen;
+ QAction * m_actNewGen;
+ QAction * m_actOpenGen;
+ QAction * m_actOpenWorld;
QAction * m_actReload;
QAction * m_actExit;
+ /** List of actions that open the specific vanilla world. */
+ QList<QAction *> m_WorldActions;
+
+ /** Path to the vanilla folder. */
+ QString m_MinecraftPath;
+
+ /** The dialog for setting up the generator. */
+ std::unique_ptr<GeneratorSetupDlg> m_GeneratorSetupDlg;
+
+
+ /** Initializes the m_MinecraftPath based on the proper MC path */
+ void initMinecraftPath();
/** Creates the actions that the UI supports. */
void createActions();
+ /** Creates the actions that open a specific vanilla world. Iterates over the minecraft saves folder. */
+ void createWorldActions();
+
/** Creates the menu bar and connects its events. */
void createMenus();
+
+ /** Returns the name of the vanilla world in the specified path.
+ Reads the level.dat file for the name. Returns an empty string on failure. */
+ QString getWorldName(const AString & a_Path);
};
diff --git a/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro b/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro
index e6b65e628..7171562bb 100644
--- a/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro
+++ b/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro
@@ -29,7 +29,25 @@ SOURCES += main.cpp\
ChunkCache.cpp \
Chunk.cpp \
ChunkSource.cpp \
- ChunkLoader.cpp
+ ChunkLoader.cpp \
+ ../../src/StringCompression.cpp \
+ ../../src/WorldStorage/FastNBT.cpp \
+ ../../lib/zlib/adler32.c \
+ ../../lib/zlib/compress.c \
+ ../../lib/zlib/crc32.c \
+ ../../lib/zlib/deflate.c \
+ ../../lib/zlib/gzclose.c \
+ ../../lib/zlib/gzlib.c \
+ ../../lib/zlib/gzread.c \
+ ../../lib/zlib/gzwrite.c \
+ ../../lib/zlib/infback.c \
+ ../../lib/zlib/inffast.c \
+ ../../lib/zlib/inflate.c \
+ ../../lib/zlib/inftrees.c \
+ ../../lib/zlib/trees.c \
+ ../../lib/zlib/uncompr.c \
+ ../../lib/zlib/zutil.c \
+ GeneratorSetupDlg.cpp
HEADERS += MainWindow.h \
Globals.h \
@@ -48,7 +66,21 @@ HEADERS += MainWindow.h \
ChunkCache.h \
Chunk.h \
ChunkSource.h \
- ChunkLoader.h
+ ChunkLoader.h \
+ ../../src/StringCompression.h \
+ ../../src/WorldStorage/FastNBT.h \
+ ../../lib/zlib/crc32.h \
+ ../../lib/zlib/deflate.h \
+ ../../lib/zlib/gzguts.h \
+ ../../lib/zlib/inffast.h \
+ ../../lib/zlib/inffixed.h \
+ ../../lib/zlib/inflate.h \
+ ../../lib/zlib/inftrees.h \
+ ../../lib/zlib/trees.h \
+ ../../lib/zlib/zconf.h \
+ ../../lib/zlib/zlib.h \
+ ../../lib/zlib/zutil.h \
+ GeneratorSetupDlg.h
INCLUDEPATH += $$_PRO_FILE_PWD_ \
$$_PRO_FILE_PWD_/../../src \
@@ -57,4 +89,8 @@ INCLUDEPATH += $$_PRO_FILE_PWD_ \
CONFIG += C++11
+OTHER_FILES += \
+ ../../lib/zlib/example.c.txt \
+ ../../lib/zlib/minigzip.c.txt
+
diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp
index 1b0b45736..c8ebc4314 100644
--- a/src/Entities/Entity.cpp
+++ b/src/Entities/Entity.cpp
@@ -260,7 +260,7 @@ void cEntity::TakeDamage(eDamageType a_DamageType, cEntity * a_Attacker, int a_R
void cEntity::SetYawFromSpeed(void)
{
const double EPS = 0.0000001;
- if ((abs(m_Speed.x) < EPS) && (abs(m_Speed.z) < EPS))
+ if ((std::abs(m_Speed.x) < EPS) && (std::abs(m_Speed.z) < EPS))
{
// atan2() may overflow or is undefined, pick any number
SetYaw(0);
@@ -277,7 +277,7 @@ void cEntity::SetPitchFromSpeed(void)
{
const double EPS = 0.0000001;
double xz = sqrt(m_Speed.x * m_Speed.x + m_Speed.z * m_Speed.z); // Speed XZ-plane component
- if ((abs(xz) < EPS) && (abs(m_Speed.y) < EPS))
+ if ((std::abs(xz) < EPS) && (std::abs(m_Speed.y) < EPS))
{
// atan2() may overflow or is undefined, pick any number
SetPitch(0);
diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp
index 1501eea84..bc9e21d8e 100644
--- a/src/Entities/Minecart.cpp
+++ b/src/Entities/Minecart.cpp
@@ -876,7 +876,7 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta)
Vector3d Distance = MinecartCollisionCallback.GetCollidedEntityPosition() - Vector3d(GetPosX(), 0, GetPosZ());
// Prevent division by small numbers
- if (abs(Distance.z) < 0.001)
+ if (std::abs(Distance.z) < 0.001)
{
Distance.z = 0.001;
}
@@ -925,7 +925,7 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta)
Vector3d Distance = MinecartCollisionCallback.GetCollidedEntityPosition() - Vector3d(GetPosX(), 0, GetPosZ());
// Prevent division by small numbers
- if (abs(Distance.z) < 0.001)
+ if (std::abs(Distance.z) < 0.001)
{
Distance.z = 0.001;
}
diff --git a/src/Generating/Caves.cpp b/src/Generating/Caves.cpp
index 71154dff9..fc925a150 100644
--- a/src/Generating/Caves.cpp
+++ b/src/Generating/Caves.cpp
@@ -755,7 +755,7 @@ void cStructGenDualRidgeCaves::GenFinish(cChunkDesc & a_ChunkDesc)
float n2 = m_Noise2.CubicNoise3D(xx, yy, zz);
float n3 = m_Noise1.CubicNoise3D(xx * 4, yy * 4, zz * 4) / 4;
float n4 = m_Noise2.CubicNoise3D(xx * 4, yy * 4, zz * 4) / 4;
- if ((abs(n1 + n3) * abs(n2 + n4)) > m_Threshold)
+ if ((std::abs(n1 + n3) * std::abs(n2 + n4)) > m_Threshold)
{
a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_AIR);
}
diff --git a/src/Generating/Noise3DGenerator.cpp b/src/Generating/Noise3DGenerator.cpp
index eb816f564..c3ca30384 100644
--- a/src/Generating/Noise3DGenerator.cpp
+++ b/src/Generating/Noise3DGenerator.cpp
@@ -236,7 +236,7 @@ void cNoise3DGenerator::GenerateNoiseArray(int a_ChunkX, int a_ChunkZ, NOISE_DAT
m_Cubic.Generate2D(Height, DIM_X, DIM_Z, StartX / 25, EndX / 25, StartZ / 25, EndZ / 25);
for (size_t i = 0; i < ARRAYCOUNT(Height); i++)
{
- Height[i] = abs(Height[i]) * m_HeightAmplification + 1;
+ Height[i] = std::abs(Height[i]) * m_HeightAmplification + 1;
}
// Modify the noise by height data:
@@ -395,7 +395,7 @@ void cNoise3DComposable::GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_ChunkZ)
for (int x = 0; x < 17; x += UPSCALE_X)
{
NOISE_DATATYPE NoiseX = ((NOISE_DATATYPE)(a_ChunkX * cChunkDef::Width + x)) / m_FrequencyX;
- NOISE_DATATYPE val = abs(m_Noise1.CubicNoise2D(NoiseX / 5, NoiseZ / 5)) * m_HeightAmplification + 1;
+ NOISE_DATATYPE val = std::abs(m_Noise1.CubicNoise2D(NoiseX / 5, NoiseZ / 5)) * m_HeightAmplification + 1;
Height[x + 17 * z] = val * val * val;
}
}
diff --git a/src/LineBlockTracer.cpp b/src/LineBlockTracer.cpp
index f03e796d1..1b42081c2 100644
--- a/src/LineBlockTracer.cpp
+++ b/src/LineBlockTracer.cpp
@@ -146,7 +146,7 @@ bool cLineBlockTracer::MoveToNextBlock(void)
dirY,
dirZ,
} Direction = dirNONE;
- if (abs(m_DiffX) > EPS)
+ if (std::abs(m_DiffX) > EPS)
{
double DestX = (m_DirX > 0) ? (m_CurrentX + 1) : m_CurrentX;
Coeff = (DestX - m_StartX) / m_DiffX;
@@ -155,7 +155,7 @@ bool cLineBlockTracer::MoveToNextBlock(void)
Direction = dirX;
}
}
- if (abs(m_DiffY) > EPS)
+ if (std::abs(m_DiffY) > EPS)
{
double DestY = (m_DirY > 0) ? (m_CurrentY + 1) : m_CurrentY;
double CoeffY = (DestY - m_StartY) / m_DiffY;
@@ -165,7 +165,7 @@ bool cLineBlockTracer::MoveToNextBlock(void)
Direction = dirY;
}
}
- if (abs(m_DiffZ) > EPS)
+ if (std::abs(m_DiffZ) > EPS)
{
double DestZ = (m_DirZ > 0) ? (m_CurrentZ + 1) : m_CurrentZ;
double CoeffZ = (DestZ - m_StartZ) / m_DiffZ;
@@ -227,9 +227,11 @@ bool cLineBlockTracer::Item(cChunk * a_Chunk)
}
// Update the current chunk
- if (a_Chunk != NULL)
+ a_Chunk = a_Chunk->GetNeighborChunk(m_CurrentX, m_CurrentZ);
+ if (a_Chunk == NULL)
{
- a_Chunk = a_Chunk->GetNeighborChunk(m_CurrentX, m_CurrentZ);
+ m_Callbacks->OnNoChunk();
+ return false;
}
if (a_Chunk->IsValid())
@@ -245,13 +247,10 @@ bool cLineBlockTracer::Item(cChunk * a_Chunk)
return false;
}
}
- else
+ else if (m_Callbacks->OnNextBlockNoData(m_CurrentX, m_CurrentY, m_CurrentZ, m_CurrentFace))
{
- if (m_Callbacks->OnNextBlockNoData(m_CurrentX, m_CurrentY, m_CurrentZ, m_CurrentFace))
- {
- // The callback terminated the trace
- return false;
- }
+ // The callback terminated the trace
+ return false;
}
}
}
diff --git a/src/Tracer.cpp b/src/Tracer.cpp
index 756147a7b..8ccd18071 100644
--- a/src/Tracer.cpp
+++ b/src/Tracer.cpp
@@ -250,7 +250,7 @@ int LinesCross(float x0, float y0, float x1, float y1, float x2, float y2, float
// float linx, liny;
float d=(x1-x0)*(y3-y2)-(y1-y0)*(x3-x2);
- if (abs(d)<0.001) {return 0;}
+ if (std::abs(d)<0.001) {return 0;}
float AB=((y0-y2)*(x3-x2)-(x0-x2)*(y3-y2))/d;
if (AB>=0.0 && AB<=1.0)
{
diff --git a/src/WorldStorage/FastNBT.cpp b/src/WorldStorage/FastNBT.cpp
index c6294b99c..ed8e8bb14 100644
--- a/src/WorldStorage/FastNBT.cpp
+++ b/src/WorldStorage/FastNBT.cpp
@@ -310,7 +310,7 @@ int cParsedNBT::FindTagByPath(int a_Tag, const AString & a_Path) const
{
continue;
}
- Tag = FindChildByName(Tag, a_Path.c_str() + Begin, i - Begin - 1);
+ Tag = FindChildByName(Tag, a_Path.c_str() + Begin, i - Begin);
if (Tag < 0)
{
return -1;