Код:
	#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
# Drago - Multi Layer
# Version: 2.02, Caveman fix: 1.02
# Author : LiTTleDRAgo
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
($imported ||= {})[:drg_multi_layer] = 2.02
core = "This script needs Drago - Core Engine ver 1.43 or above"
rmvx = "This script not for RMVX"
$imported[:drg_core_engine]         || raise(core)
LiTTleDRAgo::XP || LiTTleDRAgo::VXA || raise(rmvx)
    
#==============================================================================
# ** Spriteset_Map
#------------------------------------------------------------------------------
#  This class brings together map screen sprites, tilemaps, etc. It's used
# within the Scene_Map class.
#==============================================================================
class Spriteset_Map
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_sec_reader :tilemap_layer, 'Array.new'
  #--------------------------------------------------------------------------
  # * Alias Listing
  #--------------------------------------------------------------------------
  alias_method     :initialize_multi_layer_cr, :initialize
  alias_sec_method :update_multi_layer_cr,     :update
  alias_sec_method :dispose_multi_layer_cr,    :dispose
  #--------------------------------------------------------------------------
  # * New Method : create_multi_layer
  #--------------------------------------------------------------------------
  def create_multi_layer
    return if @tilemap.not.is_a?(Tilemap)
    tilemap_layer.dispose
    tilemap_layer.clear
    @layer_data = $game_map.layer_data
    $game_map.layer_data.each_with_index do |data,index|
      temp_map = Game_Map.new
      temp_map.setup($game_map.layer_subs.at(index))
      tileset = LiTTleDRAgo.cache.tileset(temp_map.tileset_name)
      tilemap_layer[index] = Tilemap.new(@viewport1)
      tilemap_layer[index].map_data = temp_map.data
      if $game_map.map_type == 'XP'
        tilemap_layer[index].tileset = tileset
        for i in 0..6
          autotile_name = LiTTleDRAgo.cache.autotile(temp_map.autotile_names[i])
          tilemap_layer[index].autotiles[i] = autotile_name
        end
        tilemap_layer[index].priorities = temp_map.priorities
      else
        load = "This script needs Drago - XP Map Loader ver 1.10 or above"
        $imported[:drg_xp_map_loader] || raise(load)
        temp_map.tileset.tileset_names.each_with_index do |name, i|
          @tilemap_layer[index].bitmaps[i] = LiTTleDRAgo.cache.tileset(name)
        end
        @tilemap_layer[index].flags = temp_map.tileset.flags
      end
    end
  end
  #--------------------------------------------------------------------------
  # * Aliased Method : update
  #--------------------------------------------------------------------------
  def update
    update_multi_layer_cr
    create_multi_layer if @layer_data != $game_map.layer_data
    tilemap_layer.ox = @tilemap.ox 
    tilemap_layer.oy = @tilemap.oy 
    tilemap_layer.update
  end
  #--------------------------------------------------------------------------
  # * Aliased Method : dispose
  #--------------------------------------------------------------------------
  def dispose
    tilemap_layer.dispose
    dispose_multi_layer_cr
  end
  #-------------------------------------------------------------------------
  # * Drago - Custom Resolution
  #-------------------------------------------------------------------------
  if $imported[:drg_custom_resolution] && LiTTleDRAgo::XP
    #-------------------------------------------------------------------------
    # * Alias Listing
    #-------------------------------------------------------------------------
    alias_sec_method :create_tilemap_ex_multi_layer,  :create_tilemap_ex
    alias_sec_method :update_new_tilemap_multi_layer, :update_tilemap_ex
    alias_sec_method :dispose_tilemap_ex_multi_layer, :dispose_tilemap_ex
    #-------------------------------------------------------------------------
    # * Aliased method: create_tilemap_ex
    #-------------------------------------------------------------------------
    def create_tilemap_ex
      create_tilemap_ex_multi_layer
      create_multi_layer_ex
    end
    #-------------------------------------------------------------------------
    # * New method: create_multi_layer_ex
    #-------------------------------------------------------------------------
    def create_multi_layer_ex
      @tilemap_layer_ex && @tilemap_layer_ex.flatten.dispose
      @tilemap_layer_ex = []
      @extra_res.each_index do |a| 
        @tilemap_layer_ex[a] ||= []
        $game_map.layer_data.each_with_index do |d,b|
          temp_map = Game_Map.new
          temp_map.setup($game_map.layer_subs.at(b))
          tileset = LiTTleDRAgo.cache.tileset(temp_map.tileset_name)
          @tilemap_layer_ex[a][b] = Tilemap.new(@viewport_ex[a])
          @tilemap_layer_ex[a][b].tileset = tileset
          for i in 0..6
            autotile = LiTTleDRAgo.cache.autotile(temp_map.autotile_names[i])
            @tilemap_layer_ex[a][b].autotiles[i] = autotile
          end
          @tilemap_layer_ex[a][b].map_data   = temp_map.data
          @tilemap_layer_ex[a][b].priorities = temp_map.priorities
        end
      end
    end
    #-------------------------------------------------------------------------
    # * Aliased method: update_new_tilemap
    #-------------------------------------------------------------------------
    def update_tilemap_ex
      update_new_tilemap_multi_layer
      @tilemap_ex && @extra_res.each_index do |a| 
        $game_map.layer_data.each_index do |b|
          if @tilemap_layer_ex && @tilemap_layer_ex[a] && 
            @tilemap_layer_ex[a][b] && @tilemap_layer_ex[a][b].not.disposed?
            @tilemap_ex[a].not.disposed?
            @tilemap_layer_ex[a][b].ox = @tilemap_ex[a].ox
            @tilemap_layer_ex[a][b].oy = @tilemap_ex[a].oy
            @tilemap_layer_ex[a][b].update
          end
        end
      end
    end
    #-------------------------------------------------------------------------
    # * Aliased method: dispose_tilemap_ex
    #-------------------------------------------------------------------------
    def dispose_tilemap_ex
      @tilemap_layer_ex && @tilemap_layer_ex.flatten.dispose
      dispose_tilemap_ex_multi_layer
    end
  end
end
#==============================================================================
# ** Game_Map
#------------------------------------------------------------------------------
#  This class handles maps. It includes scrolling and passage determination
# functions. The instance of this class is referenced by $game_map.
#==============================================================================
class Game_Map
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------  
  attr_sec_accessor :layer_data, :layer_subs, 'Array.new'
  attr_reader :layer_tilesets
  attr_reader       :map_type
  #--------------------------------------------------------------------------
  # * Alias Method
  #--------------------------------------------------------------------------
  alias_sec_method :setup_multilayer, :setup
  #--------------------------------------------------------------------------
  # * Aliased Method : setup
  #--------------------------------------------------------------------------
  def setup(*args)
    setup_multilayer(*args)   
    @map_type ||= 'XP'
    @is_load = true # hot fix
    decide_map_layer(*args)          
  end
  #--------------------------------------------------------------------------
  # * Overwriten Method : decide_map_layer
  #--------------------------------------------------------------------------
  def decide_map_layer(*args)
    return if layer_subs.include?(@map_id)
    return if @is_load == nil
    @layer_data, @layer_subs = [], [] 
    @layer_tilesets = []
    
    child_ids.each do |submap_id|
      map_info = mapInfo[submap_id]
      unless map_info.nil?
        if map_info.parent_id == map_id &&
          map_info.name.include?("[" + 'join' + "]")
        then
          submap = load_map_data(submap_id, @map_type=='XP' ? :rxdata : :rvdata2)
          unless submap
            print "Map #{submap_id} doesn't exist" 
            next 
          end
          if [submap.width,submap.height] != [width,height]
            raise "Dimension of child maps must be same with parent's dimension"
          end
         # p sprintf("tileset=%d, cur_size=%d", submap.tileset_id, data.zsize)
          @layer_tilesets << submap.tileset_id
          @layer_data << data
          @layer_subs << submap_id
          old_zsize = data.zsize
          data.resize(data.xsize, data.ysize, old_zsize + 3)
          for x in 0...data.xsize
            for y in 0...data.ysize
              if @map_type == 'XP' 
                data[x, y, old_zsize]     = submap.data[x, y, 0]
                data[x, y, old_zsize + 1] = submap.data[x, y, 1]
                data[x, y, old_zsize + 2] = submap.data[x, y, 2]
              else
                data[x, y, old_zsize]     = submap.data[x, y, 1]
                data[x, y, old_zsize + 1] = submap.data[x, y, 2]
              end
            end
          end
        end
        @need_redraw = true
      end
    end
  end
  # for separate passability
  def check_passage(x, y, bit)
    pass = true
    # проверяем первую карту
    all_tiles1(x, y).each do |tile_id|
      flag = tileset.flags[tile_id]
      if flag & 0x10 != 0                       # [?]: No effect on passage
        if flag & bit == 0 # [0] : Passable but star
          next   
        end
        if flag & bit == bit   # [?] : Impassable
          pass = false 
          break
        end
      else
        if flag & bit == 0  # [0] : Passable
          pass = true  
          break
        end
        if flag & bit == bit   # [?] : Impassable
          pass = false 
          break
        end
      end
    end
    if pass == false                           # Impassable
      return false 
    end
    
    idx = 0
   
    @layer_tilesets.each do |tileset_n|     
      all_tiles_n(x, y, idx).each do |tile_id|
        flag = $data_tilesets[tileset_n].flags[tile_id]
        if flag & 0x10 != 0    # [?]: No effect on passage
          if flag & bit == 0 # [0] : Passable but star
            next   
          end
          if flag & bit == bit   # [?] : Impassable
            pass = false 
            break
          end
        else
          if flag & bit == 0  # [0] : Passable
            pass = true  
            break
          end
          if flag & bit == bit   # [?] : Impassable
            pass = false 
            break
          end
        end
      end
      
      if pass == false                           # Impassable
        return false 
      end
      idx = idx +1
    end
    
    return pass                                
  end
  
  def all_tiles1(x, y)
    tile_events_xy(x, y).collect {|ev| ev.tile_id } + layered_tiles1(x, y)
  end
  
  def layered_tiles1(x, y)
    _z_data = z_data.reject {|s| s >= 3 }
    _z_data.collect {|z| tile_id(x, y, z) }
  end
  
  def all_tiles_n(x, y, idx)
    tile_events_xy(x, y).collect {|ev| ev.tile_id } + layered_tiles_n(x, y, idx)
  end
  
  def layered_tiles_n(x, y, idx)
    idx1 = 3 + idx*3
    idx2 = 5 + idx*3
   # p sprintf("idx1=%d,idx2=%d",idx1,idx2)
    _z_data = z_data.reject {|s| s <= idx1 || s > idx2 }
    _z_data.collect {|z| tile_id(x, y, z) }
  end
  
  #--------------------------------------------------------------------------
  # * If RMXP
  #--------------------------------------------------------------------------
  if LiTTleDRAgo::XP
    #--------------------------------------------------------------------------
    # * Overwriten Method : passable?
    #--------------------------------------------------------------------------
    def passable?(x, y, d, s = nil)
      return false unless valid?(x, y)
      bit = (1 << (d / 2 - 1)) & 0x0f
      (event_tiles(x, y, s) + layered_tiles(x, y)).each do |tile_id|
        return false if tile_id.nil?
        if @passages[tile_id] & bit != 0
          return false
        elsif @passages[tile_id] & 0x0f == 0x0f
          return false
        elsif @priorities[tile_id] == 0
          return true
        end
      end
      return true
    end
    #--------------------------------------------------------------------------
    # * Overwriten Method : bush?
    #--------------------------------------------------------------------------
    def bush?(x, y)
      return false if @map_id == 0
        layered_tiles(x, y).each do |tile_id|
        return false if tile_id.nil?
        passage = @passages[tile_id] 
        return true if passage & 0x40 == 0x40
      end
      return false
    end
    #--------------------------------------------------------------------------
    # * Overwriten Method : counter?
    #--------------------------------------------------------------------------
    def counter?(x, y)
      return false if @map_id == 0
      layered_tiles(x, y).each do |tile_id|
        return false if tile_id.nil?
        passage = @passages[tile_id] 
        return true if passage & 0x80 == 0x80
      end
      return false
    end
    #--------------------------------------------------------------------------
    # * Overwriten Method : terrain_tag
    #--------------------------------------------------------------------------
    def terrain_tag(x, y)
      return 0 if @map_id == 0
      layered_tiles(x, y).each do |tile_id|
        return 0 if tile_id.nil?
        tag = @terrain_tags[tile_id] 
        return tag if tag > 0
      end
      return 0
    end
    #--------------------------------------------------------------------------
    # * New Method : layered_tiles
    #--------------------------------------------------------------------------
    def layered_tiles(x, y)
      z_data.collect {|z| tile_id(x, y, z) }
    end
    #--------------------------------------------------------------------------
    # * New Method : z_data
    #--------------------------------------------------------------------------
    unless method_defined?(:z_data)
      def z_data
        (0...data.zsize).to_a.reverse
      end
    end
    #--------------------------------------------------------------------------
    # * New Method : event_tiles
    #--------------------------------------------------------------------------
    def event_tiles(x, y, s=nil)
      return [] unless self.respond_to?(:events_xy_nt)
      e = events_xy_nt(x,y).select {|e| e.tile_id >= 0 && e != s }
      e.collect {|event| event.tile_id }
    end
    #--------------------------------------------------------------------------
    # * New Method : tile_id
    #--------------------------------------------------------------------------
    unless method_defined?(:tile_id)
      def tile_id(x, y, z)
        data[x, y, z]
      end
    end
  end
end
 
Социальные закладки