From f560d2de1137940942c3b9cb926a0093359e80fa Mon Sep 17 00:00:00 2001 From: jj Date: Thu, 5 Jul 2012 14:15:34 +0200 Subject: [PATCH] ruby: add MapTile class --- plugins/ruby/README | 3 ++ plugins/ruby/item.rb | 2 +- plugins/ruby/map.rb | 112 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+), 1 deletion(-) diff --git a/plugins/ruby/README b/plugins/ruby/README index a3f9bf945..493e3c821 100644 --- a/plugins/ruby/README +++ b/plugins/ruby/README @@ -66,6 +66,9 @@ obj1 and 2 should respond to #pos and #x #y #z. df.map_block_at(pos) / map_block_at(x, y, z) Returns the MapBlock for the coordinates or nil. + df.map_tile_at(pos) +Returns a MapTile, holds all information relative to the map tile. + df.each_map_block { |b| } df.each_map_block_z(zlevel) { |b| } Iterates over every map block (opt. on a single z-level). diff --git a/plugins/ruby/item.rb b/plugins/ruby/item.rb index a3fe68b97..34b404505 100644 --- a/plugins/ruby/item.rb +++ b/plugins/ruby/item.rb @@ -33,7 +33,7 @@ module DFHack return world.items.all.binsearch(what) if not z # search by position x = what - world.items.all.find { |i| i.pos.x == x and i.pos.y == y and i.pos.z == z } + world.items.all.find { |i| i.pos.x == x and i.pos.y == y and i.pos.z == z } elsif what.respond_to?(:x) or what.respond_to?(:pos) world.items.all.find { |i| same_pos?(what, i) } else diff --git a/plugins/ruby/map.rb b/plugins/ruby/map.rb index af9e8b804..a0438670d 100644 --- a/plugins/ruby/map.rb +++ b/plugins/ruby/map.rb @@ -26,6 +26,13 @@ module DFHack end end + def map_tile_at(x, y=nil, z=nil) + x = x.pos if x.respond_to?(:pos) + x, y, z = x.x, x.y, x.z if x.respond_to?(:x) + b = map_block_at(x, y, z) + MapTile.new(b, x, y, z) if b + end + # yields every map block def each_map_block (0...world.map.x_count_block).each { |xb| @@ -51,4 +58,109 @@ module DFHack } end end + + class MapTile + attr_accessor :x, :y, :z, :dx, :dy, :mapblock + def initialize(b, x, y, z) + @x, @y, @z = x, y, z + @dx, @dy = @x&15, @y&15 + @mapblock = b + end + + def designation + @mapblock.designation[@dx][@dy] + end + + def occupancy + @mapblock.occupancy[@dx][@dy] + end + + def tiletype + @mapblock.tiletype[@dx][@dy] + end + + def tiletype=(t) + @mapblock.tiletype[@dx][@dy] = t + end + + def caption + Tiletype::Caption[tiletype] + end + + def shape + Tiletype::Shape[tiletype] + end + + def tilemat + Tiletype::Material[tiletype] + end + + def variant + Tiletype::Variant[tiletype] + end + + def special + Tiletype::Special[tiletype] + end + + def direction + Tiletype::Direction[tiletype] + end + + # return all veins for current mapblock + def all_veins + mapblock.block_events.grep(BlockSquareEventMineralst) + end + + # return the vein applicable to current tile + def vein + # last vein wins + all_veins.reverse.find { |v| + (v.tile_bitmask.bits[@dy] & (1 << @dx)) > 0 + } + end + + # return the mat_index for the current tile (if in vein) + def mat_index_vein + v = vein + v.inorganic_mat if v + end + + # return the world_data.geo_biome for current tile + def geo_biome + b = designation.biome + wd = df.world.world_data + + # region coords + [[-1, -1], [0, -1], ..., [1, 1]][b] + # clipped to world dimensions + rx = df.world.map.region_x/16 + rx -= 1 if b % 3 == 0 and rx > 0 + rx += 1 if b % 3 == 2 and rx < wd.world_width-1 + + ry = df.world.map.region_y/16 + ry -= 1 if b < 3 and ry > 0 + ry += 1 if b > 5 and ry < wd.world_height-1 + + wd.geo_biomes[ wd.region_map[rx][ry].geo_index ] + end + + # return the world_data.geo_biome.layer for current tile + def stone_layer + geo_biome.layers[designation.geolayer_index] + end + + # current tile mat_index (vein if applicable, or base material) + def mat_index + mat_index_vein or stone_layer.mat_index + end + + # MaterialInfo: inorganic token for current tile + def mat_info + MaterialInfo.new(0, mat_index) + end + + def inspect + "#" + end + end end