mirror of
https://github.com/Maruno17/pokemon-essentials.git
synced 2025-09-24 18:41:27 +02:00
242 lines
8.3 KiB
Ruby
242 lines
8.3 KiB
Ruby
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, layer = nil)
|
|
return 0 if x < 0 || x >= data.xsize
|
|
return 0 if y < 0 || y >= data.ysize
|
|
if layer.nil?
|
|
t = data[x, y]
|
|
else
|
|
t = data[x, y, layer]
|
|
end
|
|
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
|
|
if layer.nil?
|
|
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
|
|
else
|
|
i |= 0x01 if data[ x, ym1, layer] == t # N
|
|
i |= 0x02 if data[xp1, ym1, layer] == t # NE
|
|
i |= 0x04 if data[xp1, y, layer] == t # E
|
|
i |= 0x08 if data[xp1, yp1, layer] == t # SE
|
|
i |= 0x10 if data[ x, yp1, layer] == t # S
|
|
i |= 0x20 if data[xm1, yp1, layer] == t # SW
|
|
i |= 0x40 if data[xm1, y, layer] == t # W
|
|
i |= 0x80 if data[xm1, ym1, layer] == t # NW
|
|
end
|
|
return i
|
|
end
|
|
|
|
def self.fromTileset(tileset)
|
|
bmtileset = pbGetTileset(tileset.tileset_name)
|
|
bmautotiles = []
|
|
7.times do |i|
|
|
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
|
|
@tileset = nil
|
|
@autotiles.each_with_index do |autotile, i|
|
|
autotile.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)
|
|
4.times do |i|
|
|
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 Bitmap.new(32, 32) if !map
|
|
bitmap = Bitmap.new(map.width * 4, map.height * 4)
|
|
black = Color.black
|
|
tilesets = $data_tilesets
|
|
tileset = tilesets[map.tileset_id]
|
|
return bitmap if !tileset
|
|
helper = TileDrawingHelper.fromTileset(tileset)
|
|
map.height.times do |y|
|
|
map.width.times do |x|
|
|
3.times do |z|
|
|
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)
|
|
4.times do |i|
|
|
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/UI/minimap_tiles")
|
|
ret = Bitmap.new(map.width * 6, map.height * 6)
|
|
passtable = Table.new(map.width, map.height)
|
|
passages = tileset.passages
|
|
map.width.times do |i|
|
|
map.height.times do |j|
|
|
pass = true
|
|
[2, 1, 0].each do |z|
|
|
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
|
|
map.width.times do |i|
|
|
map.height.times do |j|
|
|
next 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
|
|
minimap.dispose
|
|
return ret
|
|
end
|