For my Karsthafen map, I had written a quick script to shrink my map. I wrote it only for my personal use, so its quick and dirty... In this version, I have translatet the error-messages to english.
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
- Code: Select all
#!/usr/bin/perl
use strict;
use CGI;
use DBI qw(:sql_types);
my $y;
my $z;
my $a;
my $b;
my $cgi=CGI->new();
my $Game=$cgi->param('game')?$cgi->param('game'):'.';
my $Out=$cgi->param('out')?$cgi->param('out'):'map.sqlite';
if(-e "$Game/map.sqlite" && -e "$Game/savegame.txt"){
my $dbGame=DBI->connect("dbi:SQLite:$Game/map.sqlite",'','')||die 'Cannot open map.sqlite';
my $dbSave=DBI->connect('dbi:SQLite:dbname=:memory:','','')||die 'Cannot create inmemory database';
my $dbInput=$dbSave->prepare("CREATE TABLE `blocks` (`pos` INT NOT NULL PRIMARY KEY,`data` BLOB)");
$dbInput->execute();
open(FILE,"<$Game/savegame.txt")||die 'Cannot open savegame.txt';
foreach(<FILE>){
my @line=split(/\,/,$_);
if($line[5]){
$line[0]=int($line[0]/16-1);
$line[1]=int($line[1]/16+1);
$line[2]=int($line[2]/16-1);
$line[3]=int($line[3]/16+1);
$line[4]=int($line[4]/16-1);
$line[5]=int($line[5]/16+1);
print 'Writing ',$line[6];
for(my $x=$line[0];$x<=$line[1];$x++){
for(my $y=$line[2];$y<=$line[3];$y++){
for(my $z=$line[4];$z<=$line[5];$z++){
my $pos=minetest_get_block_as_integer($x,$y,$z);
my $dbData=$dbGame->prepare("SELECT * FROM `blocks` WHERE `pos`=?");
$dbData->execute($pos);
my $rows=$dbData->fetchall_arrayref;
if($rows->[0][1]){
my $dbTest=$dbSave->prepare("SELECT * FROM `blocks` WHERE `pos`=?");
$dbTest->execute($pos);
my $test=$dbTest->fetchall_arrayref;
unless($test->[0][1]){
$dbInput=$dbSave->prepare("INSERT INTO `blocks`(pos,data) VALUES (?,?)");
$dbInput->execute($rows->[0][0],$rows->[0][1]);
}
}
}
}
}
}
}
print "\n";
$dbSave->sqlite_backup_to_file($Out);
$dbSave->disconnect();
$dbGame->disconnect();
}else{
print "Minetest savegame with savegame.txt not found.\n\nUsage of this script:\n";
print "nt_clean.pl game=[path to the savegame directory] out=[path for the new database file]\n\n";
print "Width no use of the game parameter, the data is read from the actual directory.\nWidth no use of the out parameter, the database is written to 'map.sqlite'.\n\n";
print "If you use the script from the savegame directory with no set parameters, the game database will be overwritten with no warning!\n\n";
print "The file savegame.txt is a CSV file with no quotation marks and with comma as separator and following table columns:\n";
print "1 - x from\n2 - x to\n3 - y from\n4 - y to\n5 - z from\n6 - z to\n7 - Name of the block\n\n";
}
sub minetest_unsigned_to_signed{
if($_[0]<$_[1]){
return $_[0];
}else{
return ($_[0]-2*$_[1]);
}
}
sub minetest_get_integer_as_block{
my $int=shift;
my @return;
$return[0]=minetest_unsigned_to_signed($int%4096,2048);
$int=int(($int-$return[0])/4096);
$return[1]=minetest_unsigned_to_signed($int%4096,2048);
$int=int(($int-$return[1])/4096);
$return[2]=minetest_unsigned_to_signed($int%4096,2048);
return @return;
}
sub minetest_get_block_as_integer{
return $_[2]*16777216+$_[1]*4096+$_[0];
}
If you save the code to 'mt_clean.pl' and put a savegame.txt to the directory with your map.sqlite-file, you can use the script with (if your savefile is in '.minetest/worlds/world' and a copy for the new version in '.minetest/worlds/newworld':
perl mt_clean.pl game=.minetest/worlds/world out=.minetest/worlds/newworld/map.sqlite
Bevor you use the script, you have to put a savegame.txt-file in the directory with your map.sqlite-file. As an example:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
- Code: Select all
-100,100,-20,50,-100,100,Center of the World
20,300,200,250,-120,-50,My Skycastle
Every Line is a definition of a area, that should be saved in the new database. The second line is an area from 20,200,-120 to 300,250,-50.
It will save a bigger area as you write in the file, it put the 16x16x16 Fields big blocks in the new database. But big landscapes outside this areas will be unexplored after that.
I hope this script can help you. It works from version 0.4.10 of minetest. In older versions, the landscape-generator destroys the buildings.
PS: Dont use the script form the Savegame-Directory without saving the map beforehand. You can use the script without parameter from the path with your map.sqlite-File and it will overwrite it with the belittled file without asking. With an faulty savegame.txt, your map can be destroyed. To copy the map and use the script on the copy without parameters make the new map in a simple way.