02-22-2025, 05:25 AM 
(This post was last modified: 02-26-2025, 05:17 PM by DerVVulfman.)
	
	
	Poccil's Tilemap Rewrite
Version: 1.3
The Re-Envisioned Game Set
Version: 1.3
The Re-Envisioned Game Set
Introduction
This script is a replacement for the default code within the RPGMaker engine that generates the visible map within your game. Just as the default tilemap system, it uses the tilesets applied to your maps.
As a script, it still renders the map slower than the default system. But it works with screen resolution scripts that increase/decrease the screen size and may work with other scripts that work with the tilemap.
Features
- Automatically adjusts based on the viewport's dimensions
 
- Adaptable
 
Screenshots
None.
Demo
BOX.COM LINK Look for the Download link in the top right of the screen
Script
 The Script
  			Code:
#==============================================================================
# ** Poccil's Tilemap Rewrite
#    A rewrite of Poccil's Tilemap found in HBGames.
#------------------------------------------------------------------------------
#    Version 1.3
#    Edit by DerVVulfman
#    02-26-2025 (MM-DD-YYYY)
#    RGSS / RPGMaker XP / RUBY 2.7 Compliant
#==============================================================================
#
#
#  INTRODUCTION:
#  =============
#  This script is a replacement for the default code within the RPGMaker engine
#  that generates the visible map within your game. Just as the default tilemap
#  system, it uses the tilesets applied to your maps.
#
#  As a script, it still renders the map slower than the default system. But it
#  works with screen resolution scripts  that increase/decrease the screen size
#  and may work with other scripts that work with the tilemap.
#
#
#  INSTALLTION:
#  ============
#  Place below Scene_Debug and above Main. Place it below any resolution script
#  if one is in use.
#
#
#  CONFIGURATION:
#  ==============
#  Generally, you don't touch it. But it allows you to set the refresh rate of
#  autotiles, the opacity level of flash effects,  and how many map layers you
#  can display assuming you have a compatible map editor.
#
#
#  ORIGINAL SOURCE:
#  ================
#  The 3rd post in (Jan 19, 2008):
#  https://www.arpgmaker.com/threads/tilemap-script-needed-some-feedback.37433/
#  - or (with the Internet Archive) -
#  http://www.hbgames.org/forums/viewtopic.php?f=11&t=37433&start=2
#
#
#------------------------------------------------------------------------------
#
#  CREDITS
#  =======
#  Thanks to Poccil for the creation of the original tilemap script, and thanks
#  to Mel of Save-Point.Org for noticing a few priority tile issues
#
#
#==============================================================================
#
#  TERMS OF USE:
#  =============
#  Free for use, even in commercial products. However, due credit to myself,
#  Poccil and Mel is a necessity.
#
#==============================================================================
#==============================================================================
# ** Poccil's Tilemap Settings
#------------------------------------------------------------------------------
#  This module just allows you to adjust the three settings in the script.
#==============================================================================
module PoccilTilemap
  
  
  # Animated Autotiles Frames Reset
  # ===============================
  # Defines the speed where the autotiles repaint and refresh within the map.
  # (DEFAULT: 15)
  #--------------------------------------------------------------------------
  #
  AUTOTILES_SPEED = 15
  
  # Map Layers
  # ==========
  # Defines how many layers are used to draw the rendered map. It will require
  # the map editor to be compatible with the number of layers possible.
  # (DEFAULT: 3  typical RMXP layers)
  #--------------------------------------------------------------------------
  #
  LAYERS = 3
  # Zoom Fitting
  # ============
  # This allows for a very minor increase in scale for priority defined tiles
  # during the scaling/zooming process,  otherwise gaps may appear.  However,
  # set the value too large, and tiles may overlap too much.  For transparent
  # tiles, one may see a checkerboard pattern. For some reason, this does not
  # occur as much when using the HiddenChest exe by kyonides,  and would rec-
  # comend a setting of 0.5 in that instance.
  # (DEFAULT: 2.5  A minor increase for RMXP's exe.
  #                Set to 0.5 for HiddenChest)
  #--------------------------------------------------------------------------
  #
  ZOOM_FIT = 2.5
  # Flash Opacity per Stage
  # =======================
  # The flash effect is generated in six stages, each of the six stages ren-
  # dering the colorized effet with its own opacity intensity.  It is here
  # where you set the intensity (range 0-255) for each of the six stages.
  # (DEFAULT: [100,90,80,70,80,90]
  #--------------------------------------------------------------------------
  #
  FLASH_OPACITY = [100,90,80,70,80,90]
  
  
end
#==============================================================================
# ** Custom Tilemap Autotiles
#------------------------------------------------------------------------------
#  This class handles the autotiles
#==============================================================================
class CustomTilemapAutotiles
  
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_accessor :changed                  # autotiles changed flag
  
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize
    #
    @changed  = true
    @tiles    = [nil,nil,nil,nil,nil,nil,nil]
    #
  end
 
  #--------------------------------------------------------------------------
  # * Set tiles
  #     value : tiles
  #--------------------------------------------------------------------------
  def []=(i,value)
    #
    @tiles[i] = value
    @changed  = true
    #
  end
  
  #--------------------------------------------------------------------------
  # * Get tiles 
  #--------------------------------------------------------------------------
  def [](i)
    #
    return @tiles[i]
    #
  end
  
end
#==============================================================================
# ** Tilemap (hidden class)
#------------------------------------------------------------------------------
#  This class handles the map data to screen processing
#==============================================================================
class Tilemap
  #--------------------------------------------------------------------------
  # * Configured values
  #   - Animated Autotiles Frames Reset
  #   - Map Layer System (default for 3 - typical RMXP layers)
  #   - Flash Opacity (with 6 opacity stages for a single flash)
  #--------------------------------------------------------------------------
  Animated_Autotiles_Frames = PoccilTilemap::AUTOTILES_SPEED
  Map_Layers                = PoccilTilemap::LAYERS
  FlashOpacity              = PoccilTilemap::FLASH_OPACITY
  #--------------------------------------------------------------------------
  # * Auto-Tiles
  #   Auto-Tile 48 : First Auto-Tile, Constructed of tiles 27, 28, 33, 34
  #--------------------------------------------------------------------------
  Autotiles = [
    [ [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] ]
  ]
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_accessor :tileset                  # tileset
  attr_accessor :autotiles                # autotiles
  attr_accessor :map_data                 # map data
  attr_accessor :priorities               # map priorities
  attr_accessor :flash_data               # flash data
  attr_reader :visible                    # visible
  attr_accessor :ox                       # ox
  attr_accessor :oy                       # oy
  attr_reader :viewport                   # viewport
  
  #--------------------------------------------------------------------------
  # * Object Initialization
  #     viewport : viewport
  #--------------------------------------------------------------------------
  def initialize(viewport)
    #
    @viewport               = viewport
    @tileset                = nil
    @autotiles              = CustomTilemapAutotiles.new
    @map_data               = nil
    @flash_data             = nil
    @priorities             = nil
    @visible                = true
    @ox                     = 0
    @oy                     = 0
    @plane                  = false
    @tiles                  = []
    @autotileInfo           = []
    @regularTileInfo        = []
    @oldOx                  = 0
    @oldOy                  = 0
    @layer0                 = Sprite.new(viewport)
    @layer0.visible         = true
    @nowshown               = false
    vrw                     = @viewport.rect.width*2
    vrh                     = @viewport.rect.height*2
    @layer0.bitmap          = Bitmap.new(vrw, vrh)
    @flash                  = nil
    @layer0.ox              = 0
    @layer0.oy              = 0
    @zoom_x                 = $game_map.tilemap_zoom_x
    @zoom_y                 = $game_map.tilemap_zoom_y
    @layer0.zoom_x          = @zoom_x
    @layer0.zoom_y          = @zoom_y
    @oxLayer0               = 0
    @oyLayer0               = 0
    @oxFlash                = 0
    @oyFlash                = 0
    @layer0.z               = 0
    @priotiles              = []
    @prioautotiles          = []
    @autosprites            = []
    @framecount             = []
    @need_refresh           = true
    @flashChanged           = false
    @firsttime              = true
    @disposed               = false
    @usedsprites            = false
    @layer0clip             = true
    @firsttimeflash         = true
    @fullyrefreshed         = false
    @fullyrefreshedautos    = false
    #
  end
  
  #--------------------------------------------------------------------------
  # * Set Tileset and confirm change with refresh
  #     value     : tileset data
  #--------------------------------------------------------------------------
  def tileset=(value)
    #
    @tileset      = value
    @need_refresh = true
    #
  end
  
  #--------------------------------------------------------------------------
  # * Set X-Coordinate Starting point and confirm for update
  #     value     : revised y coordinate starting value
  #--------------------------------------------------------------------------
  def ox=(value)
    #
    value     = (value * $game_map.tilemap_zoom_x).to_i
    value     = (value / $game_map.tilemap_zoom_x).to_i
    wasshown  = self.shown?
    @ox       = value.floor
    @nowshown = (!wasshown && self.shown?)
    #
  end
  
  #--------------------------------------------------------------------------
  # * Set Y-Coordinate Starting point and confirm for update
  #     value     : revised y coordinate starting value
  #--------------------------------------------------------------------------
  def oy=(value)
    #
    value     = (value * $game_map.tilemap_zoom_y).to_i
    value     = (value / $game_map.tilemap_zoom_y).to_i
    wasshown  = self.shown?
    @oy       = value.floor
    @nowshown = (!wasshown && self.shown?)
    #
  end  
  
  #--------------------------------------------------------------------------
  # * Acquire number of horizontal tiles on the screen
  #     value     : revised y coordinate starting value
  #--------------------------------------------------------------------------  
  def tiles_width
    #
    (@viewport.rect.width / 32)
    #
  end
  
  #--------------------------------------------------------------------------
  # * Acquire number of horizontal tiles on the screen
  #     value     : revised y coordinate starting value
  #--------------------------------------------------------------------------  
  def tiles_height
    #
    (@viewport.rect.height / 32)
    #
  end
  #--------------------------------------------------------------------------
  # * Refresh
  #     autotiles : autotile flag
  #--------------------------------------------------------------------------
  def refresh(autotiles=false)
    #
    @oldOx      = @ox
    @oldOy      = @oy
    usesprites  = false
    #
    if @layer0
      @layer0.visible = @visible
      usesprites      =!  refreshLayer0(autotiles)
      return if autotiles && !usesprites
    else
      usesprites = true
    end
    #
    refreshFlashSprite
    vpx   = @viewport.rect.x
    vpy   = @viewport.rect.y
    vpr   = @viewport.rect.width+vpx
    vpb   = @viewport.rect.height+vpy
    xsize = @map_data.xsize
    ysize = @map_data.ysize
    minX  = (@ox/32)-1
    maxX  = ((@ox+@viewport.rect.width)/32)+1
    minY  = (@oy/32)-1
    maxY  = ((@oy+@viewport.rect.height)/32)+1
    minX  = 0 if minX<0
    minX  = xsize-1 if minX>=xsize
    maxX  = 0 if maxX<0
    maxX  = xsize-1 if maxX>=xsize
    minY  = 0 if minY<0
    minY  = ysize-1 if minY>=ysize
    maxY  = 0 if maxY<0
    maxY  = ysize-1 if maxY>=ysize
    #    
    count = 0
    if (minX < maxX) && (minY < maxY)
      @usedsprites=usesprites || @usedsprites
      if @layer0
        @layer0.visible=false if usesprites
      end
      #
      if @fullyrefreshed
        for prio in @priotiles
          next if (prio[0] < minX) || (prio[0] > maxX)
          next if (prio[1] < minY) || (prio[1] > maxY)
          id    = prio[3]
          xpos  = (prio[0]<<5)-@ox
          ypos  = (prio[1]<<5)-@oy
          count = addTile(@tiles, count, xpos, ypos, id, true)
        end
      else
        for z in 0...@map_data.zsize
          for y in minY..maxY
            for x in minX..maxX
              id = @map_data[x, y, z]
              next  if (id == 0) || !@priorities[id]
              next  if @priorities[id] == 0
              xpos  = (x << 5) - @ox
              ypos  = (y << 5) - @oy
              count = addTile(@tiles, count, xpos, ypos, id)
            end
          end
        end
      end
    end
    if count < @tiles.length
      bigchange = (count <= (@tiles.length*2/3)) && (@tiles.length*2/3)>25
      j         = count
      len       = @tiles.length
      while j<len
        sprite = @tiles[j]
        @tiles[j+1] =- 1
        if bigchange
          sprite.dispose
          @tiles[j]   = nil
          @tiles[j+1] = nil
        elsif !@tiles[j].disposed?
          sprite.visible = false if sprite.visible
        end
        j += 2
      end
      @tiles.compact! if bigchange
    end
    #
  end
  
  #--------------------------------------------------------------------------
  # * Dispose
  #--------------------------------------------------------------------------
  def dispose
    #
    return if disposed?
    @help.dispose if @help
    @help=nil
    i=0;len=@autotileInfo.length;while i<len
      if @autotileInfo[i]
         @autotileInfo[i].dispose
         @autotileInfo[i]=nil
      end
      i+=1
    end
    i=0;len=@regularTileInfo.length;while i<len
      if @regularTileInfo[i]
         @regularTileInfo[i].dispose
         @regularTileInfo[i]=nil
      end
      i+=1
    end
    i=0;len=@tiles.length;while i<len
      @tiles[i].dispose
      @tiles[i]=nil
      i+=2
    end
    i=0;len=@autosprites.length;while i<len
      @autosprites[i].dispose
      @autosprites[i]=nil
      i+=2
    end
    if @layer0
      @layer0.bitmap.dispose if !@layer0.disposed?
      @layer0.bitmap=nil if !@layer0.disposed?
      @layer0.dispose
      @layer0=nil
    end
    if @flash
      @flash.bitmap.dispose if !@flash.disposed?
      @flash.bitmap=nil if !@flash.disposed?
      @flash.dispose
      @flash=nil
    end
    for i in 0...7
      self.autotiles[i]=nil
    end
    @tiles.clear
    @autosprites.clear
    @autotileInfo.clear
    @regularTileInfo.clear
    @tilemap=nil
    @tileset=nil
    @priorities=nil
    @disposed=true
    #
  end
  
  #--------------------------------------------------------------------------
  # * Get if disposed
  #--------------------------------------------------------------------------
  def disposed?
    #
    return @disposed
    #
  end
 
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  def update
    #
    # Refresh and repaint autotiles if changed
    if @autotiles.changed
      refresh_autotiles
      repaintAutotiles
    end
    #
    # Get current zoom settings from Game Map
    z_x          = $game_map.tilemap_zoom_x
    z_y          = $game_map.tilemap_zoom_y
    #
    # Apply zoom settings to layers if zoom settings changed
    if @zoom_x != z_x || @zoom_y != z_y
      @zoom_x                 = z_x
      @zoom_y                 = z_y
      @layer0.zoom_x          = @zoom_x
      @layer0.zoom_y          = @zoom_y
      refresh
    end
    #
    # Refresh the flash and tileset if needed
    refresh_flash   if @flashChanged
    refresh_tileset if @need_refresh
    #
    # Handle flash opacity if flash present
    if @flash
     @flash.opacity = FlashOpacity[(Graphics.frame_count/2) % 6]
   end
   #
   # Refresh if anything changed
    if !(@oldOx==@ox && @oldOy==@oy && !@need_refresh && !@autotiles.changed)
      refresh
    end
    # Repaint autotiles and refresh based on timed autotiles system
    if (Graphics.frame_count % Animated_Autotiles_Frames == 0) || @nowshown
      repaintAutotiles
      refresh(true)
    end
    #
    # Clear refresh/redraw values
    @nowshown           = false
    @autotiles.changed  = false
    @need_refresh       = false
    #
  end
  
  #--------------------------------------------------------------------------
  # * Set Flash Data
  #     value : flash data value
  #--------------------------------------------------------------------------
  def flash_data=(value)
    #
    @flash_data   = value
    @flashChanged = true
    #
  end
  #--------------------------------------------------------------------------
  # * Set Priorities
  #     value : priority value
  #--------------------------------------------------------------------------
  def priorities=(value)
    #
    @priorities   = value
    @need_refresh = true
    #
  end
  
  #--------------------------------------------------------------------------
  #  * Get if shown
  #--------------------------------------------------------------------------
  def shown?
    #
    return false if !@visible
    ysize   = @map_data.ysize
    xsize   = @map_data.xsize
    xStart  = (@ox / 32) - 1
    xEnd    = ((@ox + @viewport.rect.width) / 32) + 1
    yStart  = (@oy / 32) - 1
    yEnd    = ((@oy + @viewport.rect.height) / 32) + 1
    xStart  = 0 if xStart < 0
    xStart  = xsize - 1 if xStart >= xsize
    xEnd    = 0 if xEnd < 0
    xEnd    = xsize - 1 if xEnd >= xsize
    yStart  = 0 if yStart < 0
    yStart  = ysize - 1 if yStart >= ysize
    yEnd    = 0 if yEnd < 0
    yEnd    = ysize - 1 if yEnd >= ysize
    return (xStart < xEnd && yStart < yEnd)
    #
  end
 
  #--------------------------------------------------------------------------
  # Blit Autotile
  #     bitmap  : bitmap
  #     x       : x-coordinates
  #     y       : y coordinates
  #     id      : Tile ID
  #     frame   : animation frame
  #--------------------------------------------------------------------------
  def bltAutotile(bitmap,x, y, id, frame)
    #
    return if frame < 0
    autotile = @autotiles[id / 48 - 1]
    return if !autotile
    if autotile.height == 32
      anim = frame * 32
      src_rect=Rect.new(anim, 0, 32, 32)
      bitmap.blt(x, y, autotile, src_rect)
    else
      anim = frame * 96
      id %= 48
      tiles = Autotiles[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.blt(i % 2 * 16 + x, i / 2 * 16 + y, autotile, src)
      end
    end
    #
  end
  #--------------------------------------------------------------------------
  # * Autotile Number of Frames
  #     id : Tile ID
  #--------------------------------------------------------------------------
  def autotileNumFrames(id)
    #
    # Acquire autotile
    autotile = @autotiles[id/48-1]
    # Exit if no autotile or autotile disposed
    return 0 if !autotile || autotile.disposed?
    # Set frames
    frames = 1
    # Reset frames based on autotile height
    frames = (autotile.height==32) ? (autotile.width/32) : (autotile.width/96)
    # Exit method with number of frames
    return frames
    #
  end
  #--------------------------------------------------------------------------
  # * Autotile Frame (count/rate used in display)
  #     id : Tile ID
  #--------------------------------------------------------------------------
  def autotileFrame(id)
    #
    # Acquire autotile
    autotile = @autotiles[id/48-1]
    # Exit if no autotile or autotile disposed
    return -1 if !autotile || autotile.disposed?
    # Set frames
    frames = 1
    # Reset frames based on autotile height
    frames = (autotile.height==32) ? (autotile.width/32) : (autotile.width/96)
    # Exit method with autotile frame
    return (Graphics.frame_count/Animated_Autotiles_Frames)%frames
    #
  end
  #--------------------------------------------------------------------------
  # * Repaint Autotiles
  #--------------------------------------------------------------------------
  def repaintAutotiles
    #
    # Cycle through autotile information
    for i in 0...@autotileInfo.length
      next  if !@autotileInfo[i]                # Skip if no autotile data
      frame = autotileFrame(i)                  # Acquire frame
      bltAutotile(@autotileInfo[i],0,0,i,frame) # Blit current autotile
    end
    #
  end
  #--------------------------------------------------------------------------
  # * Get Autotile Tile
  #     sprite : Map sprite
  #     id     : Tile ID
  #--------------------------------------------------------------------------
  def getAutotile(sprite,id)
    #
    # Get Autotile data
    anim    = autotileFrame(id)               # Get if it is animated  
    return  if anim < 0                       # Exit if anim flag below 0
    bitmap  = @autotileInfo[id]               # Get bitmap from autotile data
    #
    # If no autotile bitmap
    if !bitmap
      bitmap            = Bitmap.new(32,32)   # Define a 32x32 bitmap
      bltAutotile(bitmap, 0, 0, id, anim)     # Blit the autotile
      @autotileInfo[id] = bitmap              # Apply to autotile data
    end
    #
    # Set the bitmap to the sprite if sprite bitmap doesn't match
    sprite.bitmap=bitmap if !sprite.equal?(bitmap) || sprite.bitmap!=bitmap
    #
  end
  #--------------------------------------------------------------------------
  # * Get Regular Tile
  #     sprite : Map sprite
  #     id     : Tile ID
  #--------------------------------------------------------------------------
  def getRegularTile(sprite, id)
    #
    if false
      # Get empty sprite if bitmap doesn't match tileset 
      if !sprite.equal?(@tileset) || sprite.bitmap != @tileset
        sprite.bitmap
      end
      # Get the sprite tile
      sprite.src_rect.set((id - 384) % 8 * 32, (id - 384) / 8 * 32,32,32)
      #
    else
      #
      # Get the bitmap for a tile
      bitmap    = @regularTileInfo[id]
      # If there's no bitmap
      if !bitmap
        # Creae an empty 32x32 bitmap
         bitmap = Bitmap.new(32,32)
         # Define which tile from the tileset to use
         rect   = Rect.new((id - 384) % 8 * 32, (id - 384) / 8 * 32,32,32)
         # Apply the tileset tile to the bitmap
         bitmap.blt(0,0,@tileset,rect)
         # Set the bitmap 
         @regularTileInfo[id] = bitmap
       end
       # Set the bitmap to the sprite if sprite bitmap doesn't match
      sprite.bitmap=bitmap if !sprite.equal?(bitmap) || sprite.bitmap!=bitmap
      #
    end
    #
  end
  #--------------------------------------------------------------------------
  # * Add the tiles
  #     tiles     : tiles array
  #     count     : size/count of tiles
  #     xpos      : x position
  #     ypos      : y position
  #     id        : Tile ID
  #     prio_star : Priority Star Rating
  #--------------------------------------------------------------------------
  def addTile(tiles, count, xpos, ypos, id, prio_star = false)
    #
    #
    # Calculate base Z-Depth of tile
    tile_z = 32 * @zoom_y
    #
    # Set a tertiary zoom increase to fit tiles in proces based on config
    zoom_fit  = ((PoccilTilemap::ZOOM_FIT).to_f)/100
    #
    # As long as it is a tile, and not an autotile
    if id >= 384
      #
      if count >= tiles.length
        sprite  = Sprite.new(@viewport)
        tiles.push(sprite,0)
      else
        sprite=tiles[count]
        tiles[count+1] = 0
      end
      
      # Adjust position by zcale and position sprite
      xpos      *= @zoom_x
      ypos      *= @zoom_y
      sprite.x  =   xpos
      sprite.y  =   ypos
      # Increase by 1/20th beyond scale for odd tile separation
      sprite.zoom_x = (@zoom_x + zoom_fit)
      sprite.zoom_y = (@zoom_y + zoom_fit)
      #
      # Get Priority from ID
      prio      = @priorities[id]
      getRegularTile(sprite,id)
      #
      # Define z-Depth based on pririty
      spriteZ   = (prio==0||!prio) ? 0 : ypos + prio * tile_z + tile_z
      sprite.z  = spriteZ
      # Make Visible
      sprite.visible  = @visible
      # Add to count
      count     += 2
      #
    # If 
    else
      #
      if count >= tiles.length
        sprite  = Sprite.new(@viewport)
        tiles.push(sprite,1)
      else
        sprite = tiles[count]
        tiles[count+1] = 1
      end
      #
      # Adjust position by zcale and position sprite
      xpos      *= @zoom_x
      ypos      *= @zoom_y
      sprite.x  =   xpos
      sprite.y  =   ypos
      # Increase by 1/20th beyond scale for odd tile separation
      sprite.zoom_x = (@zoom_x + zoom_fit)
      sprite.zoom_y = (@zoom_y + zoom_fit)
      #
      # Get Priority from ID
      prio      =   @priorities[id]
      #
      getAutotile(sprite,id)
      #
      # Define z-Depth based on pririty
      spriteZ   = (prio==0||!prio) ? 0 : ypos + prio * tile_z + tile_z
      sprite.z  = spriteZ
      # Make Visible
      sprite.visible  = @visible
      # Add to count
      count     += 2
      #
    end
    #
    # Exit with count
    return count
    #
  end
  #--------------------------------------------------------------------------
  # * Refresh the tileset
  #--------------------------------------------------------------------------
  def refresh_tileset
    #
    # Initialize the sort index and length of tile data
    i   = 0
    len = @regularTileInfo.length
    #
    # Sort throught and dispose all tilemap data
    while i < len
      if @regularTileInfo[i]
        @regularTileInfo[i].dispose
        @regularTileInfo[i]=nil
      end
      # Increase index by 1
      i+=1
    end
    #
    # Clear tiledata
    @regularTileInfo.clear
    @priotiles.clear
    #
    # Get map dimensions
    ysize = @map_data.ysize
    xsize = @map_data.xsize
    zsize = @map_data.zsize
    #
    # Exit with no refresh if x or y sizes exceed 100
    return @fullyrefreshed = false if xsize > 100 || ysize > 100
    #      
    # Cycle through all map dimensions
    for z in 0...zsize    # 0 1 2 layer
      for y in 0...ysize
        for x in 0...xsize
          # Get tile ID
          id = @map_data[x, y, z]
          # Skip if no tile no valid priority above 0
          next if id == 0 || !@priorities[id]
          next if @priorities[id] == 0
          # Push Priority for map data
          @priotiles.push( [x, y, z, id] )
        end
      end
    end
    #
    # Set refresh tilemap flag
    @fullyrefreshed = true
    #
  end
  
  #--------------------------------------------------------------------------
  # * Refresh Flash
  #--------------------------------------------------------------------------
  def refresh_flash
    #
    # If flash data exists but no flash
    if @flash_data && !@flash
      #
      @flash            = Sprite.new(viewport)            # Create the sprite
      @flash.visible    = true                            # Show the sprite
      @flash.z          = 1                               # Set its depth
      @flash.blend_type = 1                               # Set its blend
      bm_width          = @viewport.rect.width  * 2       # Calc the bitmap size
      bm_height         = @viewport.rect.height * 2       #
      @flash.bitmap     = Bitmap.new(bm_width, bm_height) # Make the bitmap
      @flash.zoom_x     = @zoom_x                         # Set the flash scale
      @flash.zoom_y     = @zoom_y                         #
      @firsttimeflash   = true                            # Set the flash flag
      #
    # Or if flash but no flash data
    elsif !@flash_data && @flash
      #
      @flash.bitmap.dispose if @flash.bitmap              # Clear the bitmap
      @flash.dispose                                      # Erase the sprite
      @flash            = nil                             # Nil the sprite
      @firsttimeflash   = false                           # Clear the flag
      #
    end
    #
  end
  
  #--------------------------------------------------------------------------
  # * Refresh Autotiles
  #--------------------------------------------------------------------------
  def refresh_autotiles
    #
    # Initialize the sort index and length of autotile data
    i   = 0
    len = @autotileInfo.length
    #
    # Sort throught and dispose all autotile data
    while i < len
      if @autotileInfo[i]
        @autotileInfo[i].dispose
        @autotileInfo[i] = nil
      end
      # Increase index by 1
      i += 1
    end
    #
    # Initialize the sort index and length of autotile sprites
    i   = 0
    len = @autosprites.length
    #
    # Sort throught and dispose all autotile sprites
    while i<len
      if @autosprites[i]
        @autosprites[i].dispose
        @autosprites[i] = nil
      end
      # Increase index by 2
      i += 2
    end
    #
    # Clear autotile data
    @autosprites.clear
    @autotileInfo.clear
    @prioautotiles.clear
    #
    # Set animated flag false
    hasanimated = false
    #
    # Cycle through the 8 autotiles
    for i in 0...7
      numframes       = autotileNumFrames(48*(i+1))
      hasanimated     = true  if numframes >= 2
      @framecount[i]  = numframes
    end
    #
    # Exit with test for autotile search if animated
    return refresh_autotiles_search if hasanimated
    # Set refresh autotile flag
    @fullyrefreshedautos=true
    #
  end
  
  #--------------------------------------------------------------------------
  # * Refresh Autotiles Map Search
  #--------------------------------------------------------------------------
  def refresh_autotiles_search
    #
    # Get map dimensions
    ysize = @map_data.ysize
    xsize = @map_data.xsize
    zsize = @map_data.zsize
    #
    # Exit with autotile refresh flag if x or y sizes exceed 100
    if xsize > 100 || ysize > 100
      @fullyrefreshedautos = false
      return
    end
    #
    # Cycle through flat map
    for y in 0...ysize
      for x in 0...xsize
        # Assume no autotile
        haveautotile = false
        # Cycle through map depths
        for z in 0...zsize
          # Get tile ID
          id = @map_data[x, y, z]
          # Skip if no autotile or no valid 0 priority
          next if id==0 || id>=384 || @priorities[id] != 0 || !@priorities[id]
          # Skip based on frame count
          next if @framecount[id/48-1] < 2
          # Set autotile flag and break from depth loop
          haveautotile = true
          break
        end
        # Push into priority autotile array if found
        @prioautotiles.push([x,y]) if haveautotile
      end
    end
    # Set refresh autotile flag
    @fullyrefreshedautos = true
    #
  end
  #--------------------------------------------------------------------------
  # * Set Map Data
  #     value : map data
  #--------------------------------------------------------------------------
  def map_data=(value)
    #
    @map_data     = value   # Apply new map data to tilemap
    @need_refresh = true    # Set refresh variaable
    #
  end
  #--------------------------------------------------------------------------
  # * Refresh Flash Sprite
  #--------------------------------------------------------------------------
  def refreshFlashSprite
    #
    # Exit if no flash or no flash data
    return if !@flash || @flash_data.nil?
    #
    #
    ptX = @ox - @oxFlash
    ptY = @oy - @oyFlash
    #
    #
    if !@firsttimeflash && !@usedsprites &&
        ptX>=0 && ptX+@viewport.rect.width<=@flash.bitmap.width &&
        ptY>=0 && ptY+@viewport.rect.height<=@flash.bitmap.height
      @flash.ox = 0
      @flash.oy = 0
      @flash.src_rect.set(ptX.round,ptY.round,
         @viewport.rect.width,@viewport.rect.height)
      return
    end
    #
    #
    width           = @flash.bitmap.width
    height          = @flash.bitmap.height
    bitmap          = @flash.bitmap
    ysize           = @map_data.ysize
    xsize           = @map_data.xsize
    zsize           = @map_data.zsize
    @firsttimeflash = false
    @oxFlash        = @ox - (width>>2)
    @oyFlash        = @oy - (height>>2)
    @flash.ox       = 0
    @flash.oy       = 0
    #
    #
    @flash.src_rect.set(width>>2,height>>2,
       @viewport.rect.width,@viewport.rect.height)
    @flash.bitmap.clear
    #
    @oxFlash        = @oxFlash.floor
    @oyFlash        = @oyFlash.floor
    xStart          = (@oxFlash>>5)
    yStart          = (@oyFlash>>5)
    xStart          = 0         if xStart < 0
    yStart          = 0         if yStart < 0
    xEnd            = xStart + (width>>5)+1
    yEnd            = yStart + (height>>5)+1
    xEnd            = xsize     if xEnd >= xsize
    yEnd            = ysize     if yEnd >= ysize
    #
    # As long as ranges increase from start to end
    if xStart < xEnd && yStart < yEnd
      # Get the ranges
      yrange    = yStart...yEnd
      xrange    = xStart...xEnd
      tmpcolor  = Color.new(0,0,0,0)
      # Sort through ranges and get x/y positions
      for y in yrange
        ypos    = (y<<5) - @oyFlash
        for x in xrange
          xpos  = (x<<5) - @oxFlash
          # Get data
          id    = @flash_data[x, y, 0]
          # process RGB and fill flash bitmap with color
          r     = (id>>8) & 15
          g     = (id>>4) & 15
          b     = (id)    & 15
          tmpcolor.set(r*16, g*16, b*16)
          bitmap.fill_rect(xpos, ypos, 32, 32, tmpcolor)
        end
      end
    end
    #
  end
  #--------------------------------------------------------------------------
  # * Refresh Layer 0
  #     autotiles : autotile flag
  #--------------------------------------------------------------------------
  def refreshLayer0(autotiles=false)
    #
    # acquire x/y position based on origin and layer
    ptX = @ox - @oxLayer0
    ptY = @oy - @oyLayer0
    #
    # if no autotiles, 
    if !autotiles && !@firsttime && !@usedsprites &&
        ptX >= 0 && ptX+@viewport.rect.width <= @layer0.bitmap.width &&
        ptY >= 0 && ptY+@viewport.rect.height <= @layer0.bitmap.height
      # Blit into the layer based on the clip
      if @layer0clip
         @layer0.ox=0
         @layer0.oy=0
         @layer0.src_rect.set(ptX.round,ptY.round,
             @viewport.rect.width,@viewport.rect.height)
      else
        @layer0.ox=ptX.round
        @layer0.oy=ptY.round
        @layer0.src_rect.set(0,0,@layer0.bitmap.width,@layer0.bitmap.height)
      end
      # Exit the method true
      return true
    end
    #
    # Get map dimensions and bitmap
    width  = @layer0.bitmap.width
    height = @layer0.bitmap.height
    bitmap = @layer0.bitmap
    ysize  = @map_data.ysize
    xsize  = @map_data.xsize
    zsize  = @map_data.zsize
    #
    # If autotiles 
    if autotiles
      # Exit if autotiles refreshed, priority length at 0 and not shown
      return true if @fullyrefreshedautos && @prioautotiles.length == 0
      return true if !shown?
      # Set start and end ranges
      xStart = (@oxLayer0>>5)
      xStart = 0 if xStart<0
      yStart = (@oyLayer0>>5)
      yStart = 0 if yStart<0
      xEnd   = xStart+(width>>5)+1
      yEnd   = yStart+(height>>5)+1
      xEnd   = xsize if xEnd>xsize
      yEnd   = ysize if yEnd>ysize
      #
      # Exit true based on start/end range
      return true if xStart>=xEnd || yStart>=yEnd
      #
      # Get transparencey colorand set rectacle areas
      trans     = Color.new(0,0,0,0)
      temprect  = Rect.new(0,0,0,0)
      tilerect  = Rect.new(0,0,32,32)
      #
      # Set range and reset counts
      range         = 0...zsize
      overallcount  = 0
      count         = 0
      # If auto not fully refreshed
      if !@fullyrefreshedautos
        # Sort through x and y ranges
        for y in yStart..yEnd
          for x in xStart..xEnd
            # Assume no autotile
            haveautotile=false
            # Sort through depth
            for z in range
              # Get tile ID
              id = @map_data[x, y, z]
              # skip if (take your choice!!!!)
              next if id < 48 || id >= 384
              next if @priorities[id] != 0 || !@priorities[id]
              next if @framecount[id/48-1] < 2
              # Break after finding autotile
              haveautotile = true
              break
            end
            # skip if still no autotile
            next if !haveautotile
            # increase overall count
            overallcount += 1
            # Get area range
            xpos = (x<<5) - @oxLayer0
            ypos = (y<<5) - @oyLayer0
            # Fill the area if count is less than 2000
            bitmap.fill_rect(xpos, ypos, 0, 0, trans) if overallcount <= 2000
            # Sort within range
            for z in range
              # Get map data
              id = @map_data[x,y,z]
              next if id<48 || @priorities[id]!=0 || !@priorities[id]
              if overallcount>2000
                count=addTile(@autosprites, count, xpos, ypos, id)
                next
              elsif id>=384
                temprect.set((id - 384) % 8 * 32, (id - 384) / 8 * 32,32,32)
                bitmap.blt(xpos,ypos,@tileset,temprect)
              else
                # get the bitmap
                tilebitmap = @autotileInfo[id]
                # If it does not exist
                if !tilebitmap
                  # determine animation
                  anim  = autotileFrame(id)
                  # Exit if no animation
                  next if anim < 0
                  # create a blank tile bitmap
                  tilebitmap  = Bitmap.new(32,32)
                  # blit into position
                  bltAutotile(tilebitmap, 0, 0, id, anim)
                  # Save the bitmap into the autotile
                  @autotileInfo[id] = tilebitmap
                end
                # blit in area range
                bitmap.blt(xpos, ypos, tilebitmap, tilerect)
                #
              end
            end
          end
        end
      else
        #
        # Cycle through tiles in autotile priorities 
        for tile in @prioautotiles
          # get tile coordinates
          x = tile[0]
          y = tile[1]
          # Skip if out of range
          next if x < xStart || x > xEnd
          next if y < yStart || y > yEnd
          #
          # Increase overall count
          overallcount+=1
          #
          # Calculate position 
          xpos = (x<<5) - @oxLayer0
          ypos = (y<<5) - @oyLayer0
          #
          # Fill the are transparent if count not yet reached 2000
          bitmap.fill_rect(xpos,ypos,0,0,trans) if overallcount <= 2000
          #
          for z in range
            # Get map data
            id = @map_data[x,y,z]
            # 
            next if id < 48 || @priorities[id] != 0 || !@priorities[id]
            # Define count and break from depth loop if count exceeds 2000
            if overallcount > 2000
              count = addTile(@autosprites, count, xpos, ypos, id)
              next
            # Or blit tile if not an autotile
            elsif id >= 384
              temprect.set((id - 384) % 8 * 32, (id - 384) / 8 * 32,32,32)
              bitmap.blt(xpos,ypos,@tileset,temprect)
            # Otherwise handle autotile
            else
              tilebitmap = @autotileInfo[id]
              if !tilebitmap
                anim  = autotileFrame(id)
                next  if anim<0
                tilebitmap = Bitmap.new(32,32)
                bltAutotile(tilebitmap,0,0,id,anim)
                @autotileInfo[id] = tilebitmap
              end
              # Blit into the bitmap
              bitmap.blt(xpos, ypos, tilebitmap, tilerect)
            end
          end
        end
        #
      end
      #
      # Frame update when count reaches 2000
      Graphics.frame_reset if overallcount>2000
      # Reset flag and exit method
      @usedsprites = false
      return true
      #
    end
    #
    # Exit method false if 
    return false if @usedsprites
    #
    @firsttime  = false
    @oxLayer0   = @ox - (width>>2)
    @oyLayer0   = @oy - (height>>2)
    if @layer0clip
      @layer0.ox  = 0
      @layer0.oy  = 0
      @layer0.src_rect.set(width>>2,height>>2,
         @viewport.rect.width,@viewport.rect.height)
    else
      @layer0.ox  = (width>>2)
      @layer0.oy  = (height>>2)
    end
    #
    # Clear the layer bitmap
    @layer0.bitmap.clear
    # Re-acquire layer ranges
    @oxLayer0 = @oxLayer0.floor
    @oyLayer0 = @oyLayer0.floor
    xStart    = (@oxLayer0>>5)
    yStart    = (@oyLayer0>>5)
    xStart    = 0       if xStart < 0
    yStart    = 0       if yStart < 0
    xEnd      = xStart + (width>>5)  + 1
    yEnd      = yStart + (height>>5) + 1
    xEnd      = xsize   if xEnd >= xsize
    yEnd      = ysize   if yEnd >= ysize
    #
    # As long as a valid range from start to end
    if xStart < xEnd && yStart < yEnd
      #
      # reset the temp rectangle and set ranges
      tmprect = Rect.new(0,0,0,0)
      yrange = yStart...yEnd
      xrange = xStart...xEnd
      #
      # Cycle through depth
      for z in 0...zsize
        for y in yrange
          ypos = (y<<5) - @oyLayer0
          for x in xrange
            xpos = (x<<5) - @oxLayer0
            # Get the tile data
            id = @map_data[x, y, z]
            # Skip if no valid data or not at 0 priority
            next if id==0 || @priorities[id] != 0 || !@priorities[id]
            # If a normal tile
            if id >= 384
              # Set and blit the proper tile in place
              tmprect.set((id - 384) % 8 * 32, (id - 384) / 8 * 32,32,32)
              bitmap.blt(xpos,ypos,@tileset,tmprect)
            # otherwise handle autotile
            else
              frame=autotileFrame(id)
              bltAutotile(bitmap,xpos,ypos,id,frame)
            end
          end
        end
      end
      #
      Graphics.frame_reset
    end
    #
    return true
    #
  end
  #--------------------------------------------------------------------------
  # * Get Resize Factor
  # -- Depreciated (Not used in script at time of acquisition)
  #--------------------------------------------------------------------------
  def getResizeFactor
    #return $game_map.tilemap_zoom_x
    ##return $ResizeFactor ? $ResizeFactor : 1.0
  end
  #--------------------------------------------------------------------------
  # * Set Visibility
  #     val : value
  #--------------------------------------------------------------------------
  def visible=(val)
    #
    wasshown  = @visible
    @visible  = val
    @nowshown = (!wasshown && val)
    #
  end
end
#==============================================================================
# ** Game_Map
#------------------------------------------------------------------------------
#  This class handles the map. It includes scrolling and passable determining
#  functions. Refer to "$game_map" for the instance of this class.
#==============================================================================
class Game_Map
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_reader   :map                      # Current tile
  attr_accessor :tilemap_tone             # Current tone
  attr_accessor :tilemap_plane            # Current plane
  attr_accessor :tilemap_zoom_x           # Current scale (allows x stretching)
  attr_accessor :tilemap_zoom_y           # Current scale (allows y stretching)
  attr_accessor :tilemap_tile_width       # Current tile width (usually 32px)
  attr_accessor :tilemap_tile_height      # Current tile height (usually 32px)
  
  #--------------------------------------------------------------------------
  # * Alias Listings
  #--------------------------------------------------------------------------
  alias seph_orig_game_map_tilemapnew_initialize initialize
  
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize
    #
    # Perform the original method
    seph_orig_game_map_tilemapnew_initialize
    #
    # Add new values for tilemap zoom
    @tilemap_tone        = nil
    @tilemap_plane       = false
    @tilemap_zoom_x      = 1.0
    @tilemap_zoom_y      = 1.0
    @tilemap_tile_width  = 32
    @tilemap_tile_height = 32
    #
  end
  
endInstructions
Plenty, and in the script.
FAQ
Made in conjunction with Screen Size for RMXP and Poccil's Map Zoom.
I was looking for a Tilemap script that could be adapted with a Zoom Map script... any zoom map script. And this one was the most complete that could cover all three map layers and properly worked with tilemap priorities.
The original script can be found in the 3rd post of (THIS) thread.
Compatibility
Designed for RPGMaker XP. RUBY 2.7 Compliant
Credits and Thanks
Thanks to Poccil for the creation of the original tilemap script, and thanks to Mel of Save-Point.Org for noticing a priority layering issue
Terms and Conditions
Free for use, even in commercial products. However, due credit to myself, Poccil and Mel is a necessity.
Up is down, left is right and sideways is straight ahead. - Cord "Circle of Iron", 1978 (written by Bruce Lee and James Coburn... really...)
	  Above are clickable links

 
 
 Poccil's Tilemap Rewrite
 Poccil's Tilemap Rewrite
 
 
![[Image: QrnbKlx.jpg]](https://i.imgur.com/QrnbKlx.jpg)
![[Image: sGz1ErF.png]](https://i.imgur.com/sGz1ErF.png)
![[Image: liM4ikn.png]](https://i.imgur.com/liM4ikn.png)
![[Image: fdzKgZA.png]](https://i.imgur.com/fdzKgZA.png)
![[Image: sj0H81z.png]](https://i.imgur.com/sj0H81z.png)
![[Image: QL7oRau.png]](https://i.imgur.com/QL7oRau.png)
![[Image: uSqjY09.png]](https://i.imgur.com/uSqjY09.png)
![[Image: GAA3qE9.png]](https://i.imgur.com/GAA3qE9.png)
![[Image: 2Hmnx1G.png]](https://i.imgur.com/2Hmnx1G.png)
![[Image: BwtNdKw.png%5B]](https://i.imgur.com/BwtNdKw.png%5B)