Skip to content

Instantly share code, notes, and snippets.

@mikeweber
Created July 5, 2012 16:30
Show Gist options
  • Save mikeweber/3054667 to your computer and use it in GitHub Desktop.
Save mikeweber/3054667 to your computer and use it in GitHub Desktop.
Combines all Minecraft map .dat files found in the same directory as the script. TODO: add coord grid system
require 'chunky_png'
require 'nbtfile'
COLOR_MAP = %q{
255,255,255
255,255,255
255,255,255
255,255,255
89,125,39
109,153,48
127,178,56
109,153,48
174,164,115
213,201,140
247,233,163
213,201,140
117,117,117
144,144,144
167,167,167
144,144,144
180,0,0
220,0,0
255,0,0
220,0,0
112,112,180
138,138,220
160,160,225
138,138,220
117,117,117
144,144,144
167,167,167
144,144,144
0,87,0
0,106,0
0,124,0
0,106,0
180,180,180
220,220,220
255,255,255
220,220,220
115,118,129
141,144,158
164,168,184
141,144,158
129,74,33
157,91,40
183,106,47
157,91,40
79,70,70
96,96,96
112,112,112
96,96,96
45,45,180
55,55,220
64,64,255
55,55,220
73,58,35
89,71,43
104,83,50
89,71,43
}.split("\n").map(&:strip).reject{|line| line.empty?}
class MapCollector
attr_reader :mc_data, :west_border, :east_border, :north_border, :south_border
def initialize(map_dir = '.')
@map_dir = map_dir
@mc_data = []
Dir.foreach(map_dir) do |f|
next unless f =~ /\.dat$/
@mc_data << NBTFile.load(File.read("./#{f}"))[1]['data']
end
raise "Could not find any map data files in this folder" if @mc_data.empty?
east_west = mc_data.collect { |f| rounded(f['xCenter']) }
north_south = mc_data.collect { |f| rounded(f['zCenter']) }
# Determine the edges of our maps
@west_border = east_west.min - 512
@east_border = east_west.max + 512
@north_border = north_south.min - 512
@south_border = north_south.max + 512
end
def render_map
new_map = ChunkyPNG::Image.new(self.width, self.height, ChunkyPNG::Color::TRANSPARENT)
mc_data.each do |data|
data['colors'].split('').each_with_index do |pixel, i|
next if pixel.ord <= 3
x_image_pixel = world_coord(data, i)[0] - self.west_border
y_image_pixel = world_coord(data, i)[1] - self.north_border
8.times do |x_offset|
8.times do |y_offset|
new_map[(x_image_pixel + x_offset), (y_image_pixel + y_offset)] = color(pixel.ord)
end
end
end
end
apply_grid(new_map, mc_data[0])
new_map.save(File.join(@map_dir, 'full_map.png'))
end
def width
self.east_border - self.west_border
end
def height
self.south_border - self.north_border
end
def color(ord)
rgb = (COLOR_MAP[ord] || '0,0,0').split(',').collect { |c| c.to_i }
ChunkyPNG::Color.rgb(*rgb)
end
def world_coord(data, pixel)
world_offset(pixel).zip(map_center(data)).collect { |offset, center| offset + center }
end
def world_offset(pixel)
map_pixel_coord(pixel).collect { |p| (p - 64) * 8 }
end
def map_pixel_coord(pixel)
[pixel % 128, pixel / 128]
end
def map_center(data)
[rounded(data['xCenter']), rounded(data['zCenter'])]
end
def rounded(int)
int / 8 * 8
end
def apply_grid(map_image, mc_map)
grid_offsets = map_center(mc_map).collect { |c| grid_interval - (c % grid_interval) }
x_offset = grid_offsets[0]
while x_offset <= self.width
map_image.line(x_offset, 0, x_offset, self.height, ChunkyPNG::Color.rgba(0, 0, 0, 128))
x_offset += grid_interval
end
y_offset = grid_offsets[1]
while y_offset <= self.height
map_image.line(0, y_offset, self.width, y_offset, ChunkyPNG::Color.rgba(0, 0, 0, 128))
y_offset += grid_interval
end
end
def grid_interval
100
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment