class TileDrawingHelper attr_accessor :tileset attr_accessor :autotiles AUTOTILE_PATTERNS = [ [ [27, 28, 33, 34], [ 5, 28, 33, 34], [27, 6, 33, 34], [ 5, 6, 33, 34], [27, 28, 33, 12], [ 5, 28, 33, 12], [27, 6, 33, 12], [ 5, 6, 33, 12] ], [ [27, 28, 11, 34], [ 5, 28, 11, 34], [27, 6, 11, 34], [ 5, 6, 11, 34], [27, 28, 11, 12], [ 5, 28, 11, 12], [27, 6, 11, 12], [ 5, 6, 11, 12] ], [ [25, 26, 31, 32], [25, 6, 31, 32], [25, 26, 31, 12], [25, 6, 31, 12], [15, 16, 21, 22], [15, 16, 21, 12], [15, 16, 11, 22], [15, 16, 11, 12] ], [ [29, 30, 35, 36], [29, 30, 11, 36], [ 5, 30, 35, 36], [ 5, 30, 11, 36], [39, 40, 45, 46], [ 5, 40, 45, 46], [39, 6, 45, 46], [ 5, 6, 45, 46] ], [ [25, 30, 31, 36], [15, 16, 45, 46], [13, 14, 19, 20], [13, 14, 19, 12], [17, 18, 23, 24], [17, 18, 11, 24], [41, 42, 47, 48], [ 5, 42, 47, 48] ], [ [37, 38, 43, 44], [37, 6, 43, 44], [13, 18, 19, 24], [13, 14, 43, 44], [37, 42, 43, 48], [17, 18, 47, 48], [13, 18, 43, 48], [ 1, 2, 7, 8] ] ] # converts neighbors returned from tableNeighbors to tile indexes NEIGHBORS_TO_AUTOTILE_INDEX = [ 46, 44, 46, 44, 43, 41, 43, 40, 46, 44, 46, 44, 43, 41, 43, 40, 42, 32, 42, 32, 35, 19, 35, 18, 42, 32, 42, 32, 34, 17, 34, 16, 46, 44, 46, 44, 43, 41, 43, 40, 46, 44, 46, 44, 43, 41, 43, 40, 42, 32, 42, 32, 35, 19, 35, 18, 42, 32, 42, 32, 34, 17, 34, 16, 45, 39, 45, 39, 33, 31, 33, 29, 45, 39, 45, 39, 33, 31, 33, 29, 37, 27, 37, 27, 23, 15, 23, 13, 37, 27, 37, 27, 22, 11, 22, 9, 45, 39, 45, 39, 33, 31, 33, 29, 45, 39, 45, 39, 33, 31, 33, 29, 36, 26, 36, 26, 21, 7, 21, 5, 36, 26, 36, 26, 20, 3, 20, 1, 46, 44, 46, 44, 43, 41, 43, 40, 46, 44, 46, 44, 43, 41, 43, 40, 42, 32, 42, 32, 35, 19, 35, 18, 42, 32, 42, 32, 34, 17, 34, 16, 46, 44, 46, 44, 43, 41, 43, 40, 46, 44, 46, 44, 43, 41, 43, 40, 42, 32, 42, 32, 35, 19, 35, 18, 42, 32, 42, 32, 34, 17, 34, 16, 45, 38, 45, 38, 33, 30, 33, 28, 45, 38, 45, 38, 33, 30, 33, 28, 37, 25, 37, 25, 23, 14, 23, 12, 37, 25, 37, 25, 22, 10, 22, 8, 45, 38, 45, 38, 33, 30, 33, 28, 45, 38, 45, 38, 33, 30, 33, 28, 36, 24, 36, 24, 21, 6, 21, 4, 36, 24, 36, 24, 20, 2, 20, 0 ] def self.tableNeighbors(data,x,y) return 0 if x < 0 || x >= data.xsize return 0 if y < 0 || y >= data.ysize t = data[x,y] xp1 = [x + 1, data.xsize - 1].min yp1 = [y + 1, data.ysize - 1].min xm1 = [x - 1, 0].max ym1 = [y - 1, 0].max i = 0 i |= 0x01 if data[ x, ym1] == t # N i |= 0x02 if data[xp1, ym1] == t # NE i |= 0x04 if data[xp1, y] == t # E i |= 0x08 if data[xp1, yp1] == t # SE i |= 0x10 if data[ x, yp1] == t # S i |= 0x20 if data[xm1, yp1] == t # SW i |= 0x40 if data[xm1, y] == t # W i |= 0x80 if data[xm1, ym1] == t # NW return i end def self.fromTileset(tileset) bmtileset=pbGetTileset(tileset.tileset_name) bmautotiles=[] for i in 0...7 bmautotiles.push(pbGetAutotile(tileset.autotile_names[i])) end return self.new(bmtileset,bmautotiles) end def initialize(tileset, autotiles) if tileset.mega? @tileset = TilemapRenderer::TilesetWrapper.wrapTileset(tileset) tileset.dispose @shouldWrap = true else @tileset = tileset @shouldWrap = false end @autotiles = autotiles end def dispose @tileset.dispose if @tileset @tileset = nil for i in 0...@autotiles.length @autotiles[i].dispose @autotiles[i] = nil end end def bltSmallAutotile(bitmap,x,y,cxTile,cyTile,id,frame) return if id >= 384 || frame < 0 || !@autotiles autotile = @autotiles[id / 48 - 1] return if !autotile || autotile.disposed? cxTile = [cxTile / 2, 1].max cyTile = [cyTile / 2, 1].max if autotile.height == 32 anim = frame * 32 src_rect = Rect.new(anim, 0, 32, 32) bitmap.stretch_blt(Rect.new(x, y, cxTile * 2, cyTile * 2), autotile, src_rect) else anim = frame * 96 id %= 48 tiles = AUTOTILE_PATTERNS[id >> 3][id & 7] src = Rect.new(0, 0, 0, 0) for i in 0...4 tile_position = tiles[i] - 1 src.set(tile_position % 6 * 16 + anim, tile_position / 6 * 16, 16, 16) bitmap.stretch_blt(Rect.new(i % 2 * cxTile + x, i / 2 * cyTile + y, cxTile, cyTile), autotile, src) end end end def bltSmallRegularTile(bitmap,x,y,cxTile,cyTile,id) return if id < 384 || !@tileset || @tileset.disposed? rect = Rect.new((id - 384) % 8 * 32, (id - 384) / 8 * 32, 32, 32) rect = TilemapRenderer::TilesetWrapper.getWrappedRect(rect) if @shouldWrap bitmap.stretch_blt(Rect.new(x, y, cxTile, cyTile), @tileset, rect) end def bltSmallTile(bitmap,x,y,cxTile,cyTile,id,frame=0) if id >= 384 bltSmallRegularTile(bitmap, x, y, cxTile, cyTile, id) elsif id > 0 bltSmallAutotile(bitmap, x, y, cxTile, cyTile, id, frame) end end def bltAutotile(bitmap,x,y,id,frame) bltSmallAutotile(bitmap, x, y, 32, 32, id, frame) end def bltRegularTile(bitmap,x,y,id) bltSmallRegularTile(bitmap, x, y, 32, 32, id) end def bltTile(bitmap,x,y,id,frame=0) if id >= 384 bltRegularTile(bitmap, x, y, id) elsif id > 0 bltAutotile(bitmap, x, y, id, frame) end end end #=============================================================================== # #=============================================================================== def createMinimap(mapid) map=load_data(sprintf("Data/Map%03d.rxdata",mapid)) rescue nil return BitmapWrapper.new(32,32) if !map bitmap=BitmapWrapper.new(map.width*4,map.height*4) black=Color.new(0,0,0) tilesets=$data_tilesets tileset=tilesets[map.tileset_id] return bitmap if !tileset helper=TileDrawingHelper.fromTileset(tileset) for y in 0...map.height for x in 0...map.width for z in 0..2 id=map.data[x,y,z] id=0 if !id helper.bltSmallTile(bitmap,x*4,y*4,4,4,id) end end end bitmap.fill_rect(0,0,bitmap.width,1,black) bitmap.fill_rect(0,bitmap.height-1,bitmap.width,1,black) bitmap.fill_rect(0,0,1,bitmap.height,black) bitmap.fill_rect(bitmap.width-1,0,1,bitmap.height,black) return bitmap end def bltMinimapAutotile(dstBitmap,x,y,srcBitmap,id) return if id>=48 || !srcBitmap || srcBitmap.disposed? anim=0 cxTile=3 cyTile=3 tiles = TileDrawingHelper::AUTOTILE_PATTERNS[id>>3][id&7] src=Rect.new(0,0,0,0) for i in 0...4 tile_position = tiles[i] - 1 src.set( tile_position % 6 * cxTile + anim, tile_position / 6 * cyTile, cxTile, cyTile) dstBitmap.blt(i%2*cxTile+x,i/2*cyTile+y, srcBitmap, src) end end def passable?(passages,tile_id) return false if tile_id == nil passage = passages[tile_id] return (passage && passage<15) end # Unused def getPassabilityMinimap(mapid) map = load_data(sprintf("Data/Map%03d.rxdata",mapid)) tileset = $data_tilesets[map.tileset_id] minimap = AnimatedBitmap.new("Graphics/Pictures/minimap_tiles") ret = Bitmap.new(map.width*6,map.height*6) passtable = Table.new(map.width,map.height) passages = tileset.passages for i in 0...map.width for j in 0...map.height pass=true for z in [2,1,0] if !passable?(passages,map.data[i,j,z]) pass=false break end end passtable[i,j]=pass ? 1 : 0 end end neighbors=TileDrawingHelper::NEIGHBORS_TO_AUTOTILE_INDEX for i in 0...map.width for j in 0...map.height if passtable[i,j]==0 nb=TileDrawingHelper.tableNeighbors(passtable,i,j) tile=neighbors[nb] bltMinimapAutotile(ret,i*6,j*6,minimap.bitmap,tile) end end end minimap.disposes return ret end