查看: 4278|回复: 1

[转载发布] 【梅莉渣翻】在RMVA中使用RMXP的地图及多层地图

[复制链接]
梦石
0
星屑
1078
在线时间
127 小时
注册时间
2017-9-27
回帖
32
发表于 2017-12-2 20:42:11 | 显示全部楼层 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有账号?注册会员

×
https://littledrago.blogspot.jp/2014/08/rgss3-xp-map-loader-ii.html
↑原作者地址(需要科学上网)作者 : LiTTleDRAgo



[pre lang="ruby"]#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
# XP地图读取及多层地图制作
# 版本: 2.05
# 作者 : LiTTleDRAgo
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
($imported ||= {})[:drg_xp_map_loader] = 2.05
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
#
# 介绍:
#
#   XP地图读取及多层地图制作的整合脚本第2版。
#
# 特性:
#   
#  读取RMXP制作的地图:
#  - 在Drago的Custom Resolution II这一脚本中,缩放功能不可使用。
#  - 可用于RMVA读取RMXP的地图,不可反向用RMXP读取RMVA的地图。
#  - 只在RMVA可用。
#
#  多层地图:
#  - 层数越多卡得越厉害。
#
#  译者补充,原文来自littledrago.blogspot.jp/2014/08/rgss3-xp-map-loader-ii.html)
#  使用方法:
#  - 需要前置脚本Drago - Core Engine和Custom Resolution(超长,懒得翻译用法)
#
#  - 读取RMXP制作的地图:先在RMXP中做好你的地图,然后把所有地图涉及的文件复制到
# 你的RMVA工程的文件夹下对应位置。
# 包括:原工程\Data文件夹下所有名为MapXXX.rxdata(XXX是地图ID),Tileset.rxdata以及
# 原工程\Graphics文件夹下的Autotiles, Fog, Panorama,Tileset这四个文件夹所有内容。
#  - 请注意把需要对应的RMVA地图的文件名与复制来的XP地图文件名一一对应起来。
#
#  - 多层地图:
#  - 在需要使用多层地图的原地图下面建立一个名叫"[join]"的子地图。
#  - 可以用写标签[join:1][join:2]等指定多层。是否显示的条件可以在下面设定。
#  - 同类脚本可能会冲突
#  - 需要额外注意A5和B图块中一些透明但不通行的图块,如果通行度不正常请首先排查。
#
#  注意:
#  - 此脚本只调用RMXP工程中的地图、远景、雾图形、通行度、灌木柜台等特殊地形标志,
#  其余图像文件及地图涉及到的BGM、BGS仍沿用原本的RMVA工程。
#
#==============================================================================
module LiTTleDRAgo
  
  # Condition for layer to be joined
  MultiLayerCond = proc do |i|
    condition = {
   
      1 => $game_switches[1], # 1号开关开启时本层显示,否则不显示
      2 => $game_variables[1] == 200, #1号变量=200时显示,否则不显示
      
      }
    condition   #请勿删除本行
  end
  
  
end
  
core  = "This script needs Drago - Core Engine ver 1.44 or above"
implemented = "%1$s has already implemented, Please remove the %1$s script"

($imported[:drg_core_engine] || 0) >= 1.44 || raise(core)
($imported[:drg_multi_layer])&& raise(sprintf(implemented,"Multi Layer"))
#==============================================================================
# ** 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 :panorama_name, :fog_name,             'String.new'      
  attr_sec_accessor :panorama_hue, :fog_hue, :fog_zoom,    1        
  attr_sec_accessor :fog_opacity, :fog_blend_type,         0
  attr_sec_accessor :fog_sx, :fog_sy, :fog_ox, :fog_oy,    0
  attr_sec_accessor :fog_tone, :fog_tone_target,           'Tone.new(0,0,0)'
  attr_sec_accessor :multi_layer_condition_true,           'Array.new'
  attr_sec_accessor :multi_layer_condition_false,          'Array.new'
  attr_sec_reader   :xpmap,  'Array.new'            
  attr_sec_reader   :vxamap, 'Array.new'
  #--------------------------------------------------------------------------
  # * Class Variable
  #--------------------------------------------------------------------------
  tileset = "Data/Tilesets.rxdata"
  @@tileset_xp = File.exist?(tileset) ? load_data(tileset) : nil
  @@rpgmakerxp = LiTTleDRAgo::XP
  #--------------------------------------------------------------------------
  # * Define Method
  #--------------------------------------------------------------------------
  unless @@rpgmakerxp
    define_method(:zoom_x) { 1 }
    define_method(:zoom_y) { 1 }
  end
  #--------------------------------------------------------------------------
  # * Undefine Method
  #--------------------------------------------------------------------------
  if !@@rpgmakerxp && method_defined?(:zoom)
    undef :zoom, :zoom_in, :zoom_out, :zoom_x=, :zoom_y=, :start_zoom
  end
  #--------------------------------------------------------------------------
  # * Alias Listing
  #--------------------------------------------------------------------------
  alias_sec_method :xpmap_loader_setup,         :setup
  alias_sec_method :xpmap_loader_update,        :update
  alias_sec_method :layered_tiles_flag_vxlayer, :layered_tiles_flag?
  #--------------------------------------------------------------------------
  # * Aliased Method : setup
  #--------------------------------------------------------------------------
  def setup(*args)
    xpmap_loader_setup(*args)
    setup_map_xp
    setup_map_layer
  end
  #--------------------------------------------------------------------------
  # * New Method : setup_map_xp
  #--------------------------------------------------------------------------
  def setup_map_xp
    reset_map_xp
    map = sprintf("Map%03d",@map_id)
    b   = "The dimension on %1$s.rvdata2 %2$s and %1$s.rxdata %3$s is not same"
   
    return unless @@tileset_xp && File.exist?("Data/"+map+".rxdata")
    return if @@rpgmakerxp
    return if self.xpmap.detect {|xp| xp && xp[:map_id] == @map_id }
   
   
    _xp = load_map_data(@map_id,:rxdata)
    _sz   = [@map,_xp].flatten.map {|m| [m.width,m.height]}.uniq
    fail( sprintf( b, map, *_sz.map {|s| s.inspect})) if _sz.size > 1
   
    self.xpmap[0]                   = {}
    self.xpmap[0][:map_id]          = @map_id
    self.xpmap[0][:map]             = _xp
    self.xpmap[0][:tileset_id]      = _xp.tileset_id
    _xp = @@tileset_xp[_xp.tileset_id]
    self.xpmap[0][:tileset_name]    = _xp.tileset_name
    self.xpmap[0][:autotile_names]  = _xp.autotile_names
    self.xpmap[0][:passages]        = _xp.passages
    self.xpmap[0][:priorities]      = _xp.priorities
    self.xpmap[0][:terrain_tags]    = _xp.terrain_tags
   
    @panorama_name   = _xp.panorama_name
    @panorama_hue    = _xp.panorama_hue
    @fog_name        = _xp.fog_name
    @fog_hue         = _xp.fog_hue
    @fog_opacity     = _xp.fog_opacity
    @fog_blend_type  = _xp.fog_blend_type
    @fog_zoom        = _xp.fog_zoom
    @fog_sx          = _xp.fog_sx
    @fog_sy          = _xp.fog_sy
  end
  #--------------------------------------------------------------------------
  # * Aliased Method : update
  #--------------------------------------------------------------------------
  def update(*args)
    xpmap_loader_update(*args)
    update_fog unless @@rpgmakerxp
    update_layer_condition
  end
  #--------------------------------------------------------------------------
  # * New Method : reset_map_xp
  #--------------------------------------------------------------------------
  def reset_map_xp
    self.xpmap.clear
    self.vxamap.clear
    self.multi_layer_condition_true.clear
    self.multi_layer_condition_false.clear
    @mapinfo = nil
    self.clear_panorama unless @@rpgmakerxp
    self.clear_fog      unless @@rpgmakerxp
  end  
  #--------------------------------------------------------------------------
  # * New Method : setup_map_layer
  #--------------------------------------------------------------------------
  def setup_map_layer
    layered = false
    self.child_ids.each_with_index do |submap_id,index|
      next if self.vxamap.detect {|vxa| vxa && vxa[:map_id] == submap_id }
      next if self.xpmap.detect {|xp| xp && xp[:map_id] == submap_id }
      next unless (map_info = mapInfo[submap_id]).not.nil?
      next unless (map_info.parent_id == map_id)
      join = map_info.name[/\[\s*join\s*\]/]
      if map_info.name[/\[\s*join:\s*([-]?\d+)\s*\]/]
        id = $1.to_i
        cond = LiTTleDRAgo::MultiLayerCond.call(id)
        if !cond && multi_layer_condition_true.not.include?(id)
          @multi_layer_condition_true << id
        end
        if cond && multi_layer_condition_false.not.include?(id)
          @multi_layer_condition_false << id
        end
        join ||= cond
      end
      next unless join
      map     = sprintf("Map%03d",submap_id)
      org     = sprintf("Map%03d",map_id)
      notsame = "The dimension of Parent map and Child map must be same"
      
      if @@tileset_xp && File.exist?("Data/"+map+".rxdata")
        _xp = load_map_data(submap_id,:rxdata)
        _sz = [@map,_xp].flatten.map {|m| [m.width,m.height]}.uniq
        _sz.size > 1 && fail(notsame)
         
        self.xpmap[index+1]                   = {}
        self.xpmap[index+1][:map_id]          = submap_id
        self.xpmap[index+1][:map]             = _xp
        self.xpmap[index+1][:tileset_id]      = _xp.tileset_id
        _xp = @@tileset_xp[_xp.tileset_id]
        self.xpmap[index+1][:tileset_name]    = _xp.tileset_name
        self.xpmap[index+1][:autotile_names]  = _xp.autotile_names
        self.xpmap[index+1][:passages]        = _xp.passages
        self.xpmap[index+1][:priorities]      = _xp.priorities
        self.xpmap[index+1][:terrain_tags]    = _xp.terrain_tags
      elsif File.exist?("Data/"+map+".rvdata2")
        _vxa = load_map_data(submap_id,:rvdata2)
        _sz  = [@map,_vxa].flatten.map {|m| [m.width,m.height]}.uniq
        _sz.size > 1 && fail(notsame)
   
        self.vxamap[index] = {}
        self.vxamap[index][:map_id]     = submap_id
        self.vxamap[index][:map]        = _vxa
        self.vxamap[index][:tileset_id] = _vxa.tileset_id
        tileset = $data_tilesets[_vxa.tileset_id]
        self.vxamap[index][:tileset]    = tileset
      end
      layered = _xp || _vxa
    end
    spriteset.create_multi_layer if spriteset
  end  
  #--------------------------------------------------------------------------
  # * New Method : update_layer_condition
  #--------------------------------------------------------------------------
  def update_layer_condition
    meth = LiTTleDRAgo::MultiLayerCond
    condition = multi_layer_condition_true.any?  {|id| meth.call(id)    } ||
                multi_layer_condition_false.any? {|id| meth.not.call(id)}
    condition && [setup_map_xp, setup_map_layer]
  end
  #--------------------------------------------------------------------------
  # * New Method : reset_fog_variable
  #--------------------------------------------------------------------------
  def reset_fog_variable
    @fog_ox               =
    @fog_oy               =
    @fog_tone             =
    @fog_tone_target      = nil
    @fog_tone_duration    =
    @fog_opacity_duration =
    @fog_opacity_target   = 0
  end
  #--------------------------------------------------------------------------
  # * New Method : start_fog_tone_change
  #--------------------------------------------------------------------------
  unless method_defined?(:start_fog_tone_change)
    def start_fog_tone_change(tone, duration)
      @fog_tone_target = tone.clone
      @fog_tone_duration = duration
      if @fog_tone_duration == 0
        @fog_tone = @fog_tone_target.clone
      end
    end
  end
  #--------------------------------------------------------------------------
  # * New Method : start_fog_opacity_chang
  #--------------------------------------------------------------------------
  unless method_defined?(:start_fog_opacity_change)
    def start_fog_opacity_change(opacity, duration)
      @fog_opacity_target = opacity * 1.0
      @fog_opacity_duration = duration
      if @fog_opacity_duration == 0
        @fog_opacity = @fog_opacity_target
      end
    end
  end
  #--------------------------------------------------------------------------
  # * New Method : change_panorama
  #--------------------------------------------------------------------------
  def change_panorama(panorama_name = '',panorama_hue = 0)
    @panorama_name = panorama_name
    @panorama_hue  = panorama_hue
  end
  #--------------------------------------------------------------------------
  # * New Method : clear_panorama
  #--------------------------------------------------------------------------
  def clear_panorama(*args)
    change_panorama
  end
  #--------------------------------------------------------------------------
  # * New Method : change_fog
  #--------------------------------------------------------------------------
  def change_fog(name='',hue=0,opac = 60, blend = 0,zoom = 1.0,sx = 0,sy = 0)
    @fog_name       = name
    @fog_hue        = hue
    @fog_opacity    = opac
    @fog_blend_type = blend
    @fog_zoom       = zoom
    @fog_sx         = sx
    @fog_sy         = sy
  end
  #--------------------------------------------------------------------------
  # * New Method : clear_fog
  #--------------------------------------------------------------------------
  def clear_fog(*args)
    change_fog
  end
  #--------------------------------------------------------------------------
  # * New Method : update_fog
  #--------------------------------------------------------------------------
  unless method_defined?(:update_fog)
    def update_fog
      @fog_ox = fog_ox - fog_sx / 8.0
      @fog_oy = fog_oy - fog_sy / 8.0
      if (@fog_tone_duration ||= 0) >= 1
        d = (@fog_tone_duration ||= 0)
        target = fog_tone_target
        fog_tone.red   = (fog_tone.red * (d - 1) + target.red) / d
        fog_tone.green = (fog_tone.green * (d - 1) + target.green) / d
        fog_tone.blue  = (fog_tone.blue * (d - 1) + target.blue) / d
        fog_tone.gray  = (fog_tone.gray * (d - 1) + target.gray) / d
        @fog_tone_duration -= 1
      end
      if (@fog_opacity_duration ||= 0) >= 1
        d = (@fog_opacity_duration ||= 0)
        @fog_opacity  = (fog_opacity * (d-1) + (@fog_opacity_target||=0)) / d
        @fog_opacity_duration -= 1
      end
    end
  end
  #--------------------------------------------------------------------------
  # * New Method : tile_id_obj
  #--------------------------------------------------------------------------
  def tile_id_obj(obj, x, y, z)
    if $game_map.respond_to?(:reverse) && $game_map.reverse && LiTTleDRAgo::XP
      obj.reverse_data[x, y, z] || 0
    else
      obj.data[x, y, z] || 0
    end
  end
  #--------------------------------------------------------------------------
  # * New Method : collect_flag_tiles_vxa
  #--------------------------------------------------------------------------
  def collect_flag_tiles_vxa(x,y,*flag)
    result = []
    vxamap.compact.each do |map|
      result += [2, 1, 0].collect do |z|
        tile_id = tile_id_obj(map[:map],x, y, z)
        [tile_id] + flag.collect {|s| map.flags[tile_id]}
      end
    end
    return result
  end
  #--------------------------------------------------------------------------
  # * New Method : collect_flag_tiles_xp
  #--------------------------------------------------------------------------
  def collect_flag_tiles_xp(x,y,*flag)
    result = []
    xpmap.compact.each do |map|
      result += [2, 1, 0].collect do |z|
        tile_id = tile_id_obj(map[:map],x, y, z)
        [tile_id] + flag.collect {|s| map[tile_id]}
      end
    end
    return result
  end
  #--------------------------------------------------------------------------
  # * New Method : collect_flag_tiles_original
  #--------------------------------------------------------------------------
  def collect_flag_tiles_original(x,y,*flag)
    all_tiles_rep(x, y).collect do |t_id|
      @@rpgmakerxp ? [t_id] + flag.collect {|map| map[t_id]} :
      [t_id, tileset.flags[t_id]]
    end
  end
  #--------------------------------------------------------------------------
  # * Aliased Method : layered_tiles_flag?
  #--------------------------------------------------------------------------
  def layered_tiles_flag?(x, y, bit)
    xp       = collect_flag_tiles_xp(x,y,:passages)
    vxa      = collect_flag_tiles_vxa(x,y,:tileset)
    original = collect_flag_tiles_original(x,y,@passages)
    if @@rpgmakerxp
      result = (xp + vxa + original).any? { |id,flag| flag & bit != 0 }
    else
      result   = layered_tiles_flag_vxlayer(x, y, bit)
      result ||= (xp + vxa ).any? { |id,flag| flag & bit != 0 }
    end
    return result
  end
  #--------------------------------------------------------------------------
  # * Overwriten Method : check_passage
  #--------------------------------------------------------------------------
  def check_passage(x, y, bit)
    original = collect_flag_tiles_original(x,y,@passages)
    xp       = collect_flag_tiles_xp(x,y,:passages)
    vxa      = collect_flag_tiles_vxa(x,y,:tileset)
    ( xp + vxa + original ).each do |t_id,flag,prio|
      next if flag & 0x10 != 0            # [☆]: No effect on passage
      #return true  if flag & bit == 0     # [○] : Passable
      return false if flag & bit != 0     # [×] : Impassable
      return false if flag & bit == bit   # [×] : Impassable
      return true  if prio && prio == 0    # [○] : Passable
    end
    return true#false                          # Impassable
  end
  #--------------------------------------------------------------------------
  # * Overwriten Method : terrain_tag
  #--------------------------------------------------------------------------
  def terrain_tag(x, y)
    return 0 unless valid?(x, y)
    original = collect_flag_tiles_original(x,y,@terrain_tags)
    xp  = collect_flag_tiles_xp(x,y,:terrain_tags)
    vxa = collect_flag_tiles_vxa(x,y,:tileset).map {|t| t >> 12}
    (xp + vxa).each { |t_id,tag| return tag if tag > 0 }
    (original).each do |t_id,flag|
      tag = @@rpgmakerxp ? flag : flag >> 12
      return tag if tag > 0
    end
    return 0
  end
  #--------------------------------------------------------------------------
  # * Overwriten Method : passable?
  #--------------------------------------------------------------------------
  if @@rpgmakerxp
    def passable?(x, y, d, s = nil)
      original = (event_tiles(x, y, s) + layered_tiles(x, y)).map do |t_id|
        [t_id, @passages[t_id], @priorities[t_id]]
      end
      xp    = collect_flag_tiles_xp(x,y,:passages,:priorities)
      vxa   = collect_flag_tiles_vxa(x,y,:tileset)
      bit   = (1 << (d / 2 - 1)) & 0x0f
      (xp + vxa + original ).each do |t_id,flag,prio|
        next if flag & 0x10 != 0             # [☆]: No effect on passage
        return false if flag & bit != 0      # [×] : Impassable
        return false if flag & 0x0f == 0x0f  # [×] : Impassable
        return true  if prio && prio == 0    # [○] : Passable
      end
      return true                            # [○] : Passable
    end
    #--------------------------------------------------------------------------
    # * Overwriten Method : bush?
    #--------------------------------------------------------------------------
    def bush?(x, y)
      valid?(x, y) && layered_tiles_flag?(x, y, 0x40)
    end
    #--------------------------------------------------------------------------
    # * Overwriten Method : counter?
    #--------------------------------------------------------------------------
    def counter?(x, y)
      valid?(x, y) && layered_tiles_flag?(x, y, 0x80)
    end
  end
  #--------------------------------------------------------------------------
  # * New Method : event_tiles
  #--------------------------------------------------------------------------
  def event_tiles(x, y, s = nil)
    e = events_xy(x,y).select {|e| e.tile_id > 0 && e != s && !e.through}
    e.collect {|event| event.tile_id }
  end
  #--------------------------------------------------------------------------
  # * Replicated Method : layered_tiles
  #--------------------------------------------------------------------------
  unless method_defined?(:layered_tiles)
    def layered_tiles(x, y)
      [2, 1, 0].collect {|z| tile_id_obj(@map, x, y, z) }
    end
  end
  #--------------------------------------------------------------------------
  # * Replicated Method : all_tiles_rep
  #--------------------------------------------------------------------------
  unless method_defined?(:all_tiles_rep)
    def all_tiles_rep(x, y)
      event_tiles(x, y) + layered_tiles(x,y)
    end
  end
  #--------------------------------------------------------------------------
  # * Replicated Method : events_xy
  #--------------------------------------------------------------------------
  unless method_defined?(:events_xy)
    def events_xy(x, y)
      @events.values.select {|event| event.x == x && event.y == y }
    end
  end
end
  
#==============================================================================
# ** RPG
#------------------------------------------------------------------------------
#
#==============================================================================
module RPG
  #============================================================================
  # ** Map
  #----------------------------------------------------------------------------
  #
  #============================================================================
  class Map
    attr_accessor     :tileset_id
    attr_sec_accessor :reverse_data, 'data.reverse(true,false,false)'
  end
  #============================================================================
  # ** Tileset
  #----------------------------------------------------------------------------
  #
  #============================================================================
  class Tileset
    #--------------------------------------------------------------------------
    # * Public Instance Variables
    #--------------------------------------------------------------------------
    attr_sec_accessor :tileset_name,  :panorama_name, :fog_name,
                      :battleback_name,                      'String.new'
    attr_sec_accessor :autotile_names,                       '[String.new]*7'
    attr_sec_accessor :panorama_hue, :fog_hue, :fog_blend_type,
                      :fog_sx, :fog_sy,                      0
    attr_sec_accessor :passages, :priorities, :terrain_tags, 'Table.new(384)'
    attr_sec_accessor :fog_zoom,                             200
    attr_sec_accessor :fog_opacity,                          64
  end
end

#==============================================================================
# ** 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'
  #--------------------------------------------------------------------------
  # * Class Variable
  #--------------------------------------------------------------------------
  @@rpgmakerxp = LiTTleDRAgo::XP
  @@fog_opacity = @@panorama_opacity = 0
  #--------------------------------------------------------------------------
  # * Alias Listing
  #--------------------------------------------------------------------------
  alias_sec_method :update_multi_layer_cr,         :update
  alias_sec_method :dispose_multi_layer_cr,        :dispose
  alias_sec_method :reload_tilemap_multi_layer_cr, :reload_tilemap
  alias_method     :fog_fix_initialize,            :initialize
  #--------------------------------------------------------------------------
  # * Aliased method: initialize
  #--------------------------------------------------------------------------
  def initialize(*args)
    fog_fix_initialize
    @fog.opacity = @@fog_opacity || 0 if @fog
    @panorama.opacity = @@panorama_opacity || 0 if @panorama
  end
  #--------------------------------------------------------------------------
  # * New Method : create_multi_layer
  #--------------------------------------------------------------------------
  def create_multi_layer
    dispose_multi_layer
    @xpmap_size  = $game_map.xpmap.size
    @vxamap_size = $game_map.vxamap.size
    $game_map.vxamap.compact.each do |data|
      next if @@rpgmakerxp
      tilemap_layer[(i  = tilemap_layer.size)] = Tilemap.new(@viewport1)
      create_layer_tilemap(tilemap_layer,data)
    end
    $game_map.xpmap.compact.each do |data|
      _data             = data.clone
      _data[:tileset]   = LiTTleDRAgo.cache.tileset(data[:tileset_name])
      _data[:autotiles] = []
      if (tilemap = ([@tilemap]+tilemap_layer).detect {|t| obj_is_ztilemap?(t)})
        data[:autotile_names].each_with_index do |name, i|
          _data[:autotiles] = LiTTleDRAgo.cache.autotile_cr_tilemap(name)
        end
        [tilemap.extra_map_data.push(_data), tilemap.refresh] && next
      end
      unless @@rpgmakerxp
        cr = "This script needs Drago - Custom Resolution ver 2.12 or above"
        ($imported[:drg_custom_resolution] || 0) >= 2.12 || raise(cr)
      end
      klass             = @@rpgmakerxp ? @tilemap.class : ZTilemap
      tilemap_layer[(i  = tilemap_layer.size)] = klass.new(@viewport1)
      create_layer_tilemap(tilemap_layer, _data)
    end   
    @viewport_screen_width = 0
  end
  #--------------------------------------------------------------------------
  # * New Method : create_layer_tilemap
  #--------------------------------------------------------------------------
  def create_layer_tilemap(tilemap,data)
    if (@@rpgmakerxp && tilemap.is_a?(Tilemap)) || obj_is_ztilemap?(tilemap)
      if obj_is_ztilemap?(tilemap)
        temp = tilemap.sprite_compact
        tilemap.sprite_compact = false
      end
      (0..6).each do |i|
        name = data[:autotile_names]
        bitmap = LiTTleDRAgo.cache.autotile(name)
        @force_tilemap_enabled = true if bitmap.height == 192
        tilemap.autotiles = obj_is_ztilemap?(tilemap) ?
        LiTTleDRAgo.cache.autotile_cr_tilemap(name) : bitmap
      end
      tilemap.tileset     = data[:tileset]
      tilemap.priorities  = data[:priorities]
      tilemap.map_data    = data[:map].data
      update_layer_tilemap(tilemap)
      tilemap.update
      tilemap.sprite_compact = temp  if obj_is_ztilemap?(tilemap)
    else
      tilemap.map_data = data[:map].data
      data[:tileset].tileset_names.each_with_index do |name, i|
        tilemap.bitmaps = LiTTleDRAgo.cache.tileset(name)
      end
      tilemap.flags = data[:tileset].flags
      update_layer_tilemap(tilemap)
      tilemap.update
    end
  end
  #--------------------------------------------------------------------------
  # * Aliased Method : update
  #--------------------------------------------------------------------------
  def update
    unless @@rpgmakerxp                  
      update_panorama
      update_fog
      update_panorama_plane
      update_fog_plane
    end         
    update_multi_layer_cr
    if @xpmap_size != $game_map.xpmap.size ||
      @vxamap_size != $game_map.vxamap.size
      create_multi_layer  
    end
    update_multi_layer
  end
  #--------------------------------------------------------------------------
  # * New Method : dispose_multi_layer
  #--------------------------------------------------------------------------
  def dispose_multi_layer
    tilemap_layer.dispose
    tilemap_layer.clear
  end
  #--------------------------------------------------------------------------
  # * New Method : update_multi_layer
  #--------------------------------------------------------------------------
  def update_multi_layer
    tilemap_layer.each { |t| update_layer_tilemap(t) }
  end
  #--------------------------------------------------------------------------
  # * New Method : update_layer_tilemap
  #--------------------------------------------------------------------------
  def update_layer_tilemap(tilemap)
    if obj_is_ztilemap?(tilemap)
      if @@rpgmakerxp
        tilemap.ox      = @tilemap.ox
        tilemap.oy      = @tilemap.oy
        tilemap.zoom_x  = $game_map.zoom_x
        tilemap.zoom_y  = $game_map.zoom_y
        tilemap.opacity = $game_map.tilemap_opacity
        tilemap.hue     = $game_map.tilemap_hue
        tilemap.tone    = $game_map.tilemap_tone
      else
        tilemap.ox = $game_map.display_x * tilemap_move_multiplier
        tilemap.oy = $game_map.display_y * tilemap_move_multiplier
      end
    else
      tilemap.ox = @tilemap.ox rescue $game_map.display_x * tilemap_move_multiplier
      tilemap.oy = @tilemap.oy rescue $game_map.display_y * tilemap_move_multiplier
    end
    tilemap.update
  end
  #--------------------------------------------------------------------------
  # * New Method : obj_is_ztilemap?
  #--------------------------------------------------------------------------
  def obj_is_ztilemap?(obj)
    defined?(ZTilemap) && obj.is_a?(ZTilemap)
  end
  #--------------------------------------------------------------------------
  # * Aliased Method : dispose
  #--------------------------------------------------------------------------
  def dispose
    dispose_multi_layer
    dispose_multi_layer_cr
    [dispose_fog, dispose_panorama] rescue nil unless @@rpgmakerxp
  end
  #--------------------------------------------------------------------------
  # * Aliased Method : reload_tilemap
  #--------------------------------------------------------------------------
  def reload_tilemap
    reload_tilemap_multi_layer_cr      
    create_multi_layer
  end
  #--------------------------------------------------------------------------
  # * New Method : tilemap_move_multiplier
  #--------------------------------------------------------------------------
  def tilemap_move_multiplier
    n = 1.00 / 4
    n = 1.00 / 8  if LiTTleDRAgo::VX
    n = 1.00 * 32 if LiTTleDRAgo::VXA
    return n
  end  
  #--------------------------------------------------------------------------
  # * New Method : update_panorama
  #--------------------------------------------------------------------------
  unless method_defined?(:update_panorama)
    def update_panorama
      if @panorama.nil?
        @panorama = Plane.new(@viewport1)
        @panorama.opacity = (@@panorama_opacity ||= 0)
        @panorama.z = -1000
      end
      if @panorama_name != $game_map.panorama_name or
          @panorama_hue != $game_map.panorama_hue
        @panorama_name = $game_map.panorama_name
        @panorama_hue = $game_map.panorama_hue
        if @panorama.bitmap.respond_to?(:dispose) &&
          @panorama.bitmap.not.disposed?
          @panorama.bitmap.dispose
          @panorama.bitmap = nil
        end
        if @panorama_name != ''
          @panorama.bitmap =
                LiTTleDRAgo.cache.panorama(@panorama_name, @panorama_hue)
        end
        Graphics.frame_reset
      end
    end
  end
  #--------------------------------------------------------------------------
  # * New Method : update_fog
  #--------------------------------------------------------------------------  
  unless method_defined?(:update_fog)
    def update_fog
      if @fog.nil?
        @fog = Plane.new(@viewport1)
        @fog.opacity = (@@fog_opacity ||= 0)
        @fog.z = 3000
      end
      if @fog_name != $game_map.fog_name or @fog_hue != $game_map.fog_hue
        @fog_name = $game_map.fog_name
        @fog_hue  = $game_map.fog_hue
        if @fog.bitmap.respond_to?(:dispose) && @fog.bitmap.not.disposed?
          @fog.bitmap.dispose
          @fog.bitmap = nil
        end
        if @fog_name != ''
          @fog.bitmap = LiTTleDRAgo.cache.fog(@fog_name, @fog_hue)
        end
        Graphics.frame_reset
      end
    end
  end
  #--------------------------------------------------------------------------
  # * New Method : update_panorama_plane
  #--------------------------------------------------------------------------
  unless method_defined?(:update_panorama_plane)
    def update_panorama_plane
      @panorama.ox = $game_map.display_x / 8
      @panorama.oy = $game_map.display_y / 8
    end
  end
  #--------------------------------------------------------------------------
  # * New Method : update_fog_plane
  #--------------------------------------------------------------------------
  unless method_defined?(:update_fog_plane)
    def update_fog_plane
      @fog.zoom_x = $game_map.fog_zoom / 100.0
      @fog.zoom_y = $game_map.fog_zoom / 100.0
      @fog.opacity = $game_map.fog_opacity
      @fog.blend_type = $game_map.fog_blend_type
      @fog.ox = $game_map.display_x*tilemap_move_multiplier + $game_map.fog_ox
      @fog.oy = $game_map.display_y*tilemap_move_multiplier + $game_map.fog_oy
      @fog.tone = $game_map.fog_tone
    end
  end
  #--------------------------------------------------------------------------
  # * New Method : dispose_fog
  #--------------------------------------------------------------------------
  unless method_defined?(:dispose_fog)
    def dispose_fog
      unless @fog.nil? || @fog.disposed?
        @@fog_opacity = @fog.opacity
        @fog.dispose
      end
    end
  end
  #--------------------------------------------------------------------------
  # * New Method : dispose_panorama
  #--------------------------------------------------------------------------
  unless method_defined?(:dispose_panorama)
    def dispose_panorama
      unless @panorama.nil? || @panorama.disposed?
        @@panorama_opacity = @panorama.opacity
        @panorama.dispose
      end
    end
  end
end
#==============================================================================
# ** RPG::Cache
#==============================================================================
ModCache = LiTTleDRAgo.cache
module ModCache
  #----------------------------------------------------------------------------
  # * Self
  #----------------------------------------------------------------------------
  class << self
    #--------------------------------------------------------------------------
    # * Get Autotile Graphic
    #--------------------------------------------------------------------------
    unless method_defined?(:autotile)
      def autotile(filename)
        load_bitmap("Graphics/Autotiles/", filename)
      end
    end
    #--------------------------------------------------------------------------
    # * Get Panorama Graphic
    #--------------------------------------------------------------------------
    unless method_defined?(:panorama)
      def panorama(filename, hue = 0)
        load_bitmap("Graphics/Panoramas/", filename, hue)
      end
    end
    #--------------------------------------------------------------------------
    # * Get Fog Graphic
    #--------------------------------------------------------------------------
    unless method_defined?(:fog)
      def fog(filename, hue = 0)
        load_bitmap("Graphics/Fogs/", filename, hue)
      end
    end
  end
end[/pre]



附带两个作为前置的脚本(未翻译):



[pre lang="ruby"]#==============================================================================
# ** Drago - Core Engine
# Version : 1.59
# Contact : littledrago.blogspot.com / forum.chaos-project.com
#==============================================================================
($imported ||= {})[:drg_core_engine] = 1.59
# =============================================================================
# NOTE:
# -----------------------------------------------------------------------------
# This is a devtool for me to make me easier for scripting
# If you want to use this, put above all custom script & below Scene_Debug
#
# =============================================================================
# DOCUMENTATION:
# -----------------------------------------------------------------------------
=begin
  Version History
  
  1.57 -
  ▼ Overhaul script (108 minor modification)
  ▼ Fixed glitch on BitmapDump method
  ▼ Added Bitmap#rotate90
  ▼ Added Bitmap#rotate180
  ▼ Added Bitmap#rotate270
  
  1.50 -
  ▼ Overhaul script (71 minor modification)
  ▼ Longer script call (RMXP script call bug fix)
  
  1.42 -
  ▼ Fixed Graphics.fullscreen?
  
  1.40 -
  ▼ Modified Game_Map#load_event
  
  1.39 -
  ▼ Fixed glitch at Bitmap#draw_icon
  ▼ Added Fiber class
  ▼ Added Game_Map#load_event
  ▼ Added Game_Map#call_event
  
  1.36 -
  ▼ Added Color class library
  
  1.34 -
  ▼ Added Module#define_third_method(sym = nil, _alias = nil,
                    prevent_stack = true, *a, &block)
  ▼ Added Bitmap#blur
  
  1.31 -
  ▼ Added Module#attr_sec_reader(symbol, default=0)
  ▼ Added Module#attr_sec_accessor(symbol, *a, &block)
  ▼ Added Module#alias_sec_method(sym = nil, *a, &block)
  ▼ Added Module#define_sec_method(sym = nil, *a, &block)
  
  1.29 -
  ▼ Added Array#have_all?(array)
  ▼ Added Array#have_any?(array)
  
  1.27 -
  ▼ Added Added Graphics.brightness
  ▼ Added Graphics.wait(frames = 10)
  ▼ Added Graphics.fadein(frames = 10)
  ▼ Added Graphics.fadeout(frames = 10)
  ▼ Added Bitmap#invert
  ▼ Added Bitmap#invert!
  ▼ Added Bitmap#brighten(amount = 10)
  ▼ Added Bitmap#brighten!(amount = 10)
  ▼ Added Bitmap#darken(amount = 10)
  ▼ Added Bitmap#darken!(amount = 10)
  ▼ Added Bitmap#grayscale
  ▼ Added Bitmap#grayscale!
  ▼ Added Bitmap#pixelate(size = 10)
  ▼ Added Bitmap#pixelate!(size = 10)
  ▼ Added Bitmap#frost(noise = 10)
  ▼ Added Bitmap#frost!(noise = 10)
  
  1.24 -
  ▼ Added Viewport#x
  ▼ Added Viewport#y
  ▼ Added Viewport#width
  ▼ Added Viewport#height
  ▼ Added Viewport#disposed?
  
  1.23 -
  ▼ Added Window_Base#draw_text (same as Bitmap#draw_text)
  ▼ Added Window_Base#draw_icon
  ▼ Added Window_Base#draw_battler
  ▼ Added Window_Base#draw_picture
  
  1.22 -
  ▼ Added Game_Map#load_map_data
  ▼ Added Game_Map#load_event
  ▼ Rename Array#product => Array#prod (because of conflict with RGSS3)
  
  1.21 -
  ▼ Fixed Glitch at Bitmap#crop
  
  1.20 -
  ▼ Fixed Script Hanging Error at Bitmap#export
  
  1.19 -
  ▼ Added some of RMXP method - Game_System#play_bgm
  ▼ Added some of RMXP method - Game_System#play_bgs
  ▼ Added some of RMXP method - Game_System#play_me
  ▼ Added some of RMXP method - Game_System#play_se
  
  1.18 -
  ▼ Fixing Backtrace at Array#method_missing
  
  1.17 -
  ▼ Added Bitmap#flip_vertical
  ▼ Added Bitmap#flip_vertical!
  ▼ Added Bitmap#flip_horizontal
  ▼ Added Bitmap#flip_horizontal!
  
  1.16 -
  ▼ Added Bitmap#export (dump bitmap into .png files)
  
  1.15 -
  ▼ Added Game_Characters#character_above?
  ▼ Added Game_Characters#character_below?
  ▼ Added Game_Characters#character_right?
  ▼ Added Game_Characters#character_left?
  
  1.11 -
  ▼ Fixing Bug at changing screen size
  
  1.10 -
  ▼ Added Graphics.scale_screen(width, height)
  
  1.00 -
  ▼ Original Release

# -----------------------------------------------------------------------------
# Below is the available command in this script
# -----------------------------------------------------------------------------
# * Graphics
# -----------------------------------------------------------------------------
# -----------------------------------------------------------------------------
  This command is not recommended to used in RMXP
  
  Graphics.scale_screen(width,height)
  - Resize the screen and stretched it (if not RMXP) into new resolution
  
  Graphics.fill_monitor
  - Maximize the screen and stretched it (if not RMXP) to fill the monitor
  
  Graphics.control_screen_size(enable = true)
  - Enable or disable screen size control by mouse.
    Resized screen will be stretched (if not RMXP)
# -----------------------------------------------------------------------------

  Graphics.width        - Returns screen width
  Graphics.height       - Returns screen height
  Graphics.fullscreen?  - Returns true if Game in fullscreen mode, else false
  Graphics.fullscreen   - Switch to fullscreen mode
  Graphics.window       - Switch to windowed mode
  Graphics.toggle       - Switch between fullscreen mode and windowed mode
  Graphics.wait(frame)    - Wait for frame
  Graphics.wait_for_input - Wait until input is pressed
  Graphics.fadein(frame)  - Fade in the screen
  Graphics.fadeout(frame) - Fade out the screen
  Graphics.snap_to_bitmap - Snap screen to a bitmap object
  
  Graphics.high_priority = true/false - Change process priority to high / normal
  Graphics.disable_alt_enter  - Disable input ALT+Enter (until game is closed)
  
# -----------------------------------------------------------------------------
# * Module
# -----------------------------------------------------------------------------
  Module#attr_sec_reader(symbol, default=0)
  - Create attr_reader with default value
     Example : attr_sec_reader :something, "Sprite.new"
     Equal : def something
               @something ||= Sprite.new
             end
            
  Module#attr_sec_accessor(symbol, *a, &block)
  - Create (sheer of) attr_accessor with default value
     Example : attr_sec_accessor :sprite1, :sprite2, :sprite3, "Sprite.new"
     Equal : attr_writer :sprite1, :sprite2, :sprite3
             attr_sec_reader :sprite1, "Sprite.new"
             attr_sec_reader :sprite2, "Sprite.new"
             attr_sec_reader :sprite3, "Sprite.new"
  
  Module#alias_sec_method(sym = nil, *a, &block)
  - Create alias only if alias name is not defined and target method is exist
     Example : alias_sec_method :alias_method, :target_method
     Equal : if method_defined?(:target) && !method_defined?(:alias)
               alias_method :alias, :target
             end
            
  Module#define_sec_method(sym = nil, *a, &block)
  - Define method only if the method is not defined
     Example : define_sec_method(:some_method) { |*a| block }
     Equal : unless method_defined?(:some_method)
               def some_method(*a)
                 block
               end
             end
  
# -----------------------------------------------------------------------------
# * Array
# -----------------------------------------------------------------------------
  Array Method Distributor
  - Distribute unexisted method in array into each variable
  (will work only if the method isn't exist in Array)
    Example : [Graphics,Input].update
                # equal => Graphics.update ; Input.update  
              [@string1,@string2,@integer1,@sprite].dispose
                # equal => @sprite.dispose
                # (all variable without dispose method is ignored)
              [@string1,@string2,@integer1].dispose
                # Throws NoMethodError if all method didn't have dispose method
  
  Array#random_each / Array#random_each_with_index
    Example : a = [1,2,3,4,5,6,7]
              a.random_each {|i| puts i} # 4,5,3,2,7,1,6
              
  Array#sum
  Array#prod
  Array#average
    Example : [1,2,3,4].sum         # 10  (1+2+3+4)
              [1,2,3,4].average     # 2.5 (10 / 4)
              [1,2,3,4].prod        # 24  (1*2*3*4)
              
  Array#shuffle / Array#shuffle!  
    Example : [1,2,3,4].shuffle     # [3,2,4,1]  
   
  Array#random / Array#random!
    Example : [1,2,3,4].random      # 3  
  
  Array#switch=(true/false)
  Array#switch_reverse
  - Turn on / off switches all variable in the array
    (will ignored if variable not integer or not an array)
    Example : [1,2,[3,2,'A'],5].switch = true
                # equal => $game_switches[1] = true
                           $game_switches[2] = true
                           $game_self_switches[[3,2,'A']] = true
                           $game_switches[5] = true
                           
  Array#variable(value = nil, method = "=")   
  - Change all variable value in the array (ignored if variable not integer)
    Example : [1,2,5].variable(10)
                # equal => $game_variables[1] = 10
                           $game_variables[2] = 10
                           $game_variables[5] = 10
    Example : [1,2,5].variable(10, "+=")
                # equal => $game_variables[1] += 10
                           $game_variables[2] += 10
                           $game_variables[5] += 10
                           
  Array#have_all?(array)
  - returns true if contains all elements of the array               
  Array#have_any?(array)
  - returns true if contains any elements of the array   
# -----------------------------------------------------------------------------
# * Sprite
# -----------------------------------------------------------------------------
  Sprite#clone
  Sprite#dup
  - Clone sprite without "can't clone sprite error"
    Example : a = Sprite.new
              b = a.clone
              a.dispose
              print a.disposed? # true
              print b.disposed? # false
              
# -----------------------------------------------------------------------------
# * Spriteset_Map
# -----------------------------------------------------------------------------
  Spriteset_Map#sprite_player
  - returns sprite player at @character_sprites in Spriteset_Map
  
  Spriteset_Map#find_character(character)
  - returns character sprite at @character_sprites in Spriteset_Map
  
# -----------------------------------------------------------------------------
# * Game Battler
# -----------------------------------------------------------------------------
  Game_Battler#hp_percent(integer = false, float_points = 2)
  Game_Battler#sp_percent(integer = false, float_points = 2)
  Example : $game_actors[1].hp_percent
                   # returns 0 - 100 based on percentage hp
                  
# -----------------------------------------------------------------------------
# * Bitmap
# -----------------------------------------------------------------------------
  Bitmap#export(filename)
  - exporting bitmap into a file (only support bmp and png)
  Example : bitmap = Bitmap.new(50,20)
            bitmap.export('empty.png')
            
  Bitmap#flip_vertical
  Bitmap#flip_vertical!
  Bitmap#flip_horizontal
  Bitmap#flip_horizontal!
  - flip the bitmap vertically or horizontally (using ! will modify self)
  Example : bitmap = Bitmap.new(50,20)
            bitmap.flip_vertical!
            
  Bitmap#rotate90
  Bitmap#rotate90!
  Bitmap#rotate180
  Bitmap#rotate180!
  Bitmap#rotate270         
  Bitmap#rotate270!            
      
  Additional Bitmap Effects
  Note : calling this method is process consuming, use with caution
    Bitmap#invert
    Bitmap#invert!
    Bitmap#brighten(amount = 10)
    Bitmap#brighten!(amount = 10)
    Bitmap#darken(amount = 10)
    Bitmap#darken!(amount = 10)
    Bitmap#grayscale
    Bitmap#grayscale!
    Bitmap#pixelate(size = 10)
    Bitmap#pixelate!(size = 10)
    Bitmap#frost(noise = 10)
    Bitmap#frost!(noise = 10)
# -----------------------------------------------------------------------------
# * Color
# -----------------------------------------------------------------------------
  Color RGB value shortcut
  List :
    Color.red
    Color.green
    Color.blue
    Color.white
    Color.black
    Color.yellow
    Color.magenta
    Color.cyan
    Color.purple
    Color.gray
    Color.lightgray
    Color.darkgray
    Color.pink
    Color.orange
    Color.brown
    Color.golden
   
    Color.invert
   
  Color Hex
  - You can use hex value as method in color class (not case sensitive)
    (need to include 'x' in front)
  Example : Color.xffffff, Color.x04dacf, etc
  
  
# -----------------------------------------------------------------------------
# * Game_Map
# -----------------------------------------------------------------------------
  
  Game_Map#load_event(mapid, eventid, x, y, page_id)
  Game_Map#load_event(mapid, eventid, x, y)
  Game_Map#load_event(eventid, x, y)   # map_id will be assumed as current map
  - Duplicate an event from another map to current map at position (x, y)
  
  Game_Map#call_event(mapid, eventid, page_id)
  Game_Map#call_event(mapid, eventid)  # page_id will be assumed as -1
  Game_Map#call_event(eventid)         # map_id will be assumed as current map
  - Call an event from another map to current map
      Note that page_id is start from 1, not 0
      If you're using RMVX or RMVXA, setting page_id to -1 will bring you to
      the page with met condition.
      
      
# -----------------------------------------------------------------------------
# * RTP fix
# -----------------------------------------------------------------------------
  
  Longer script call
  - You can stack script call next to each other as many as possible and they
    will be connected.
  - In addition, this also fixes the Interpreter Script call bug when if you
    use $game_system..... = false, game would freeze. This will prevent that.

# -----------------------------------------------------------------------------
# * End Documentation
# -----------------------------------------------------------------------------
=end
# =============================================================================

#==============================================================================
# ** Module     
#------------------------------------------------------------------------------
#  
#==============================================================================

class Module
  #-------------------------------------------------------------------------
  # * New method: attr_sec_reader (Attr Secondary Reader)
  #-------------------------------------------------------------------------
  unless method_defined?(:attr_sec_reader)
    def attr_sec_reader(*sym)
      if (1..2) === sym.size
        module_eval("define_method(:#{sym[0]}) { @#{sym[0]} ||= #{sym[1]||0}}")
      elsif sym.size > 2
        (default = sym.pop) && sym.each {|s| attr_sec_reader(s,default)}
      end
    end
  end
  #-------------------------------------------------------------------------
  # * New method: attr_sec_accessor (Attr Secondary Accessor)
  #-------------------------------------------------------------------------
  def attr_sec_accessor(sym = nil, *args)
    (args.size > 0) | sym.nil? || args.push(0)
    (default = args.pop) && (b = [sym].concat(args).compact)
    (b).each {|a| (attr_writer(a) || 0) && attr_sec_reader(a,default)}
  end
  #-------------------------------------------------------------------------
  # * New method: alias_sec_method (Alias Secondary Method)
  #   Note : This method will create alias only if alias name is not defined
  #          and target alias is exist
  #-------------------------------------------------------------------------
  unless method_defined?(:alias_sec_method)
    private
    def alias_sec_method(sym = nil, *args)
      (args.size > 0) | sym.nil? || args.clear
      (t = args.pop) && (b = [sym].concat(args).compact).each do |a|
        c = (t == :initialize ? true : method_defined?(t))
        method_defined?(a) || (c && alias_method(a, t))
      end
    end
  end
  #-------------------------------------------------------------------------
  # * New method: redirect_method
  #-------------------------------------------------------------------------
  unless method_defined?(:redirect_method)
    private
    def redirect_method(sym = nil, *args, &block)
      (args.size > 0) | sym.nil? || args.clear
      (t = args.pop) && (b = [sym].concat(args).compact).each do |a|
        meth = "def #{a}[*args] #{t}(*args) end"
        meth.gsub!(/(['")}\](\d+)])\(\*args\)/i)  {    $1     }#'
        meth.gsub!(/\[\*args\]/i)                 { '(*args)' }
        method_defined?(a) || module_eval(meth)
      end
    end
  end
  #-------------------------------------------------------------------------
  # * New method: define_sec_method
  #   Note : This method will not defining method if method name already
  #          exist
  #-------------------------------------------------------------------------
  unless method_defined?(:define_sec_method)
    private
    def define_sec_method(sym = nil, *args, &block)
      sym && (method_defined?(s = sym.to_sym) || define_method(s,*args,&block))
    end
  end
  #-------------------------------------------------------------------------
  # * New method: define_third_method
  #   Note : After aliasing, define a method
  #-------------------------------------------------------------------------
  unless method_defined?(:define_third_method)
    private
    def define_third_method(sym = nil, _alias = nil, *args, &block)
      unless sym.nil? || _alias.nil?
        stack = _alias.to_s =~ /stack/i || sym.to_s == 'initialize'
        stack = (!stack && method_defined?(_alias.to_sym))
        stack || alias_method(_alias.to_sym, sym.to_sym)
        define_method(sym.to_sym,*args,&block)
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: define_pre_alias
  #--------------------------------------------------------------------------
  unless method_defined?(:define_pre_method)
    private
    def define_pre_alias(sym = nil, *args, &block)
      _time = Time.now
      _alias = :"#{sym}_#{_time.to_i}_#{_time.usec}"
      define_third_method(:"#{sym}",_alias) do  |*args|
        block.bind(self).call
        send(_alias,*args)
      end
    end
    private
    def define_post_alias(sym = nil, *args, &block)
      _time = Time.now
      _alias = :"#{sym}_#{_time.to_i}_#{_time.usec}"
      define_third_method(:"#{sym}",_alias) do  |*args|
        send(_alias,*args)
        block.bind(self).call
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: include_auto_update
  #--------------------------------------------------------------------------
  unless method_defined?(:include_auto_update)
    private
    def include_auto_update
      return if method_defined?(:update_auto_update)
      attr_sec_accessor(:auto_update, "[]")
      define_method(:update_auto_update) do
        return if auto_update.empty?
        auto_update.each do |x|
          (x[1].nil? ? send(x[0]) : (x[2].nil? ? x[0].method(x[1]).call :
          (x[0].method(x[1]).call(*x[2]))))
          (x[3].is_a?(Numeric) && (x[3] -= 1))
        end   
        auto_update.reject! {|x| x[3].is_a?(Numeric) && x[3] <= 0 }
      end
      _time = Time.now
      _alias = :"update_#{_time.to_i}_#{_time.usec}"
      define_third_method(:update,_alias) do  |*args|
        send(_alias,*args)
        update_auto_update
      end
    end
  end  
end
#==============================================================================
# ** LiTTleDRAgo     
#------------------------------------------------------------------------------
#  
#==============================================================================

module LiTTleDRAgo
  #-------------------------------------------------------------------------
  # * Constant
  #-------------------------------------------------------------------------
  VX            = defined?(Window_ActorCommand)
  VXA           = defined?(Window_BattleActor)
  XP            = !VX
  RGSS1         = defined?(Hangup)
  RGSS2         = RUBY_VERSION == '1.8.1' && !RGSS1
  RGSS3         = RUBY_VERSION == '1.9.2'  
  APPPATHDRAGO  = "#{ENV['APPDATA']}/Drago/"
end
#==============================================================================
# ** CoreDLL
#------------------------------------------------------------------------------
#  
#==============================================================================
module CoreDLL
  #-------------------------------------------------------------------------
  # * Constant
  #-------------------------------------------------------------------------
  DLL_USED = ['kernel32','msvcrt','user32','gdi32']
  SCENEVXA = "SceneManager.send(:instance_variable_set,:@scene,args.at(0))"
  L        = LiTTleDRAgo
  #-------------------------------------------------------------------------
  # * Public Instance Variables
  #-------------------------------------------------------------------------
  attr_sec_reader :rtlmemory_pi,  "winapi(0,'RtlMoveMemory','pii','i')"
  attr_sec_reader :rtlmemory_ip,  "winapi(0,'RtlMoveMemory','ipi','i')"
  attr_sec_reader :setpriority,   "winapi(0,'SetPriorityClass','pi','i')"
  attr_sec_reader :getprocesstime,"winapi(0,'GetProcessTimes','ipppp','i')"
  attr_sec_reader :getdc,         "winapi(2,'GetDC','i','i')"
  attr_sec_reader :releasedc,     "winapi(2,'ReleaseDC','ii','i')"
  attr_sec_reader :reghotkey,     "winapi(2,'RegisterHotKey', 'liii', 'i')"
  attr_sec_reader :sendinput,     "winapi(2,'SendInput','ipi','i')"
  attr_sec_reader :setwindowlong, "winapi(2,'SetWindowLong','lll','l')"
  attr_sec_reader :getkeysta,     "winapi(2,'GetKeyboardState','p','i')"
  attr_sec_reader :getkeylay,     "winapi(2,'GetKeyboardLayout','l','l')"
  attr_sec_reader :mapvirkey,     "winapi(2,'MapVirtualKeyEx','iil','i')"
  attr_sec_reader :tounicode,     "winapi(2,'ToUnicodeEx','llppill','l')"
  attr_sec_reader :screentoclient,"winapi(2,'ScreenToClient', 'lp', 'i')"
  attr_sec_reader :cursorposition,"winapi(2,'GetCursorPos', 'p', 'i')"
  attr_sec_reader :systemmetrix,  "winapi(2,'GetSystemMetrics', %w(i), 'i')"
  attr_sec_reader :bitblt,        "winapi(3,'BitBlt','iiiiiiiii','i')"
  attr_sec_reader :ccdc,          "winapi(3,'CreateCompatibleDC','i','i')"
  attr_sec_reader :ccbitmap,      "winapi(3,'CreateCompatibleBitmap','iii','i')"
  attr_sec_reader :deleteobject,  "winapi(3,'DeleteObject','i','i')"
  attr_sec_reader :getbitmapbits, "winapi(3,'GetBitmapBits','llp','l')"
  attr_sec_reader :getdibits,     "winapi(3,'GetDIBits','iiiiipi','i')"
  attr_sec_reader :setdibits,     "winapi(3,'SetDIBits','iiiiipi','i')"
  attr_sec_reader :selectobject,  "winapi(3,'SelectObject','ii','i')"
  attr_sec_reader :getpixel,      "winapi(3,'GetPixel','iii','i')"
  attr_sec_reader :setpixel,      "winapi(3,'SetPixel','liil','l')"  
  attr_sec_reader :disabled_key,  "Array.new"
  attr_sec_reader :high_priority, 'false'
  #-------------------------------------------------------------------------
  # * Define Secondary Listing
  #-------------------------------------------------------------------------
  define_sec_method(:disable_alt_enter) { disable_keys(0x0D) }
  define_sec_method(:fullscreen?) { systemmetrix.call(0) == Graphics.width }
  define_sec_method(:fullscreen)  { self.fullscreen? || toggle }
  define_sec_method(:window)      { self.fullscreen? && toggle }
  #-------------------------------------------------------------------------
  # * Redirect Listing
  #-------------------------------------------------------------------------
  redirect_method :cache,      L::VX  ? '(Cache)' : '(RPG::Cache)'
  redirect_method :scene,      L::VXA ? '(SceneManager.scene)':'($scene)'
  redirect_method :scene=,     L::VXA ? SCENEVXA : '($scene = args[0])'
  #-------------------------------------------------------------------------
  # * Enable change window size via mouse (border required)
  #   Screen will not resized if RMXP
  #-------------------------------------------------------------------------
  def control_screen_size(enable = true)
    hid = @hide_border ? 0x14000000 : 0x14CA0000
    set = enable ? (0x10C70000|0x00080000) : hid
    self.setwindowlong.call(self.hwnd,-16, set)
  end
  #-------------------------------------------------------------------------
  # * Hide window border
  #   Screen size can't be controlled via mouse
  #-------------------------------------------------------------------------
  def hide_borders
     control_screen_size((@hide_border = true) && false)
  end
  #-------------------------------------------------------------------------
  # * Show window border
  #   Screen size can't be controlled via mouse
  #-------------------------------------------------------------------------
  def show_borders
    control_screen_size((@hide_border = false))
  end
  #-------------------------------------------------------------------------
  # * Disable Key
  #-------------------------------------------------------------------------
  def disable_keys(*keys)
    keys.each do |key|
      disabled_key.include?(key) || disabled_key.push(key)
      self.reghotkey.call(self.hwnd, 1, 0x0001, key)
    end
  end
  #-------------------------------------------------------------------------
  # * Resize the screen (scaled)
  #   Screen will not resized if RMXP
  #-------------------------------------------------------------------------
  def scale_screen(width, height)
    width  += ((res = self.systemmetrix).call(5) + (res.call(45))) * 2
    height += (res.call(6) + (res.call(46))) * 2 + res.call(4)
    x = [(res.call(0) - width) / 2, 0].max
    y = [(res.call(1) - height) / 2, 0].max
    self.setwindowpos(self.hwnd,0,x,y,width,height,0)
  end
  #-------------------------------------------------------------------------
  # * Scale the game.exe to fill the monitor
  #   Screen will not resized if RMXP
  #-------------------------------------------------------------------------
  def fill_monitor
    setwindowpos(hwnd,0,0,0,(res = systemmetrix).call(0),res.call(1),0)
  end
  #-------------------------------------------------------------------------
  # * setwindowpos
  #-------------------------------------------------------------------------
  def setwindowpos(hwnd = self.hwnd,at = 0,x = 0,y = 0,
      width = 640, height = 480, ni = 0)
    @setwindowpos ||= winapi(2, 'SetWindowPos', 'liiiiip','i')
    @setwindowpos.call(hwnd, at, x, y, width, height, ni)
  end
  #-------------------------------------------------------------------------
  # * Toggle between fullscreen and windowed
  #-------------------------------------------------------------------------
  def toggle
    @keybd ||= winapi(2, 'keybd_event', %w(i i l l), 'v')
    [@keybd.call(0xA4, 0, 0, 0), @keybd.call(13, 0, 0, 0)  ]
    [@keybd.call(13, 0, 2, 0),   @keybd.call(0xA4, 0, 2, 0)]
  end
  #-------------------------------------------------------------------------
  # * Show FPS
  #-------------------------------------------------------------------------
  def show_fps
    @show_fps ||= winapi(2, 'keybd_event', %w(l l l l), '')
    @show_fps.call(0x71,0,0,0)
    sleep(0.1)
    @show_fps.call(0x71,0,2,0)
  end
  #-------------------------------------------------------------------------
  # * Get the Game Window's width and height
  #-------------------------------------------------------------------------
  def client_size   
    @window_c_rect ||= winapi(2, 'GetClientRect', %w(l p), 'i')
    @window_c_rect.call(self.hwnd, (rect = [0, 0, 0, 0].pack('l4')))
    right, bottom = rect.unpack('l4')[2..3]
    return right, bottom
  end  
  #-------------------------------------------------------------------------
  # * Get the game window handle (specific to game)
  #-------------------------------------------------------------------------
  def hwnd
    @game_window ||= winapi(2, 'FindWindowEx', %w(l l p p), 'i').
                            call(0,0,"RGSS Player",0)
  end  
  #-------------------------------------------------------------------------
  # * always_on_top  (cannot be undone)
  #-------------------------------------------------------------------------
  def always_on_top
    res = self.systemmetrix
    width  = Graphics.width  + (res.call(5) + (res.call(45))) * 2
    height = Graphics.height + (res.call(6) + (res.call(46))) * 2 + res.call(4)
    x = [(res.call(0) - width) / 2, 0].max
    y = [(res.call(1) - height) / 2, 0].max
    self.setwindowpos(self.hwnd,-1,x,y,width,height,0x0200)
  end
  #-------------------------------------------------------------------------
  # * Get the value of game.ini
  #-------------------------------------------------------------------------
  def read_ini(field, key, ini = 'Game.ini')
    @gpps ||= winapi(0, 'GetPrivateProfileString', 'pppplp', 'l')
    @gpps.call(field,key,"",result="\0"*256,256,".//#{ini}") rescue return ""
    return result.delete!("\0")
  end
  #-------------------------------------------------------------------------
  # * Data default extension
  #-------------------------------------------------------------------------
  def data_default_extension
    data = read_ini('Game','Scripts')
    data = data.split('.').last || 'rxdata'
    return data
  end
  #-------------------------------------------------------------------------
  # * High Priority (true/false)
  #-------------------------------------------------------------------------
  def high_priority=(value)
    @high_priority = value && true
    setpriority.call(-1, @high_priority ? 0x00000080 : 0x00000020)
  end
  #--------------------------------------------------------------------------
  # * snap_to_bitmap
  #--------------------------------------------------------------------------
  def snap_to_bitmap
    bitmap = Bitmap.new((w = client_size.at(0)),(h = client_size.at(1)))
    info   = [40,w,h,1,32,0,0,0,0,0,0].pack('LllSSLLllLL')
    hDC    = ccdc.call((dc = getdc.call(hwnd)))
    deleteobject.call(selectobject.call(hDC, (hBM = ccbitmap.call(dc, w, h))))
    setdibits.call(hDC, hBM, 0, h, (a = bitmap.address), info, 0)
    bitblt.call(hDC, 0, 0, w, h, dc, 0, 0, 0xCC0020)
    getdibits.call(hDC, hBM, 0, h, a, info, 0)
    deleteobject.call(hBM)
    deleteobject.call(hDC)
    return bitmap
  end                           
  #-------------------------------------------------------------------------
  # * Execute Win32API
  #-------------------------------------------------------------------------
  def winapi(*a)
    Win32API.new(*((a[0].is_a?(Integer) ? a[0] = DLL_USED[a[0]] : a) && a))
  end
  #----------------------------------------------------------------------------
  # * unicode_to_utf8
  #  string - string in Unicode format
  #  Converts a string from Unicode format to UTF-8 format as RGSS does not
  #  support Unicode.
  #----------------------------------------------------------------------------
  def unicode_to_utf8(string)
    result = ''
    string.unpack('L*').each do |c|
      if (c1 = c < 0x0080) || (c2 = c < 0x0800) || (c3 = c < 0x10000) ||
        (c4 = c < 0x200000)|| (c5 = c < 0x4000000) || (c6 = c < 0x80000000)
        result += c.chr                           if c1
        result += (0xC0 | (c >> 6)).chr           if c2
        result += (0xE0 | (c >> 12)).chr          if c3
        result += (0xF0 | (c >> 18)).chr          if c4
        result += (0xF8 | (c >> 24)).chr          if c5
        result += (0xFC | (c >> 30)).chr          if c6
        result += (0x80 | ((c >> 24) & 0x3F)).chr if c6
        result += (0x80 | ((c >> 18) & 0x3F)).chr if c5 || c6
        result += (0x80 | ((c >> 12) & 0x3F)).chr if c4 || c5 || c6
        result += (0x80 | ((c >> 6) & 0x3F)).chr  if c3 || c4 || c5 || c6
        result += (0x80 | (c & 0x3F)).chr         if c2 || c3 || c4 || c5 || c6
      end
    end
    return result
  end
end                        
LiTTleDRAgo.extend(CoreDLL)

#==============================================================================
# ** RPG
#------------------------------------------------------------------------------
#  
#==============================================================================
module RPG
  #============================================================================
  # ** System
  #----------------------------------------------------------------------------
  #
  #============================================================================
  class System
    #----------------------------------------------------------------------
    # ● Class Variables
    #----------------------------------------------------------------------
    if (VX = LiTTleDRAgo::VX)
      #------------------------------------------------------------------------
      # ● Public Instance Variables
      #------------------------------------------------------------------------
      attr_accessor :magic_number,      :windowskin_name, :gameover_name
      attr_accessor :battle_transition, :battleback_name, :title_name
      #------------------------------------------------------------------------
      # ● Redefined Methods
      #------------------------------------------------------------------------
      redirect_method :sounds,            "$data_system.sounds"
      redirect_method :cursor_se,         "sounds[0]"
      redirect_method :decision_se,       "sounds[1]"
      redirect_method :cancel_se,         "sounds[2]"
      redirect_method :buzzer_se,         "sounds[3]"
      redirect_method :equip_se,          "sounds[4]"
      redirect_method :save_se,           "sounds[5]"
      redirect_method :load_se,           "sounds[6]"
      redirect_method :battle_start_se,   "sounds[7]"
      redirect_method :escape_se,         "sounds[8]"
      if (VXA = LiTTleDRAgo::VXA)
        redirect_method :shop_se,           "sounds[21]"
        redirect_method :actor_collapse_se, "sounds[15]"
      else
        redirect_method :shop_se,           "sounds[17]"
        redirect_method :actor_collapse_se, "sounds[13]"
      end
      redirect_method :enemy_collapse_se, "sounds[11]"
      redirect_method :words,             "@words ||= RPG::System::Words.new()"
      #------------------------------------------------------------------------
      # ● Aliased Methods
      #------------------------------------------------------------------------
      alias_sec_method :battleback_name, :battleback1_name
      alias_sec_method :title_name,      :title1_name      
    end
    #========================================================================
    # ** Words
    #------------------------------------------------------------------------
    #
    #========================================================================
    class Words      
      #----------------------------------------------------------------------
      # ● New Methods
      #----------------------------------------------------------------------
      attr_sec_accessor :params,    !(VXA = LiTTleDRAgo::VXA) ? !VX ?
                                    '[hp,sp,str,dex,agi,int]' :         # XP
                                    '[hp,sp,atk,pdef,int,agi]' :        # VX
                                    '[hp,sp,atk,pdef,int,mdef,agi,luk]' # VXA
      attr_sec_accessor :weapon1,   VX && !VXA ? 'Vocab.weapon1' : "'Weapon 1'"
      attr_sec_accessor :weapon2,   VX && !VXA ? 'Vocab.weapon2' : "'Weapon 2'"
      attr_sec_accessor :status,    VX ? 'Vocab.status'          : "'Status'  "
      attr_sec_accessor :save,      VX ? 'Vocab.save'            : "'Save'    "
      attr_sec_accessor :game_end,  VX ? 'Vocab.game_end'        : "'Game End'"
      attr_sec_accessor :fight,     VX ? 'Vocab.fight'           : "'Fight'   "
      attr_sec_accessor :escape,    VX ? 'Vocab.escape'          : "'Escape'  "
      attr_sec_accessor :new_game,  VX ? 'Vocab.new_game'        : "'New Game'"
      attr_sec_accessor :continue,  VX ? 'Vocab.continue'        : "'Continue'"
      attr_sec_accessor :shutdown,  VX ? 'Vocab.shutdown'        : "'Shutdown'"
      attr_sec_accessor :to_title,  VX ? 'Vocab.to_title'        : "'To Title'"
      attr_sec_accessor :cancel,    VX ? 'Vocab.cancel'          : "'Cancel'  "
      #----------------------------------------------------------------------
      # ● Redirect Listings
      #----------------------------------------------------------------------
      redirect_method :gold,   (VXA ? 'Vocab.currency_unit' : 'Vocab.gold')
      redirect_method :hp,     'Vocab.hp'
      redirect_method :sp,     'Vocab.mp'
      redirect_method :str,    'String.new()'
      redirect_method :dex,    'String.new()'
      redirect_method :luk,    (VXA ? 'Vocab.param(7)' : 'String.new()')
      redirect_method :agi,    (VXA ? 'Vocab.param(6)' : 'Vocab.agi')
      redirect_method :int,    (VXA ? 'Vocab.param(4)' : 'Vocab.spi')
      redirect_method :atk,    (VXA ? 'Vocab.param(2)' : 'Vocab.atk')
      redirect_method :pdef,   (VXA ? 'Vocab.param(3)' : 'Vocab.def')
      redirect_method :mdef,   (VXA ? 'Vocab.param(5)' : 'String.new()')
      redirect_method :weapon, (VXA ? 'Vocab.etype(0)' : 'Vocab.weapon')
      redirect_method :armor1, (VXA ? 'Vocab.etype(1)' : 'Vocab.armor1')
      redirect_method :armor2, (VXA ? 'Vocab.etype(2)' : 'Vocab.armor2')
      redirect_method :armor3, (VXA ? 'Vocab.etype(3)' : 'Vocab.armor3')
      redirect_method :armor4, (VXA ? 'Vocab.etype(4)' : 'Vocab.armor4')
      redirect_method :attack, 'Vocab.attack'
      redirect_method :skill,  'Vocab.skill'
      redirect_method :guard,  'Vocab.guard'
      redirect_method :item,   'Vocab.item'
      redirect_method :equip,  'Vocab.equip'
    end
  end
end
#==============================================================================
# ** RPG_FileTest
#------------------------------------------------------------------------------
#
#==============================================================================
module RPG_FileTest
  #--------------------------------------------------------------------------
  # ● New method: self.exist?
  #--------------------------------------------------------------------------
  def self.exist?(filename)
    dir,ext = File.dirname(filename) + '/', File.extname(filename)
    base = File.basename(filename, ext)
    if ['.png','.jpg','.bmp'].include?(ext.downcase)
      cache = defined?(Cache) ? Cache : RPG::Cache
      (cache.load_bitmap(dir,base) && true) rescue false
    elsif ['.rxdata','.rvdata','.rvdata2','.rb','.txt'].include?(ext.downcase)
      (load_data(filename) && true) rescue false
    else
      File.exist?(filename)
    end
  end
end

#==============================================================================
# ** Sound
#------------------------------------------------------------------------------
#  This module plays sound effects. It obtains sound effects specified in the
# database from the global variable $data_system, and plays them.
#==============================================================================
module Sound;  end
class << Sound
  #------------------------------------------------------------------------
  # ● New Method :se_play
  #------------------------------------------------------------------------
  unless method_defined?(:se_play)
    def se_play(type)
      system = ($game_system ||= Game_System.new)
      case type
      when :cursor         then system.se_play($data_system.cursor_se)
      when :decision       then system.se_play($data_system.decision_se)
      when :cancel         then system.se_play($data_system.cancel_se)
      when :buzzer         then system.se_play($data_system.buzzer_se)
      when :shop           then system.se_play($data_system.shop_se)
      when :equip          then system.se_play($data_system.equip_se)
      when :save           then system.se_play($data_system.save_se)
      when :load           then system.se_play($data_system.load_se)
      when :battle_start   then system.se_play($data_system.battle_start_se)
      when :escape         then system.se_play($data_system.escape_se)
      when :actor_collapse then system.se_play($data_system.actor_collapse_se)
      when :enemy_collapse then system.se_play($data_system.enemy_collapse_se)
      end
    end
  end
  #--------------------------------------------------------------------------
  # * Redefined Method
  #--------------------------------------------------------------------------
  define_sec_method(:play_cursor)         { se_play(:cursor)         }
  define_sec_method(:play_decision)       { se_play(:decision)       }
  define_sec_method(:play_cancel)         { se_play(:cancel)         }
  define_sec_method(:play_buzzer)         { se_play(:buzzer)         }
  define_sec_method(:play_equip)          { se_play(:equip)          }
  define_sec_method(:play_save)           { se_play(:save)           }
  define_sec_method(:play_load)           { se_play(:load)           }
  define_sec_method(:play_battle_start)   { se_play(:battle_start)   }
  define_sec_method(:play_escape)         { se_play(:escape)         }
  define_sec_method(:play_enemy_collapse) { se_play(:enemy_collapse) }
  define_sec_method(:play_actor_collapse) { se_play(:actor_collapse) }
  define_sec_method(:play_shop)           { se_play(:shop)           }
  #--------------------------------------------------------------------------
  # * Alias Listing
  #--------------------------------------------------------------------------
  alias_sec_method :play_ok, :play_decision
end

#==============================================================================
# ** Game_System
#------------------------------------------------------------------------------
#  This class handles data surrounding the system. Backround music, etc.
#  is managed here as well. Refer to "$game_system" for the instance of
#  this class.
#==============================================================================
class Game_System
  #--------------------------------------------------------------------------
  # * Constant
  #--------------------------------------------------------------------------
  VX = LiTTleDRAgo::VX && !LiTTleDRAgo::VXA
  #--------------------------------------------------------------------------
  # * Public Instance Variable
  #--------------------------------------------------------------------------
  attr_sec_accessor :bgm_volume    , 100
  attr_sec_accessor :bgs_volume    , 100
  attr_sec_accessor :me_volume     , 100
  attr_sec_accessor :se_volume     , 100
  attr_sec_accessor :bgm_pitch     , 100
  attr_sec_accessor :bgs_pitch     , 100
  attr_sec_accessor :me_pitch      , 100
  attr_sec_accessor :se_pitch      , 100
  attr_sec_accessor :volume_control, 'false'
  #--------------------------------------------------------------------------
  # * Redefined method: bgm_memorize, bgm_restore
  #--------------------------------------------------------------------------
  VX && define_sec_method(:bgm_memorize) { @memorized_bgm = @playing_bgm }
  VX && define_sec_method(:bgm_restore)  { bgm_play(@memorized_bgm)     }
  #--------------------------------------------------------------------------
  # * Redirect Listing
  #--------------------------------------------------------------------------
  redirect_method :bgm_stop,     'Audio.bgm_stop'
  redirect_method :bgs_stop,     'Audio.bgs_stop'
  redirect_method :se_stop,      'Audio.se_stop'
  redirect_method :me_stop,      'Audio.me_stop'
  #--------------------------------------------------------------------------
  # * Alias Listing
  #--------------------------------------------------------------------------
  alias_sec_method :bgm_memorize, :save_bgm
  alias_sec_method :bgm_restore,  :replay_bgm
  alias_sec_method :save_bgm,     :bgm_memorize
  alias_sec_method :replay_bgm,   :bgm_restore
  #--------------------------------------------------------------------------
  # * Aliased method: bgm_play, bgs_play, me_play, se_play
  #--------------------------------------------------------------------------
  [:bgm,:bgs,:me,:se].each do |sa|
    next unless method_defined?(:"#{sa}_play")
    alias_sec_method(:"drg_#{sa}_play", :"#{sa}_play")
    define_method(:"#{sa}_play") do |bgm,*a|
      if bgm.is_a?(String) && bgm != ''
        bgm = RPG::AudioFile.new(bgm,send(:"#{sa}_volume"),send(:"#{sa}_pitch"))
      elsif volume_control && bgm.is_a?(RPG::AudioFile) && bgm.name != ""
        bgm = bgm.clone
        bgm.volume = Math.percent(bgm.volume,send(:"#{sa}_volume"))
        bgm.pitch  = Math.percent(bgm.pitch,send(:"#{sa}_pitch"))
      end
      @playing_bgm = bgm if "#{sa}" == 'bgm'
      @playing_bgs = bgm if "#{sa}" == 'bgs'
      if respond_to?(:"drg_#{sa}_play")
        send(:"drg_#{sa}_play", bgm,*a)
      else
        if bgm.is_a?(RPG::AudioFile) && bgm.name != ''
          Audio.send(:"#{sa}_play","Audio/#{sa}/" + bgm.name,
             bgm.volume.round, bgm.pitch.round,*a)
        else
          send(:"#{sa}_stop")
        end
        Graphics.frame_reset
      end
    end
  end
end

#==============================================================================
# ** Object
#------------------------------------------------------------------------------
#  This class is superclass for all class
#==============================================================================
class Object
  #-------------------------------------------------------------------------
  # * New method: all_variable_dispose
  #-------------------------------------------------------------------------
  def all_variable_dispose
    all = instance_variables.map {|s| instance_variable_get("#{s}")}.flatten
    all.delete_if {|s| s.not.respond_to?(:dispose) }
    all.delete_if {|s| s.respond_to?(:disposed?) && s.disposed?}
    all.dispose
  end
  #-------------------------------------------------------------------------
  # * New method: rand_between
  #-------------------------------------------------------------------------
  unless method_defined?(:rand_between)
    def rand_between(min, max)
      min + rand(max - min + 1) if min.is_a?(Numeric) && max.is_a?(Numeric)
    end
  end
  #-------------------------------------------------------------------------
  # * New method: get_note
  #-------------------------------------------------------------------------
  unless method_defined?(:get_note)
    def get_note
      respond_to?(:note) ? note : ""
    end
  end
  #-------------------------------------------------------------------------
  # * New method: screen_rect
  #-------------------------------------------------------------------------
  unless method_defined?(:screen_rect)
    def screen_rect(as_rect = true)
      array = [0,0,Graphics.width,Graphics.height]
      as_rect ? Rect.new(*array) : array
    end
  end
  #-------------------------------------------------------------------------
  # * New method: forcesave
  #-------------------------------------------------------------------------
  unless method_defined?(:forcesave)
    def forcesave(index)
      return DataManager.save_game(index) if defined?(DataManager)
      save = LiTTleDRAgo::VX ? Scene_File.new(0,nil,0) : Scene_Save.new
      begin
        file = File.open(save.make_filename(index), "wb")
        (save.write_save_data(file) && file.close) || true
      rescue
        File.delete(save.make_filename(index)) rescue nil
        (Sound.play_buzzer) && false
      end
    end
  end
  #--------------------------------------------------------------------------
  # * sprite_report
  #--------------------------------------------------------------------------
  unless method_defined?(:script_report)
    def script_report(text,font = nil)
      s = (text.is_a?(String) || (text = text.inspect)) && Sprite.new
      s.opacity = (s.bitmap = Bitmap.new((g = Graphics).width,g.height)) && 0
      s.bitmap.font.name = ['Georgia',Font.default_name].flatten
      s.bitmap.font = (s.z += 9999) && (font || s.bitmap.font)
      y = (text.split(/\n/).size * s.bitmap.text_size(text).height) / 2
      s.bitmap.draw_enter_edging_text(0,0-y,g.width,g.height,text,1)
      (s.opacity += 10) && g.update until s.opacity >= 255
      g.wait_for_input
      (s.opacity -= 10) && g.update until s.opacity <= 0
      s.dispose
    end
  end
  #-------------------------------------------------------------------------
  # * New method: not
  #-------------------------------------------------------------------------
  define_sec_method(:not) { Not.new(self) }
  #============================================================================
  # ** Not
  #----------------------------------------------------------------------------
  #
  #============================================================================
  class Not
    #-------------------------------------------------------------------------
    # * Private
    #-------------------------------------------------------------------------
    private *instance_methods.select { |m| m !~ /(^__|^\W|^binding$)/ }
    #-------------------------------------------------------------------------
    # * Object Initialization
    #-------------------------------------------------------------------------
    define_method(:initialize) {|original|  @original = original }
    #-------------------------------------------------------------------------
    # * New method: method_missing
    #-------------------------------------------------------------------------
    def method_missing(sym, *a, &blk)
      !@original.send(sym, *a, &blk)
    end
  end
end

#==============================================================================
# ** Kernel
#------------------------------------------------------------------------------
#  
#==============================================================================
module Kernel
  #-------------------------------------------------------------------------
  # * Alias Listing
  #-------------------------------------------------------------------------
  $@ || alias_method(:carrot, :proc)
  #-------------------------------------------------------------------------
  # * Script Check
  #-------------------------------------------------------------------------
  if LiTTleDRAgo::XP && LiTTleDRAgo::RGSS3 && !defined?(XPA_CONFIG)
    $@ || alias_method(:last_before_p,        :p)
    $@ || alias_method(:last_before_print,    :print)
    $@ || alias_method(:last_before_msgbox,   :msgbox)
    $@ || alias_method(:last_before_msgbox_p, :msgbox_p)
    define_method(:p)       {|*args| last_before_msgbox_p(*args)}
    define_method(:print)   {|*args| last_before_msgbox(*args)  }
    define_method(:msgbox)  {|*args| last_before_print(*args)   }
    define_method(:msgbox_p){|*args| last_before_p(*args)       }
  end
  define_method(:draise) {|*args| (dp(*args) && !1) || exit }
  define_method(:dp)     {|*a| script_report(a.map {|i| i.inspect}.join("\n"))}
  #-------------------------------------------------------------------------
  # * New method: dprint
  #-------------------------------------------------------------------------
  def dprint(*args)
    script_report(args.map {|i| i.is_a?(String) ? i : i.inspect}.join)
  end
  #-------------------------------------------------------------------------
  # * New method: press_any_key
  #-------------------------------------------------------------------------
  unless method_defined?(:press_any_key)
    def press_any_key
      return false if Input.nil?
      return true if Input.trigger?(Input::A)    ||Input.trigger?(Input::B)
      return true if Input.trigger?(Input::C)    ||Input.trigger?(Input::X)
      return true if Input.trigger?(Input::Y)    ||Input.trigger?(Input::Z)
      return true if Input.trigger?(Input::L)    ||Input.trigger?(Input::R)
      return true if Input.trigger?(Input::UP)   ||Input.trigger?(Input::DOWN)
      return true if Input.trigger?(Input::LEFT) ||Input.trigger?(Input::RIGHT)
      return true if Input.trigger?(Input::SHIFT)||Input.trigger?(Input::CTRL)
      return true if Input.trigger?(Input::ALT)  ||Input.trigger?(Input::F5)
      return true if Input.trigger?(Input::F6)   ||Input.trigger?(Input::F7)
      return true if Input.trigger?(Input::F8)   ||Input.trigger?(Input::F9)
    end
  end
  #-------------------------------------------------------------------------
  # * New method: inspect_instance_variable
  #-------------------------------------------------------------------------
  unless method_defined?(:inspect_instance_variable)
    def inspect_instance_variable(class_name, variable)
      Module.const_get(class_name).new.instance_variable_get(:"@#{variable}")
    end
  end
end

#==============================================================================
# ** Proc
#------------------------------------------------------------------------------
#  
#==============================================================================
class Proc
  #-------------------------------------------------------------------------
  # * New method: bind
  #-------------------------------------------------------------------------
  unless method_defined?(:bind)
    def bind(object)
      block, time = self, Time.now
      class << object
        self
      end.class_eval do
        define_method((name = "__bind_#{time.to_i}_#{time.usec}"), &block)
        remove_method((method = instance_method(name)) && name)
        method
      end.bind(object)
    end
  end
end
#==============================================================================
# ** Enumerable
#------------------------------------------------------------------------------
#  
#==============================================================================
module Enumerable
  #---------------------------------------------------------------------------
  # * Redefined method: shuffle
  #---------------------------------------------------------------------------
  define_sec_method(:shuffle) {(a = entries) && Array.new(size){ a.random!}}
  #---------------------------------------------------------------------------
  # * New method: random_each
  #---------------------------------------------------------------------------
  unless method_defined?(:random_each)
    def random_each() (block_given? ? shuffle.each {|s| yield s } : random) end
  end
  #---------------------------------------------------------------------------
  # * New method: random_each_with_index
  #---------------------------------------------------------------------------
  unless method_defined?(:random_each_with_index)
    def random_each_with_index
      block_given? ? self.shuffle.each_with_index {|obj, i| yield obj,i } :
        self.random                                    
    end
  end
  #---------------------------------------------------------------------------
  # * Redefined method: drop_while
  #---------------------------------------------------------------------------
  unless method_defined?(:drop_while)
    def drop_while(&block)
      ary, state = [], false
      self.each do |e|
        state = true if !state and !block.call(e)
        ary << e if state
      end
      ary
    end
  end
  #---------------------------------------------------------------------------
  # * Redefined method: take_while
  #---------------------------------------------------------------------------
  unless method_defined?(:take_while)
    def take_while(&block)
      ary = []
      self.each do |e|
        return ary unless block.call(e)
        ary << e
      end
      ary
    end
  end
  #---------------------------------------------------------------------------
  # * Redefined method: partition
  #---------------------------------------------------------------------------
  unless method_defined?(:partition)
    def partition(&block)
      ary_T, ary_F = [], []
      self.each {|val| block.call(val) ? ary_T.push(val) : ary_F.push(val)}
      return ary_T, ary_F
    end
  end
  #---------------------------------------------------------------------------
  # * Redefined method: grep
  #---------------------------------------------------------------------------
  unless method_defined?(:grep)
    def grep(pattern, &block)
      collect {|v| pattern === v && ary.push((block)? block.call(v): v)}
    end
  end
  #---------------------------------------------------------------------------
  # * Redefined method: each_slice
  #---------------------------------------------------------------------------
  unless method_defined?(:each_slice)
    def each_slice(n, &block)
      not_integer = "expected Integer for 1st argument"
      n.is_a?(Integer) || raise(TypeError,not_integer,caller(1))
      n <= 0 && raise(ArgumentError, "invalid slice size",caller(1))
      ary = []
      self.each do |e|
        ary << e
        if ary.size == n
          block.call(ary)
          ary = []
        end
      end
      block.call(ary) unless ary.empty?
    end
  end
  #---------------------------------------------------------------------------
  # * Redefined method: minmax
  #---------------------------------------------------------------------------
  unless method_defined?(:minmax)
    def minmax(&block) (a = sort(&block)) && [a.first,a.last]  end
  end
end
  
#==============================================================================
# ** Array
#------------------------------------------------------------------------------
#  
#==============================================================================
class Array
  #---------------------------------------------------------------------------
  # * Define Secondary Listing
  #---------------------------------------------------------------------------
  define_sec_method(:have_all?)     { |*array| self & array == array        }
  define_sec_method(:have_any?)     { |*array| self - array != self         }
  define_sec_method(:relay)         { |type| map {|s| s.send(:"to_#{type}")}}
  #---------------------------------------------------------------------------
  # * Redirect method
  #---------------------------------------------------------------------------
  redirect_method :switch_on,      'self.switch = (true)'                  
  redirect_method :switch_off,     'self.switch = (false)'                  
  redirect_method :random,         'self.at(rand(size))'         
  redirect_method :random!,        'self.delete_at(rand(size))'
  redirect_method :sum,            'self.inject(0) {|r, n| r += n}'
  redirect_method :prod,           'self.inject(1) {|r, n| r *= n}'
  redirect_method :next_item,      '(item = shift) && push(item) &&  (item)'
  redirect_method :previous_item,  '(item = pop) && unshift(item) && (item)'
  redirect_method :nitems,         'count {|x| x.not.nil?}'
  redirect_method :switch_reverse, 'switch=(:flip)'
  #---------------------------------------------------------------------------
  # * New method: method_missing
  #---------------------------------------------------------------------------
  def method_missing(val,*a,&b)
    en = self.entries.find_all {|s|s.respond_to?(val.to_sym)}
    if self.not.empty? && en.empty?
      text = "Undefined method #{val} for #{self.inspect}"
      raise(NoMethodError,text,caller(1))
    end
    return en.map {|s| s.send(val.to_s,*a,&b)}
  end
  #-------------------------------------------------------------------------
  # * New method: each_ntuple
  #-------------------------------------------------------------------------
  unless method_defined?(:each_ntuple)
    def each_ntuple(number)
      0.step(size - size % number - 1, number) {|i| yield(*self[i, number])}
    end
  end
  #-------------------------------------------------------------------------
  # * New method: each_pair
  #-------------------------------------------------------------------------
  unless method_defined?(:each_pair)
    def each_pair()   each_ntuple(2) {|a,b| yield a, b }       end
  end
  #---------------------------------------------------------------------------
  # * New method: each_triple
  #---------------------------------------------------------------------------
  unless method_defined?(:each_triple)
    def each_triple() each_ntuple(3) {|a,b,c| yield a, b, c }  end
  end
  #---------------------------------------------------------------------------
  # * Redefined method: shuffle! (for RMXP)
  #---------------------------------------------------------------------------
  unless method_defined?(:shuffle!)
    def shuffle!()  self.dup == replace(shuffle) ? nil : self  end
  end
  #---------------------------------------------------------------------------
  # * New method: sort_by!
  #---------------------------------------------------------------------------
  unless method_defined?(:sort_by!)
    def sort_by!(*args,&block)
      self.dup == replace(sort_by(*args,&block)) ? nil : self
    end
  end
  #---------------------------------------------------------------------------
  # * New method: recursive_clone
  #---------------------------------------------------------------------------
  unless method_defined?(:rclone)
    def recursive_clone
      (clon = self.clone).each_index do |i|
        clon = clon.recursive_clone rescue clon.clone rescue clon
      end
      clon
    end
    alias_method(:rclone, :recursive_clone)
  end
  #---------------------------------------------------------------------------
  # * New method: to_hash
  #---------------------------------------------------------------------------
  unless method_defined?(:to_hash)
    def to_hash
      (hash = Hash.new) && each_index {|i| hash = self} && hash
    end
  end  
  #---------------------------------------------------------------------------
  # * Redefined method: count
  #---------------------------------------------------------------------------
  unless method_defined?(:count)
    def count(*args, &block)
      if block_given?
        find_all {|s| block.call(s)}.size
      else
        ary = args.empty? ? self : args.map {|a| find_all{|s| s == a}}
        ary.compact.size
      end
    end
  end
  #---------------------------------------------------------------------------
  # * New method: each_with_next
  #---------------------------------------------------------------------------
  unless method_defined?(:each_with_next)
    def each_with_next(num = 1)
      (size - num).times {|i| yield(*self[i..(i+num)])}
    end
  end
  #---------------------------------------------------------------------------
  # * New method: switch=
  #---------------------------------------------------------------------------
  unless method_defined?(:switch=)
    def switch=(value)
      integer = search_var_key[0]
      array   = search_var_key[1]
      if value == :flip
        integer.each {|i| $game_switches = !$game_switches }
        array.each {|i| $game_self_switches = !$game_self_switches }
      else
        integer.each {|i| $game_switches = value }
        array.each {|i| $game_self_switches = value }
      end
      $game_map.need_refresh = true if $game_map.respond_to?(:need_refresh)
    end
  end
  #---------------------------------------------------------------------------
  # * New method: variable
  #---------------------------------------------------------------------------
  def variable(value = nil,method = "=")
    integer = search_var_key[0]  
    integer += search_var_key[1] if $drago_game_variable
    return integer.map {|i| $game_variables} if value.nil?
    result = integer.map {|i| eval("$game_variables #{method} #{value}") }
    $game_map.need_refresh = true if $game_map.respond_to?(:need_refresh)
    result
  end
  #---------------------------------------------------------------------------
  # * New method: search_var_key
  #---------------------------------------------------------------------------
  def search_var_key
    integer = self.find_all {|s| s.is_a?(Integer)}
    range   = self.find_all {|s| s.is_a?(Range)  }
    array   = self.find_all {|s| s.is_a?(Array)  }
    string  = self.find_all {|s| s.is_a?(String) }
    integer = integer + range.collect {|s| s.to_a }.flatten
    $game_switches      ||= Game_Switches.new
    $game_self_switches ||= Game_SelfSwitches.new
    $game_variables     ||= Game_Variables.new
    return [integer.sort.uniq, array.sort.uniq]
  end
  #---------------------------------------------------------------------------
  # * New method: rindexes
  #---------------------------------------------------------------------------
  unless method_defined?(:rindexes)
    def rindexes(*values)
      array = Array.new
      each_index {|i| values.include?(self) && array.push(i)}
      array
    end
  end
  #---------------------------------------------------------------------------
  # * New method: deep
  #---------------------------------------------------------------------------
  unless method_defined?(:deep)
    def deep(deep = -1)
      tmp_deep = deep + 1
      deep = tmp_deep
      self.each do |i|
        deep < i.deep(tmp_deep) && deep = i.deep(tmp_deep)  rescue nil
      end
      deep
    end
  end
  #---------------------------------------------------------------------------
  # * New method: recursive_flatten
  #---------------------------------------------------------------------------
  unless method_defined?(:rflatten)
    def recursive_flatten
      (array = self.recursive_clone).each_index do |i|
        array = array.to_a if array.is_a?(Hash)
        array = array.recursive_flatten rescue array
      end
      array.flatten!
      array
    end
    alias_method(:rflatten, :recursive_flatten)
  end
  #---------------------------------------------------------------------------
  # * New method: recursive_flatten!
  #---------------------------------------------------------------------------
  unless method_defined?(:rflatten!)
    def recursive_flatten!
      self.each_index do |i|
        self = self.to_a if self.is_a?(Hash)
        self = self.recursive_flatten! rescue self
      end
      self.flatten!
      self
    end
    alias_method(:rflatten!, :recursive_flatten!)
  end
  #---------------------------------------------------------------------------
  # * Redefined method: product
  #---------------------------------------------------------------------------
  def dproduct(*arrays)
    (e = "(result = []) && self.each {|i0| ") &&
    (a = arrays.size).times {|i| e += "arrays[#{i}].each {|i#{i+1}| " }
    (e += "result.push([i0,") && a.times {|i| e += "i#{i+1}," }
    (e += "])}" + "}" * a + " && result"  )
    return eval(e)
  end
  alias_sec_method(:product, :dproduct)
  #---------------------------------------------------------------------------
  # * New method: geometric_average
  #---------------------------------------------------------------------------
  unless method_defined?(:geometric_average)
    def geometric_average(float = false)
      average = empty? ? 0 : prod ** (1.0 / size)
      return (float ? average : average.to_i)
    end
  end
  #---------------------------------------------------------------------------
  # * New method: average
  #---------------------------------------------------------------------------
  unless method_defined?(:average)
    def average(float = false)
      sum / [(float ? size.to_f : size.to_i), 1].max
    end
  end
  #---------------------------------------------------------------------------
  # * Alias method
  #---------------------------------------------------------------------------
  alias_sec_method :has_all?, :have_all?
  alias_sec_method :has_any?, :have_any?
end
  
#==============================================================================
# ** Hash
#------------------------------------------------------------------------------
#  
#==============================================================================
class Hash
  #--------------------------------------------------------------------------
  # * Define Secondary Listing
  #--------------------------------------------------------------------------
  define_sec_method(:reverse!)  { self.dup == replace(reverse) ? nil : self }
  #--------------------------------------------------------------------------
  # ● New method: reverse
  #--------------------------------------------------------------------------
  unless method_defined?(:reverse)
    def reverse
      key, new_hash = self.keys, {}
      key.reverse.each_with_index {|k,i| new_hash[k] = self[key]}
      new_hash
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: recursive_clone
  #--------------------------------------------------------------------------
  unless method_defined?(:rclone)
    def recursive_clone
      (clon = self.clone).each_key do |i|
        clon = clon.recursive_clone rescue clon.clone rescue clon
      end
      clon
    end
    alias_method(:rclone, :recursive_clone)
  end
  #--------------------------------------------------------------------------
  # ● New method: deep
  #--------------------------------------------------------------------------
  unless method_defined?(:deep)
    def deep(deep = -1)
      key_deep = value_deep = tmp_deep = deep + 1
      self.each do |k, v|
        key_deep = k.deep(tmp_deep)  if key_deep  < k.deep(tmp_deep) rescue nil
        value_deep = v.deep(tmp_deep)if value_deep< v.deep(tmp_deep) rescue nil
      end
      key_deep > value_deep ? key_deep : value_deep
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: fusion
  #--------------------------------------------------------------------------
  unless method_defined?(:fusion)
    def fusion
      (array = sort).each_index do |i|
        array = array[0] + array[1] rescue array
      end
      array
    end
  end
end
#==============================================================================
# ** Range     
#------------------------------------------------------------------------------
#  
#==============================================================================
class Range
  #--------------------------------------------------------------------------
  # * Include Comparable
  #--------------------------------------------------------------------------
  include(Comparable)
  #-------------------------------------------------------------------------
  # ● New method: random
  #-------------------------------------------------------------------------
  define_sec_method(:random) { self.to_a.random }
  define_sec_method(:sum)    { self.to_a.sum }
  define_sec_method(:prod)   { self.to_a.prod }
  #-------------------------------------------------------------------------
  # ● New method: <=>
  #-------------------------------------------------------------------------
  unless method_defined?(:"<=>")
    def <=>(other)
      temp = first <=> other.first
      temp = last <=> other.last if temp = 0
      return temp
    end
  end
end
#==============================================================================
# ** NilClass
#------------------------------------------------------------------------------
#  
#==============================================================================
class NilClass
  #--------------------------------------------------------------------------
  # ● Overwriten method: clone, dup
  #--------------------------------------------------------------------------
  define_method(:clone) {|*a|}
  define_method(:dup)   {|*a|}
end

#==============================================================================
# ** Math
#------------------------------------------------------------------------------
#  
#==============================================================================
module Math
  #--------------------------------------------------------------------------
  # ● New method: A (Ackermann function)
  #--------------------------------------------------------------------------
  def self.A(m,n)
    text = 'Ackermann: No negative values allowed.' if m < 0 or n < 0
    raise(ArgumentError.new(text))                  if m < 0 or n < 0
    return n + 1 if m == 0
    return Math.A(m - 1, 1) if n == 0
    return Math.A(m - 1, Math.A(m, n - 1))
  end
  #--------------------------------------------------------------------------
  # ● New method: percent
  #--------------------------------------------------------------------------
  def self.percent(min,max=100)
    (min / max.to_f) * 100.0
  end
end

#==============================================================================
# ** Numeric
#------------------------------------------------------------------------------
#  
#==============================================================================
class Numeric
  #--------------------------------------------------------------------------
  # ● Define Secondary Listing: clamp, sign
  #--------------------------------------------------------------------------
  define_sec_method(:clamp) {|min,max|  [[self, min].max, max].min}
  define_sec_method(:sign)  { zero? ? 0 :  (self / self.abs).to_i }
  #--------------------------------------------------------------------------
  # ● New method: group
  #--------------------------------------------------------------------------
  unless method_defined?(:group)
    def group
      self.to_s.gsub(/(\d)(?=\d{3}+(?:\.|$))(\d{3}\..*)?/,'\1,\2')
    end
  end
end

#==============================================================================
# ** Integer
#------------------------------------------------------------------------------
#  
#==============================================================================
class Integer
  #--------------------------------------------------------------------------
  # ● Define Secondary Listing: sum_to, factorial
  #--------------------------------------------------------------------------
  define_sec_method(:sum_down)  { sum_to(0)}
  define_sec_method(:factorial) {(sign * (1..(self.abs)).prod)  }
  #--------------------------------------------------------------------------
  # * New method: sum_to
  #--------------------------------------------------------------------------
  unless method_defined?(:sum_to)
    def sum_to(v = self) (v > self ? (self..v) : (v..self)).sum   end
  end
end

#==============================================================================
# ** Float
#------------------------------------------------------------------------------
#  
#==============================================================================
class Float
  #--------------------------------------------------------------------------
  # ● Overwriten method: =~
  #--------------------------------------------------------------------------
  # A close float comparison. Because of rounding errors, this comparison will
  # help compensate for that. Since 0 and 0.0001 are very close to each other,
  # it's best to use this custom comparison.
  define_method(:"=~") {|num| (self + 0.0001 >= num && self - 0.0001 <= num) }
  #--------------------------------------------------------------------------
  # ● New method: float_points
  #--------------------------------------------------------------------------
  unless method_defined?(:float_points)
    def float_points(points = 2)
      n = self * 10 ** points
      n = n.round.to_f / (10.0 ** points)
      return n
    end
  end
end

#==============================================================================
# ** Color
#------------------------------------------------------------------------------
#  
#==============================================================================
class Color
  #--------------------------------------------------------------------------
  # ● Define Secondary Listing
  #--------------------------------------------------------------------------
  define_sec_method(:invert)   { set(255-red, 255-green, 255-blue, alpha)}
  #----------------------------------------------------------------------------
  # * New method: to_hex
  #----------------------------------------------------------------------------
  def to_hex
    str = [self.blue.to_i, self.green.to_i, self.red.to_i].pack("C*")
    str.inspect.gsub('\\x','')
  end  
end
class << Color
  #--------------------------------------------------------------------------
  # ● Define Secondary Listing: red, green, blue, white, black... etc
  #--------------------------------------------------------------------------
  define_sec_method(:red)      {|*a| self.new(255,  0,  0,a.first||255)}
  define_sec_method(:green)    {|*a| self.new(  0,255,  0,a.first||255)}
  define_sec_method(:blue)     {|*a| self.new(  0,  0,255,a.first||255)}
  define_sec_method(:white)    {|*a| self.new(255,255,255,a.first||255)}
  define_sec_method(:purple)   {|*a| self.new(128,  0,128,a.first||255)}
  define_sec_method(:gray)     {|*a| self.new(128,128,128,a.first||255)}
  define_sec_method(:lgray)    {|*a| self.new(211,211,211,a.first||255)}
  define_sec_method(:dgray)    {|*a| self.new( 64, 64, 64,a.first||255)}
  define_sec_method(:pink)     {|*a| self.new(255,175,175,a.first||255)}
  define_sec_method(:orange)   {|*a| self.new(255,165,  0,a.first||255)}
  define_sec_method(:brown)    {|*a| self.new(128, 64,  0,a.first||255)}
  define_sec_method(:chocolate){|*a| self.new(210,105, 30,a.first||255)}
  define_sec_method(:golden)   {|*a| self.new(218,165, 32,a.first||255)}
  define_sec_method(:silver)   {|*a| self.new(192,192,192,a.first||255)}
  define_sec_method(:system)   {|*a| self.new(192,224,255,a.first||255)}
  define_sec_method(:crisis)   {|*a| self.new(255,255, 64,a.first||255)}
  define_sec_method(:knockout) {|*a| self.new(255, 64,  0,a.first||255)}
  #--------------------------------------------------------------------------
  # ● Redirect Listing: cyan, magenta, yellow, black, disabled, erase
  #--------------------------------------------------------------------------
  redirect_method :cyan,       '(red(*args).invert  )'
  redirect_method :magenta,    '(green(*args).invert)'
  redirect_method :yellow,     '(blue(*args).invert )'
  redirect_method :black,      '(white(*args).invert)'
  redirect_method :disabled,   '(black(128).invert  )'
  redirect_method :erase,      '(white(0).invert    )'
  #--------------------------------------------------------------------------
  # ● Alias method: grey, light_grey, dark_grey
  #--------------------------------------------------------------------------
  alias_sec_method :normal,    :white
  alias_sec_method :grey,      :gray
  alias_sec_method :lightgrey, :lightgray, :light_grey, :light_gray, :lgray
  alias_sec_method :darkgrey,  :darkgray,  :dark_grey,  :dark_gray,  :dgray
  #--------------------------------------------------------------------------
  # ● New method: method_missing
  #--------------------------------------------------------------------------
  def method_missing(val,*a)
    val = "#{val}".gsub(/x/i,'')
    if "#{val}".size == 6 && "#{val}".gsub(/(\d+|[a-f])/i,'')
      r = "#{val}"[0..1].hex
      g = "#{val}"[2..3].hex
      b = "#{val}"[4..5].hex
      return self.new(r,g,b,a.first||255)
    end
    text = "Undefined method #{val} for #{self.inspect}"
    raise(NoMethodError, text, caller(1))               
  end
end

#==============================================================================
# ** Viewport
#------------------------------------------------------------------------------
#  
#==============================================================================
class Viewport
  unless method_defined?(:disposed?)
    #--------------------------------------------------------------------------
    # ● Alias Listing
    #--------------------------------------------------------------------------
    alias_sec_method :d3x40932s2, :dispose
    #--------------------------------------------------------------------------
    # ● New method: disposed?
    #   help file is lying when says Viewport#disposed? is exist
    #--------------------------------------------------------------------------
    define_method(:disposed?) { @disposed == true }
    #--------------------------------------------------------------------------
    # ● Aliased method: dispose
    #--------------------------------------------------------------------------
    def dispose(*a)
      (disposed? || d3x40932s2(*a) || 0) && @disposed = true
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: resize
  #--------------------------------------------------------------------------
  define_sec_method(:resize) do |*a|
    self.rect = a.first.is_a?(Rect) ? a.first : Rect.new(*a)
  end
  #--------------------------------------------------------------------------
  # * New method: update_viewport_sizes
  #--------------------------------------------------------------------------
  define_sec_method(:update_viewport_sizes) do |*a|
    map = $game_map
    w, h = Graphics.width, Graphics.height
    hor = map.respond_to?(:loop_horizontal?) && map.loop_horizontal?
    ver = map.respond_to?(:loop_vertical?)   && map.loop_vertical?
    dx = w > map.width  * 32 && !hor ? (w - map.width  * 32) / 2 : 0
    dw = hor ? w : [w, map.width * 32].min
    dy = h > map.height * 32 && !ver ? (h - map.height * 32) / 2 : 0
    dh = ver ? h : [h, map.height * 32].min
    resize(Rect.new(dx, dy, dw, dh))
  end
  #--------------------------------------------------------------------------
  # ● New method: x, y, width, height
  #--------------------------------------------------------------------------
  define_sec_method(:x)       { self.rect.x      }
  define_sec_method(:y)       { self.rect.y      }
  define_sec_method(:width)   { self.rect.width  }
  define_sec_method(:height)  { self.rect.height }
  define_sec_method(:x=)      {|x2| resize(x2,y,width,height) }
  define_sec_method(:y=)      {|y2| resize(x,y2,width,height) }
  define_sec_method(:width=)  {|w1| resize(x,y,w1,height)     }
  define_sec_method(:height=) {|h1| resize(x,y,width,h1)      }
end
#==============================================================================
# ** Graphics
#------------------------------------------------------------------------------
#  This module handles all Graphics
#==============================================================================
class << Graphics
  #------------------------------------------------------------------------
  # ● Include AutoUpdate
  #------------------------------------------------------------------------
  include_auto_update
  #------------------------------------------------------------------------
  # ● Redirect Listing
  #------------------------------------------------------------------------
  redirect_method :width,              'LiTTleDRAgo.client_size.at(0)'
  redirect_method :height,             'LiTTleDRAgo.client_size.at(1)'
  redirect_method :snap_to_bitmap,     'LiTTleDRAgo.snap_to_bitmap'   
  redirect_method :disable_alt_enter,  'LiTTleDRAgo.disable_alt_enter'
  redirect_method :always_on_top,      'LiTTleDRAgo.always_on_top'
  redirect_method :show_fps,           'LiTTleDRAgo.show_fps'
  redirect_method :scale_screen,       'LiTTleDRAgo.scale_screen'
  redirect_method :fill_monitor,       'LiTTleDRAgo.fill_monitor'
  redirect_method :window,             'LiTTleDRAgo.window'
  redirect_method :toggle,             'LiTTleDRAgo.toggle'
  redirect_method :fullscreen,         'LiTTleDRAgo.fullscreen'
  redirect_method :fullscreen?,        'LiTTleDRAgo.fullscreen?'
  redirect_method :control_screen_size,'LiTTleDRAgo.control_screen_size'
  redirect_method :high_priority,      'LiTTleDRAgo.high_priority'
  redirect_method :high_priority=,     'LiTTleDRAgo.high_priority=args.at(0)'
  #------------------------------------------------------------------------
  # ● Alias Listing
  #------------------------------------------------------------------------
  alias_sec_method :resize_screen, :scale_screen
  #--------------------------------------------------------------------------
  # * New method: fadeoutviewport
  #--------------------------------------------------------------------------
  def fadeoutviewport
    @fadeoutviewport  ||= ((v = Viewport.new(0,0,width,height))
        (v.color = (v.z = 0x3FFFFFFF) && Color.new(0,0,0,0)) && v)
  end
  #--------------------------------------------------------------------------
  # ● Redefined method:  wait,   brightness
  #--------------------------------------------------------------------------
  define_sec_method(:wait)       { |frame| frame.times {|i| update }   }
  define_sec_method(:brightness) { (255 - fadeoutviewport.color.alpha) }
  #--------------------------------------------------------------------------
  # * Redefined method: brightness= (Set Graphics Brightness)
  #--------------------------------------------------------------------------
  unless method_defined?(:brightness=)
    def brightness=(value)
      fadeoutviewport.color.alpha = 255 - value.clamp(0,255)
    end
  end
  #--------------------------------------------------------------------------
  # * Redefined method: fadein (Graphics Fade In)
  #         frame : frame of fade
  #--------------------------------------------------------------------------
  unless method_defined?(:fadein)
    def fadein(frames = 10)
      return if frames <= 0
      curvalue, count = brightness, (255 - brightness)
      frames.times do |i|
        (self.brightness = curvalue + (count * i / frames)) && update
      end
    end
  end
  #--------------------------------------------------------------------------
  # * Redefined method: fadeout (Graphics Fade Out)
  #         frame : frame of fade
  #--------------------------------------------------------------------------
  unless method_defined?(:fadeout)
    def fadeout(frames = 10)
      return if frames <= 0
      curvalue = count = self.brightness
      frames.times do |i|
        (self.brightness = curvalue - (count * i / frames)) && update
      end
    end
  end
  #--------------------------------------------------------------------------
  # * New method: wait_for_input
  #--------------------------------------------------------------------------
  unless method_defined?(:wait_for_input)
    def wait_for_input
      [Input,self].update
      [Input,self].update until press_any_key
    end
  end
end

#==============================================================================
# ** Input
#------------------------------------------------------------------------------
#  This module handles all Input
#==============================================================================
class << Input
  #------------------------------------------------------------------------
  # ● Include AutoUpdate
  #------------------------------------------------------------------------
  include_auto_update
  #--------------------------------------------------------------------------
  # ● Aliased method: :press?, :repeat?, :trigger?
  #--------------------------------------------------------------------------
  [:press?,:repeat?,:trigger?].each do |method|
    next unless method_defined?(:"#{method}")
    alias_sec_method(:"sym_#{method}", :"#{method}")
    define_method(:"#{method}") do |*args|
      if (b = args.first).is_a?(Symbol) || b.is_a?(String)
        args[0] = Input.const_get("#{b}") rescue nil
      end
      (args.first.not.nil?) && send(:"sym_#{method}", *args)
    end
  end
end
#==============================================================================
# ** Sprite_Battler
#------------------------------------------------------------------------------
#  This sprite is used to display the battler.It observes the Game_Character
#  class and automatically changes sprite conditions.
#==============================================================================
class Sprite_Battler
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  define_pre_alias(:update) {  @battler.nil? && @battler_name = nil }
end

#==============================================================================
# ** Spriteset_Map
#------------------------------------------------------------------------------
#  This class brings together map screen sprites, tilemaps, etc.
#  It's used within the Scene_Map class.
#==============================================================================
class Spriteset_Map
  #--------------------------------------------------------------------------
  # ● New method: sprite_player
  #--------------------------------------------------------------------------
  define_sec_method(:sprite_player) { find_character($game_player) }
  #------------------------------------------------------------------------
  # ● Public Instance Variables
  #------------------------------------------------------------------------
  attr_sec_reader :character_sprites, 'Array.new'
  attr_reader     :viewport1, :viewport2, :viewport3
  #--------------------------------------------------------------------------
  # * Aliased method: update
  #--------------------------------------------------------------------------
  define_pre_alias(:update) { update_viewport_size_change }
  #--------------------------------------------------------------------------
  # * New method: update_viewport_size_change
  #--------------------------------------------------------------------------
  def update_viewport_size_change
    if viewport_size_change?
      @viewport_map_width     = $game_map.width
      @viewport_map_height    = $game_map.height
      @viewport_screen_width  = Graphics.width
      @viewport_screen_height = Graphics.height
      [@viewport1,@viewport2,@viewport3].compact.update_viewport_sizes
    end
  end
  #--------------------------------------------------------------------------
  # * New method: viewport_size_change?
  #--------------------------------------------------------------------------
  unless method_defined?(:viewport_size_change?)
    def viewport_size_change?
      return true if @viewport_map_width     != $game_map.width
      return true if @viewport_map_height    != $game_map.height
      return true if @viewport_screen_width  != Graphics.width
      return true if @viewport_screen_height != Graphics.height
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: redraw_character_sprites
  #--------------------------------------------------------------------------
  unless method_defined?(:redraw_character_sprites)
    def redraw_character_sprites
      return refresh_characters if self.respond_to?(:refresh_characters)
      character_sprites.dispose
      @character_sprites = $game_map.events.keys.sort.map {|i|
         Sprite_Character.new(@viewport1, $game_map.events) }
      @character_sprites.push(Sprite_Character.new(@viewport1, $game_player))
    end
  end  
  #--------------------------------------------------------------------------
  # ● New method: find_character
  #--------------------------------------------------------------------------
  unless method_defined?(:find_character)
    def find_character(char)
      character_sprites.detect { |s| s.character == char }
    end
  end
  #---------------------------------------------------------------------------
  # * New method: viewport_sprite
  #---------------------------------------------------------------------------
  def viewport_sprite(*v)
    v.collect! {|s| s.is_a?(Symbol) ? instance_variable_get(:"@#{s}") : s }
    v.reject!  {|s| s.not.is_a?(Viewport)}
    all = instance_variables.map {|s| instance_variable_get("#{s}")}.flatten
    all.select {|s| s.respond_to?(:viewport) && v.include?(s.viewport)}
  end
end

#==============================================================================
# ** Game_Battler
#------------------------------------------------------------------------------
#  This class deals with battlers. It's used as a superclass for the Game_Actor
#  and Game_Enemy classes.
#==============================================================================
class Game_Battler
  #--------------------------------------------------------------------------
  # ● New method: alive?
  #--------------------------------------------------------------------------
  define_sec_method(:alive?) { self.not.dead? }
  #--------------------------------------------------------------------------
  # ● New method: hp_percent
  #--------------------------------------------------------------------------
  unless method_defined?(:hp_percent)
    def hp_percent(integer = false, float_points = 2)
      n = Math.percent(hp,(respond_to?(:mhp) ? mhp : maxhp))
      return integer ? Integer(n) : n.float_points(float_points)
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: sp_percent
  #--------------------------------------------------------------------------
  unless method_defined?(:sp_percent)
    def sp_percent(integer = false, float_points = 2)
      n =  Math.percent((respond_to?(:sp) ? sp : mp),
      ((respond_to?(:mmp) ? mmp : (respond_to?(:maxsp) ? maxsp : maxmp))))
      return integer ? Integer(n) : n.float_points(float_points)
    end
    alias_method :mp_percent, :sp_percent
  end
end

#==============================================================================
# ** Game_Character
#------------------------------------------------------------------------------
#  This class deals with characters. It's used as a superclass for the
#  Game_Player and Game_Event classes.
#==============================================================================
class Game_Character
  #--------------------------------------------------------------------------
  # ● Redirect Listing
  #--------------------------------------------------------------------------
  redirect_method :move_down,        'move_straight(2,*args)'
  redirect_method :move_left,        'move_straight(4,*args)'
  redirect_method :move_right,       'move_straight(6,*args)'
  redirect_method :move_up,          'move_straight(8,*args)'
  redirect_method :turn_down,        'set_direction(2,*args)'
  redirect_method :turn_left,        'set_direction(4,*args)'
  redirect_method :turn_right,       'set_direction(6,*args)'
  redirect_method :turn_up,          'set_direction(8,*args)'
  redirect_method :move_lower_left,  'move_diagonal(4, 2,*args)'
  redirect_method :move_lower_right, 'move_diagonal(6, 2,*args)'
  redirect_method :move_upper_left,  'move_diagonal(4, 8,*args)'
  redirect_method :move_upper_right, 'move_diagonal(6, 8,*args)'
  redirect_method :character_sprite, '$game_map.character_sprite(self)'
  redirect_method :character_above?, '(args.first.y > @y)'
  redirect_method :character_below?, '(args.first.y < @y)'
  redirect_method :character_right?, '(args.first.x < @x)'
  redirect_method :character_left?,  '(args.first.x > @x)'
  redirect_method :pos,              '[@x, @y]'
  redirect_method :pos_nt?,          '!@through && pos?'
  redirect_method :normal_priority?, '@character_name != ""'  
  redirect_method :map_passable?,    '$game_map.passable?'
  redirect_method :map_terrain_tag,  '$game_map.terrain_tag'
  #--------------------------------------------------------------------------
  # * Redefined method: pos?
  #                     anime
  #                     reverse_dir
  #--------------------------------------------------------------------------
  define_sec_method(:reverse_dir) {|dir| 10 - dir }
  define_sec_method(:pos?)        {|x,y| @x == x && @y == y  }
  define_sec_method(:anime)       {|aid| @animation_id = aid }
  #--------------------------------------------------------------------------
  # ● Redefined method: check_event_trigger_touch_front
  #--------------------------------------------------------------------------
  unless method_defined?(:check_event_trigger_touch_front)
    def check_event_trigger_touch_front
      x2 = $game_map.round_x_with_direction(@x, @direction)
      y2 = $game_map.round_y_with_direction(@y, @direction)
      check_event_trigger_touch(x2, y2)
    end
  end
  #--------------------------------------------------------------------------
  # ● Redefined method: move_straight
  #--------------------------------------------------------------------------
  unless method_defined?(:move_straight)
    def move_straight(d, turn_ok = true)
      if passable?(@x, @y, d)
        set_direction(d)
        @x = $game_map.round_x_with_direction(@x, d)
        @y = $game_map.round_y_with_direction(@y, d)
        increase_steps
      elsif turn_ok
        set_direction(d)
        check_event_trigger_touch_front
      end
    end
  end  
  #--------------------------------------------------------------------------
  # ● Redefined method: set_direction
  #--------------------------------------------------------------------------
  unless method_defined?(:set_direction)
    def set_direction(d)
      @direction = d unless @direction_fix || d == 0
      @stop_count = 0
    end
  end
  #--------------------------------------------------------------------------
  # ● Redefined method: set_graphic
  #--------------------------------------------------------------------------
  unless method_defined?(:set_graphic)
    def set_graphic(character_name, character_index = 0)
      @tile_id = 0
      @character_name = character_name
      if self.respond_to?(:character_index)
        @character_index = character_index
      else
        @character_hue = character_index
      end
      @original_pattern = 1
    end
  end
  #--------------------------------------------------------------------------
  # ● Redefined method: swap
  #--------------------------------------------------------------------------
  unless method_defined?(:swap)
    def swap(character)
      new_pos = character.pos
      character.moveto(x, y)
      moveto(*new_pos)
    end
  end
  #--------------------------------------------------------------------------
  # ● Redefined method: rotate_swap_prev
  #--------------------------------------------------------------------------
  unless method_defined?(:rotate_swap_prev)
    def rotate_swap_prev(*character)
      character.unshift(self)
      position = character.collect {|c| c.pos}
      character.each_with_index { |c,i| c.moveto(*position[i-1]) }
    end
  end
  #--------------------------------------------------------------------------
  # ● Redefined method: rotate_swap_next
  #--------------------------------------------------------------------------
  unless method_defined?(:rotate_swap_next)
    def rotate_swap_next(*character)
      character.unshift(self)
      position = character.collect {|c| c.pos}
      character.each_with_index do |char,index|
        char.moveto(*position[index + 1 >= position.size ? 0 : index + 1])
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: distance_from
  #--------------------------------------------------------------------------
  unless method_defined?(:distance_from)
    def distance_from(character,type= 'xy')
      character = $game_map.events[character] if character.is_a?(Integer)
      return 0 if character.nil?
      return (@x - character.x).abs if type.to_s == 'x'
      return (@y - character.y).abs if type.to_s == 'y'
      return Math.hypot(@x - character.x, @y - character.y)
    end
  end
  #--------------------------------------------------------------------------
  # * Redefined method: distance_x_from
  #--------------------------------------------------------------------------
  unless method_defined?(:distance_x_from)
    def distance_x_from(x)
      result = @x - x
      if result.abs > $game_map.width / 2
        result += result < 0 ? $game_map.width : -$game_map.width
      end
      result
    end
  end
  #--------------------------------------------------------------------------
  # * Redefined method: distance_y_from
  #--------------------------------------------------------------------------
  unless method_defined?(:distance_y_from)
    def distance_y_from(y)
      result = @y - y
      if result.abs > $game_map.height / 2
        result += result < 0 ? $game_map.height : -$game_map.height
      end
      result
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: random_teleport
  #--------------------------------------------------------------------------
  unless method_defined?(:random_teleport)
    def random_teleport
      1000.times do
        moveto(rand($game_map.height), rand($game_map.width))
        vx  = LiTTleDRAgo::VX && !LiTTleDRAgo::VXA
        arg = vx ? [@x,@y] : [@x,@y,@direction]
        break if passable?(*arg)
      end || true
    end
  end
  #--------------------------------------------------------------------------
  # * Redefined method: diagonal_passable? (for RMXP)
  #     horz : Horizontal (4 or 6)
  #     vert : Vertical (2 or 8)
  #--------------------------------------------------------------------------
  unless method_defined?(:diagonal_passable?)
    def diagonal_passable?(x, y, horz, vert)
      x2 = $game_map.round_x_with_direction(x, horz)
      y2 = $game_map.round_y_with_direction(y, vert)
      (passable?(x, y, vert) && passable?(x, y2, horz)) ||
      (passable?(x, y, horz) && passable?(x2, y, vert))
    end
  end
  #--------------------------------------------------------------------------
  # * Redefined method: collide_with_characters? (for RMXP)
  #--------------------------------------------------------------------------
  unless method_defined?(:collide_with_characters?)
    def collide_with_characters?(x, y)
      collide_with_events?(x, y)
    end
  end
  #--------------------------------------------------------------------------
  # * Redefined method: collide_with_events? (for RMXP)
  #--------------------------------------------------------------------------
  unless method_defined?(:collide_with_events?)
    def collide_with_events?(x, y)
      $game_map.events_xy_nt(x, y).any? do |event|
        event.normal_priority? || self.is_a?(Game_Event)
      end
    end
  end
  #--------------------------------------------------------------------------
  # * Redefined method: debug_through?
  #--------------------------------------------------------------------------
  unless method_defined?(:debug_through?)
    def debug_through?
      debug = LiTTleDRAgo::VX ? $TEST : $DEBUG
      return debug && Input.press?(Input::CTRL) if self.is_a?(Game_Player)
      return false
    end
  end
end
#==============================================================================
# ** Game_Actor
#------------------------------------------------------------------------------
#  This class handles actors. It is used within the Game_Actors class
# ($game_actors), also referenced from the Game_Party class ($game_party).
#==============================================================================

class Game_Actor
  #--------------------------------------------------------------------------
  # * Get Actor Object
  #--------------------------------------------------------------------------
  define_sec_method(:actor)  { $data_actors[@actor_id]  }
  define_method(:class)      { $data_classes[@class_id] }
end

#==============================================================================
# ** Game_Enemy
#------------------------------------------------------------------------------
#  This class handles enemies. It used within the Game_Troop class
# ($game_troop).
#==============================================================================

class Game_Enemy
  #--------------------------------------------------------------------------
  # * Get Enemy Object
  #--------------------------------------------------------------------------
  define_sec_method(:enemy)  { $data_enemies[@enemy_id] }
end

#==============================================================================
# ** Game_Player
#------------------------------------------------------------------------------
#  This class handles the player. It includes event starting determinants and
# map scrolling functions. The instance of this class is referenced by
# $game_player.
#==============================================================================

class Game_Player
  #--------------------------------------------------------------------------
  # ● Redefined method: actor
  #                     name
  #--------------------------------------------------------------------------
  define_sec_method(:actor) { $game_party.leader }
  define_sec_method(:name)  { actor.name         }        
  #--------------------------------------------------------------------------
  # ● New method: method_missing
  #--------------------------------------------------------------------------
  def method_missing(val,*a,&b)
    return actor.send(val.to_s,*a,&b) if actor.respond_to?(val.to_sym)
    text = "Undefined method #{val} for #{self.inspect}"
    raise(NoMethodError, text, caller(1))               
  end
end
  
#==============================================================================
# ** Game_Event
#------------------------------------------------------------------------------
#  This class deals with events. It handles functions including event page
#  switching via condition determinants, and running parallel process events.
#  It's used within the Game_Map class.
#==============================================================================
class Game_Event < Game_Character
  #--------------------------------------------------------------------------
  # ● Public Instance Variables
  #--------------------------------------------------------------------------
  method_defined?(:erased) || (attr_reader :erased)
  method_defined?(:id)     || (attr_reader :id)
  method_defined?(:event)  || (attr_reader :event)
  attr_accessor :loaded_event
  #--------------------------------------------------------------------------
  # ● New method: name
  # ● New method: restore
  #--------------------------------------------------------------------------
  define_sec_method(:name)    { @event.name }
  define_sec_method(:restore) { (@erased = false) || refresh }
  #--------------------------------------------------------------------------
  # ● New method: destroy
  #--------------------------------------------------------------------------
  unless method_defined?(:destroy)
    def destroy
      event = $game_map.events.delete(@id)
      if (s = $game_map.spriteset).is_a?(Spriteset_Map)
        after = s.character_sprites.select { |e| e if e.character != event }
        (delet = character_sprite) && delet.dispose
        s.character_sprites.replace(after)
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: eliminate
  #--------------------------------------------------------------------------
  unless method_defined?(:eliminate)
    def eliminate
      return destroy if self.loaded_event
      (eliminate = $game_map.eliminate_event)[(id = $game_map.map_id)] ||= []
      (eliminate[id].include?(@id) || eliminate[id].push(@id)) && destroy
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: note
  #--------------------------------------------------------------------------
  unless method_defined?(:note)
    def note
      list = @page ? @page.list.select {|l| [108,408].include?(l.code)} : []
      notes = list.collect {|l| l.parameters[0] }.join("\n")
      return notes
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: proper_page_index
  #--------------------------------------------------------------------------  
  unless method_defined?(:proper_page_index)
    def proper_page_index
      if respond_to?(:conditions_met?)
        page = respond_to?(:find_proper_page) ? find_proper_page :
               @event.pages.reverse.find {|page| conditions_met?(page)}
        (i = @event.pages.index(page)).is_a?(Integer) ? i + 1 : 0
      end
    end
  end
end

#==============================================================================
# ** Game_Party
#------------------------------------------------------------------------------
#  This class handles the party. It includes information on amount of gold
#  and items. Refer to "$game_party" for the instance of this class.
#==============================================================================
class Game_Party
  #--------------------------------------------------------------------------
  # ● Alias Listing
  #--------------------------------------------------------------------------
  alias_sec_method :drg_ce_item_number, :item_number
  #--------------------------------------------------------------------------
  # ● Redirect Listing
  #--------------------------------------------------------------------------
  redirect_method :player_pos,      '($game_player.pos)'
  redirect_method :leader,          '(members.first)'
  redirect_method :members,         '(actors)'   
  redirect_method :actors,          '(members)'  
  #--------------------------------------------------------------------------
  # ● New method: existing_actors, recover_all
  #--------------------------------------------------------------------------
  define_sec_method(:existing_actors) { members.find_all {|a| a.exist?}  }
  define_sec_method(:recover_all)     { members.each {|a| a.recover_all} }
  #--------------------------------------------------------------------------
  # ● New method: has_actors?
  #--------------------------------------------------------------------------
  unless method_defined?(:has_actors?)
    def has_actors?(*actors)
      party = @actors.collect {|s| s.is_a?(Game_Actor) ? s.id : s }
      actor =  actors.collect {|s| s.is_a?(Game_Actor) ? s.id : s }.flatten
      return party.have_all?(*actor)
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: has_any_actors?
  #--------------------------------------------------------------------------
  unless method_defined?(:has_any_actors?)
    def has_any_actors?(*actors)
      party = @actors.collect {|s| s.is_a?(Game_Actor) ? s.id : s }
      actor =  actors.collect {|s| s.is_a?(Game_Actor) ? s.id : s }.flatten
      return party.have_any?(*actor)
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: swap_previous_actor
  #--------------------------------------------------------------------------
  unless method_defined?(:swap_leader_prev)
    def swap_leader_prev(n = 1)
      n <= 0 || n.round.times { @actors.previous_item && drg_ce_refresh }
      n >= 0 || swap_leader_next(n.round.abs)
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: swap_next_actor
  #--------------------------------------------------------------------------
  unless method_defined?(:swap_leader_next)
    def swap_leader_next(n = 1)
      n <= 0 || n.round.times { @actors.next_item && drg_ce_refresh }
      n >= 0 || swap_leader_prev(n.round.abs)
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: set_leader
  #--------------------------------------------------------------------------
  unless method_defined?(:set_leader)
    def set_leader(id)
      actor = id.is_a?(Numeric) ? $game_actors[id.to_i] : id
      if actor.is_a?(Game_Actor) && has_actors?(actor.id)
        swap_leader_next until $game_party.leader.id == actor.id
        actor.id
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: drg_ce_refresh
  #--------------------------------------------------------------------------
  unless method_defined?(:drg_ce_refresh)
    def drg_ce_refresh
      return refresh if respond_to?(:refresh)
      return ($game_map.need_refresh = true) && $game_player.refresh
    end
  end
  #--------------------------------------------------------------------------
  # * Get Party Name
  #--------------------------------------------------------------------------
  unless method_defined?(:name)
    def name
      return ""           if existing_actors.size == 0
      return leader.name  if existing_actors.size == 1
      return "#{leader.name}'s Party"
    end
  end
  #--------------------------------------------------------------------------
  # * Aliased method: item_number
  #--------------------------------------------------------------------------
  def item_number(item)
    unless LiTTleDRAgo::VX
      return drg_ce_item_number(item.id)          if item.is_a?(RPG::Item)
      return weapon_number(item.id)               if item.is_a?(RPG::Weapon)
      return armor_number(item.id)                if item.is_a?(RPG::Armor)  
    else
      item = $data_items[item.to_i]               if item.is_a?(Numeric)
    end
    return skill_number(item)                     if item.is_a?(RPG::Skill)
    return drg_ce_item_number(item)
  end
  #--------------------------------------------------------------------------
  # * Redefined method: weapon_number
  #--------------------------------------------------------------------------
  unless method_defined?(:weapon_number)
    def weapon_number(weapon)
      weapon = $data_weapons[weapon.to_i] if weapon.is_a?(Numeric)
      item_number(weapon)
    end
  end
  #--------------------------------------------------------------------------
  # * Redefined method: armor_number
  #--------------------------------------------------------------------------
  unless method_defined?(:armor_number)
    def armor_number(armor)
      armor = $data_armors[armor.to_i] if armor.is_a?(Numeric)
      item_number(armor)
    end
  end
  #--------------------------------------------------------------------------
  # * New method: skill_number
  #--------------------------------------------------------------------------
  unless method_defined?(:skill_number)
    def skill_number(skill)
      skill = $data_skills[skill.to_i] if skill.is_a?(Numeric)
      s1 = actors.select {|a| a.skill_learn?(skill)    }
      s2 = actors.select {|a| a.skill_learn?(skill.id) }
      return s1.size + s2.size
    end
  end
  #--------------------------------------------------------------------------
  # * New method: gain_all_items
  #--------------------------------------------------------------------------
  def gain_all_items(ammount=1)
    (0..999).to_a.each do |s|
      next if $data_items.nil? || $data_items.name == ''
      $game_party.drg_ce_get_item($data_items,ammount)
    end
  end
  #--------------------------------------------------------------------------
  # * New method: gain_all_weapons
  #--------------------------------------------------------------------------
  def gain_all_weapons(ammount=1)
    (0..999).to_a.each do |s|
      next if $data_weapons.nil? || $data_weapons.name == ''
      drg_ce_get_item($data_weapons,ammount)
    end
  end  
  #--------------------------------------------------------------------------
  # * New method: gain_all_armors
  #--------------------------------------------------------------------------
  def gain_all_armors(ammount=1)
    (0..999).to_a.each do |s|
      next if $data_armors.nil? || $data_armors.name == ''
      drg_ce_get_item($data_armors,ammount)
    end
  end
  #--------------------------------------------------------------------------
  # * New method: drg_ce_get_item
  #--------------------------------------------------------------------------
  def drg_ce_get_item(item,ammount)
    return gain_item(item,ammount)      if LiTTleDRAgo::VX
    return gain_item(item.id,ammount)   if item.is_a?(RPG::Item)
    return gain_weapon(item.id,ammount) if item.is_a?(RPG::Weapon)
    return gain_armor(item.id,ammount)  if item.is_a?(RPG::Armor)
  end
end

#==============================================================================
# ** Game_Follower
#------------------------------------------------------------------------------
#  This class handles followers. A follower is an allied character, other than
# the front character, displayed in the party. It is referenced within the
# Game_Followers class.
#==============================================================================
class Game_Follower < Game_Character
  #--------------------------------------------------------------------------
  # * Redirect Listing
  #--------------------------------------------------------------------------
  redirect_method :name, "(actor.nil? ? '' : actor.name)"
end if defined?(Game_Follower)

#==============================================================================
# ** 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_reader :eliminate_event, 'Hash.new'
  #--------------------------------------------------------------------------
  # ● New method: name,        parent_id, base_parent_id
  #               event_list , map_events
  #--------------------------------------------------------------------------
  define_sec_method(:name)             { mapInfo[@map_id].name      }
  define_sec_method(:parent_id)        { mapInfo[@map_id].parent_id }
  define_sec_method(:base_parent_id)   { search_parent_id(mapInfo)  }
  define_sec_method(:event_list)       { events.values }
  define_sec_method(:map_events)       { @map.events   }
  define_sec_method(:screen)           { $game_screen  }
  define_sec_method(:loop_horizontal?) { false }
  define_sec_method(:loop_vertical?)   { false }
  define_sec_method(:map_child?)       { |*a|  a & child_ids == a }
  #--------------------------------------------------------------------------
  # * Aliased method: setup
  #--------------------------------------------------------------------------
  define_post_alias(:setup) do
    eliminate_event[@map_id] ||= []
    eliminate_event[@map_id].each { |s| events.delete(s) }
  end
  #--------------------------------------------------------------------------
  # * Redefined method: any_event_strarting? (for RMXP)
  #--------------------------------------------------------------------------
  unless method_defined?(:any_event_starting?)
    def any_event_starting?
      event_list.any? {|event| event.starting }
    end
  end
  #--------------------------------------------------------------------------
  # * Redefined method: interpreter (for RMXP)
  #--------------------------------------------------------------------------
  unless method_defined?(:interpreter)
    def interpreter
      return $game_system.map_interpreter if LiTTleDRAgo.scene.is_a?(Scene_Map)
      return $game_system.battle_interpreter
    end
  end
  #--------------------------------------------------------------------------
  # * Redefined method: events_xy (for RMXP)
  #--------------------------------------------------------------------------
  unless method_defined?(:events_xy)
    def events_xy(x, y)
      event_list.select {|event| event.x == x && event.y == y }
    end
  end
  #--------------------------------------------------------------------------
  # * Redefined method: events_xy_nt (for RMXP)
  #--------------------------------------------------------------------------
  unless method_defined?(:events_xy_nt)
    def events_xy_nt(x, y)
      event_list.select {|event| event.pos_nt?(x, y) }
    end
  end
  #--------------------------------------------------------------------------
  # * Redefined method: round_x, round_y (for RMXP)
  #--------------------------------------------------------------------------
  define_sec_method(:round_x) {|x| loop_horizontal? ? (x + width) % width : x }
  define_sec_method(:round_y) {|y| loop_vertical? ? (y + height) % height : y }
  #--------------------------------------------------------------------------
  # * Redefined method: x_with_direction (for RMXP)
  #--------------------------------------------------------------------------
  define_sec_method(:x_with_direction) {|x, d| x + (d==6 ? 1 : d==4 ? -1 : 0)}
  define_sec_method(:y_with_direction) {|y, d| y + (d==2 ? 1 : d==8 ? -1 : 0)}
  #--------------------------------------------------------------------------
  # * Redefined method: round_x_with_direction (for RMXP)
  #--------------------------------------------------------------------------
  unless method_defined?(:round_x_with_direction)
    def round_x_with_direction(x, d)
      round_x(x_with_direction(x, d))
    end
  end
  #--------------------------------------------------------------------------
  # * Redefined method: round_y_with_direction (for RMXP)
  #--------------------------------------------------------------------------
  unless method_defined?(:round_y_with_direction)
    def round_y_with_direction(y, d)
      round_y(y_with_direction(y, d))
    end
  end
  #--------------------------------------------------------------------------
  # * New method: x_diagonal_with_direction (for RMXP)
  #--------------------------------------------------------------------------
  unless method_defined?(:x_diagonal_with_direction)
    def x_diagonal_with_direction(x, d)
      x + ([9,6,3].include?(d) ? 1 : [7,4,1].include?(d) ? -1 : 0)
    end
  end
  #--------------------------------------------------------------------------
  # * New method: y_with_direction (for RMXP)
  #--------------------------------------------------------------------------
  unless method_defined?(:y_diagonal_with_direction)
    def y_diagonal_with_direction(y, d)
      y + ([1,2,3].include?(d) ? 1 : [7,8,9].include?(d) ? -1 : 0)
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: existing_events
  #--------------------------------------------------------------------------
  unless method_defined?(:existing_events)
    def existing_events
      event_list.select {|e| e.not.erased }
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: map_info
  #--------------------------------------------------------------------------
  unless method_defined?(:mapInfo)
    def mapInfo(ext = LiTTleDRAgo.data_default_extension)
      data = "Data/MapInfos.#{ext}"  
      @mapinfo ||= load_data(sprintf("#{data}")) rescue draise(
                   "Fail to load #{data}")
      return @mapinfo
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: search_parent_id
  #--------------------------------------------------------------------------
  unless method_defined?(:search_parent_id)
    def search_parent_id(mapInfo, id = @map_id, ancestor = 0)
      m_id = id
      loop do
        _m_id = mapInfo[m_id]
        p_id = _m_id.respond_to?(:parent_id) ? _m_id.parent_id : nil
        return p_id if p_id == nil
        return m_id if p_id == ancestor
        m_id = p_id
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: base_map_name
  #--------------------------------------------------------------------------
  unless method_defined?(:base_map_name)
    def base_map_name
      map = mapInfo[search_parent_id(mapInfo)]
      name = map.respond_to?(:name) ? map.name : ''
      return name
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: child_ids
  #--------------------------------------------------------------------------
  unless method_defined?(:child_ids)
    def child_ids
      mapInfo.keys.select {|map_id| mapInfo[map_id].parent_id == @map_id }
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: descendant?
  #--------------------------------------------------------------------------
  unless method_defined?(:map_descendant?)
    def map_descendant?(*a)
      a.all? {|map_id| search_parent_id(mapInfo, map_id, @map_id)}
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: load_event
  #--------------------------------------------------------------------------
  unless method_defined?(:load_event)
    def load_event(*a)
      case a.size
      when 5, 4 then (mapid, eventid, x, y = *a)
      when 3    then (mapid = @map_id) && (eventid, x, y = *a)
      when 2    then (mapid, y = @map_id, 0) && (eventid, x = *a)
      when 1    then (mapid, x, y = @map_id, 0,0) && (eventid = a.first)
      when 0    then return nil
      end
      map = load_map_data(mapid)
      event = map.events.values.detect { |event| event.id == eventid }
      unless event.nil?
        (a = a.at(4)) && (b = [a].flatten) && event.pages.reject! do |s|
          c = b.map {|i| i.is_a?(Range) ? i.to_a : i }
          c.flatten.not.include?(event.pages.index(s)+1)
        end
        return nil if event.pages.empty?
        c,r = [Array,Range], []
        c.include?(x.class) && (x = x.to_a.map{|s|s.is_a?(Range) ? s.to_a : s})
        c.include?(y.class) && (y = y.to_a.map{|s|s.is_a?(Range) ? s.to_a : s})
        [x].flatten.dproduct([y].flatten).each do |x1,y1|
          event.instance_variable_set(:@id,(id = next_key_events))
          r.push(@events[id] = e = Game_Event.new(@map_id, event.clone))
          e.loaded_event = true
          e.moveto(x1,y1)
        end
        a = r.size == 1 ? r.first : r
        if r && (s = spriteset).is_a?(Spriteset_Map)
          sc = s.character_sprites
          after  = sc.select { |e| e if e.character != $game_player }
          player = s.sprite_player
          sc.replace(after)
          r.each {|e| sc.push(Sprite_Character.new(s.viewport1, e)) }
          sc.push(player)
        end
        return a
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: call_event
  #--------------------------------------------------------------------------
  unless method_defined?(:call_event)
    def call_event(*a)
      case a.size
      when 3 then (mapid, eventid, page_id = *a)
      when 2 then (page_id = -1) && (mapid, eventid = *a)
      when 1 then (mapid, page_id = @map_id, -1) && (eventid = a.first)
      when 0 then return nil
      end
      map = load_map_data(mapid)
      event = map.events.values.detect { |event| event.id == eventid }
      unless event.nil?
        if page_id == -1 && event.respond_to?(:conditions_met?)
          pages = event.pages.reverse.find {|page| event.conditions_met?(page)}
        else
          pages = event.pages[[page_id,1].max-1]
        end
        klass = LiTTleDRAgo::VX ? Game_Interpreter : Interpreter
        child = klass.new(interpreter.instance_variable_get(:@depth) + 1)
        child.setup(pages.list, interpreter.same_map? ? event.id : 0)
        if LiTTleDRAgo::VXA
          child.run rescue FiberError
        else
          interpreter.instance_variable_set(:@child_interpreter, child)
        end
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: load_map_data
  #--------------------------------------------------------------------------
  unless method_defined?(:load_map_data)
    def load_map_data(mapid, ext = LiTTleDRAgo.data_default_extension)
      (map = sprintf("Data/Map%03d.#{ext}", mapid)) && load_data(map)
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: increment_key_events
  #--------------------------------------------------------------------------
  unless method_defined?(:next_key_events)
    def next_key_events
      (@events.keys.max || 0) + 1
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: unused_key_events
  #--------------------------------------------------------------------------
  unless method_defined?(:unused_key_events)
    def unused_key_events(start = 1)
      start = [start, next_key_events].min
      (start..next_key_events).detect {|i| @events.keys.not.include?(i)}
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: spriteset
  #--------------------------------------------------------------------------
  unless method_defined?(:spriteset)
    def spriteset
      LiTTleDRAgo.scene.instance_variable_get(:@spriteset)
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: character_sprite
  #--------------------------------------------------------------------------
  unless method_defined?(:character_sprite)
    def character_sprite(id = 0)
      return unless spriteset.is_a?(Spriteset_Map)
      id = id.is_a?(Game_Character) ? id : id == 0 ? $game_player : events[id]
      spriteset.find_character(id)
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: picture_sprite
  #--------------------------------------------------------------------------
  unless method_defined?(:picture_sprite)
    def picture_sprite(id = nil)
      return unless spriteset.is_a?(Spriteset_Map)
      spriteset.update_pictures if spriteset.respond_to?(:update_pictures)
      result = spriteset.instance_variable_get(:@picture_sprites)
      id.nil? ? result : result[id]
    end
  end
end
#==============================================================================
# ■ RPG::Cache
#------------------------------------------------------------------------------
#
#==============================================================================
ModCache = LiTTleDRAgo.cache
class << ModCache
  #-----------------------------------------------------------------------
  # ● New method: self.draw_text
  #-----------------------------------------------------------------------
  unless method_defined?(:draw_text)
    def draw_text(
            width, height, text,
            font = Font.default_name,
            size = Font.default_size,
            bold = Font.default_bold,
            italic = Font.default_italic,
            color = Font.default_color,
            edging = false
          )
      cache_index = "text_" + width.to_s + height.to_s + text
      font_text = ""
      font.size.times do |i|
        font_text += font.to_s
      end
      cache_index += font_text + size.to_s + bold.to_s + italic.to_s
      cache_index += "#{color.red}#{color.blue}#{color.green}#{color.alpha}"
      @cache ||= {}
      if @cache[cache_index].nil? or @cache[cache_index].disposed?
        bitmap = Bitmap.new(width, height)
        bitmap.font.name = font
        bitmap.font.size = size
        bitmap.font.bold = bold
        bitmap.font.italic = italic
        bitmap.font.color = color
        if edging
          bitmap.draw_edging_text(0, 0, width, height, text, 0)
        else
          bitmap.draw_text(0, 0, width, height, text, 0)
        end
        @cache[cache_index] = bitmap
      end
      return @cache[cache_index]
    end
  end
  #-----------------------------------------------------------------------
  # ● New method: self.method_missing
  #-----------------------------------------------------------------------
  def method_missing(val,*a,&b)
    if a.at(0).is_a?(String) && a.size <= 2
      return load_bitmap("Graphics/#{val}/",*a,&b)
    end
    modified = [:invert,:brighten,:darken,:grayscale,:pixelate,:frost]
    if modified.include?(a.first) && a.at(1).is_a?(String) && a.size <= 3
      method = a.shift
      filename = a.join + "-#{method}"
      unless drago_bitmap_exist?("Graphics/#{val}",filename)
        bitmap = load_bitmap("Graphics/#{val}/",*a,&b)
        drago_set_bitmap(bitmap.send(method),"Graphics/#{val}",filename)
      end
      return drago_get_bitmap("Graphics/#{val}",filename)
    end
    text = "Undefined method #{val} for #{self.inspect}"
    raise(NoMethodError, text, caller(1))      
  end
  #-----------------------------------------------------------------------
  # ● New method: drago_get_bitmap
  #-----------------------------------------------------------------------
  def drago_get_bitmap(folder_name, filename = '', hue = 0)
    return empty_bitmap if filename.not.is_a?(String) || filename.empty?
    path = LiTTleDRAgo::APPPATHDRAGO + "#{folder_name}/"
    path = path.gsub("\\","/").gsub("//","/")
    last = filename.split('.').last
    filename.gsub!(".png","") if last.is_a?(String) && last[/png/i]
    load_bitmap_no_rescue(path.downcase,filename.downcase,hue)
  end
  #-----------------------------------------------------------------------
  # ● New method: drago_set_bitmap
  #-----------------------------------------------------------------------
  def drago_set_bitmap(bitmap, folder_name = '', filename = 'bitmap')
    path = LiTTleDRAgo::APPPATHDRAGO + "#{folder_name}/"
    path = path.gsub("\\","/").gsub("//","/")
    last = filename.split('.').last
    filename += '.png' unless last.is_a?(String) && last[/png/i]
    Dir.make_dir(path) unless FileTest.directory?(path)
    bitmap.export(path + filename)
    drago_get_bitmap(folder_name, filename)
  end
  #-----------------------------------------------------------------------
  # ● New method: drago_bitmap_exist?
  #-----------------------------------------------------------------------
  def drago_bitmap_exist?(folder_name, filename)
    return false if filename.not.is_a?(String) || filename.empty?
    path = LiTTleDRAgo::APPPATHDRAGO + "#{folder_name}/"
    path = path.gsub("\\","/").gsub("//","/")
    last = filename.split('.').last
    filename += '.png' unless last.is_a?(String) && last[/png/i]
    FileTest.file?(path + filename)
  end
  #--------------------------------------------------------------------------
  # * Load Bitmap
  #--------------------------------------------------------------------------
  define_sec_method(:load_bitmap_no_rescue) do |folder, file, *a|
    @cache ||= {}
    if file.empty?
      empty_bitmap
    elsif (hue = a.first).is_a?(Numeric) && hue != 0
      hue_changed_bitmap(folder + file, hue.round)
    else
      normal_bitmap(folder + file)
    end
  end
  #--------------------------------------------------------------------------
  # * Create Empty Bitmap
  #--------------------------------------------------------------------------
  define_sec_method(:empty_bitmap) { Bitmap.new(32, 32)}
  #--------------------------------------------------------------------------
  # * Create/Get Normal Bitmap
  #--------------------------------------------------------------------------
  define_sec_method(:normal_bitmap) do |path|
    @cache[path] = Bitmap.new(path) unless include?(path)
    @cache[path]
  end
  #--------------------------------------------------------------------------
  # * Create/Get Hue-Changed Bitmap
  #--------------------------------------------------------------------------
  define_sec_method(:hue_changed_bitmap) do |path, hue|
    key = [path, hue]
    unless include?(key)
      @cache[key] = normal_bitmap(path).clone
      @cache[key].hue_change(hue)
    end
    @cache[key]
  end
  #--------------------------------------------------------------------------
  # * Check Cache Existence
  #--------------------------------------------------------------------------
  def include?(key)
    @cache[key] && @cache[key].not.disposed?
  end
end
#==============================================================================
# ** Window_Base
#------------------------------------------------------------------------------
#  This class is for all in-game windows.
#==============================================================================

class Window_Base < Window
  #--------------------------------------------------------------------------
  # * Redirect Listing
  #--------------------------------------------------------------------------
  redirect_method :draw_text,    'contents.draw_text'
  redirect_method :text_size,    'contents.text_size'
  redirect_method :change_color, 'contents.change_color'
  redirect_method :draw_picture, 'contents.draw_picture'
  redirect_method :draw_icon,    'contents.draw_icon'
  redirect_method :draw_battler, 'contents.draw_battler'
  #--------------------------------------------------------------------------
  # * Redefined method: line_height, translucent_alpha
  # * New method:       show, hide, activate, deactivate
  #--------------------------------------------------------------------------
  define_sec_method(:line_height)       { 32 }
  define_sec_method(:translucent_alpha) { 160 }
  define_sec_method(:show)              { self.visible = true  }
  define_sec_method(:hide)              { self.visible = false }
  define_sec_method(:activate)          { self.active  = true  }
  define_sec_method(:deactivate)        { self.active  = false }
  #--------------------------------------------------------------------------
  # * New method: center_window
  #--------------------------------------------------------------------------
  unless method_defined?(:center_window)
    def center_window
      self.x = Graphics.width/2  - self.width/2
      self.y = Graphics.height/2 - self.height/2
    end
  end
  #--------------------------------------------------------------------------
  # * Redefined method: disabled_color
  #--------------------------------------------------------------------------
  unless method_defined?(:disabled_color)
    def disabled_color     
      color = normal_color
      color.alpha = 128
      return color
    end
  end
  #--------------------------------------------------------------------------
  # * Redefined method: draw_text_ex
  #--------------------------------------------------------------------------
  unless method_defined?(:draw_text_ex)
    def draw_text_ex(x, y, text)
      reset_font_settings
      text = convert_escape_characters(text)
      pos = {:x => x, :y => y, :new_x => x, :height => calc_line_height(text)}
      process_character(text.slice!(0, 1), text, pos) until text.empty?
    end
  end
  #--------------------------------------------------------------------------
  # * Redefined method: reset_font_settings
  #--------------------------------------------------------------------------
  unless method_defined?(:reset_font_settings)
    def reset_font_settings
      change_color(normal_color)
      contents.font.size = Font.default_size
      contents.font.bold = Font.default_bold
      contents.font.italic = Font.default_italic
    end
  end
  #--------------------------------------------------------------------------
  # * Redefined method: convert_escape_characters
  #--------------------------------------------------------------------------
  unless method_defined?(:convert_escape_characters)
    def convert_escape_characters(text)
      result = text.to_s.clone
      result.gsub!(/\\/)            { "\e" }
      result.gsub!(/\e\e/)          { "\\" }
      result.gsub!(/\eV\[(\d+)\]/i) { $game_variables[$1.to_i]   }
      result.gsub!(/\eN\[(\d+)\]/i) { actor_name($1.to_i)        }
      result.gsub!(/\eP\[(\d+)\]/i) { party_member_name($1.to_i) }
      result.gsub!(/\eG/i)          { currency_unit }
      result
    end
  end
  #--------------------------------------------------------------------------
  # * Redefined method: actor_name
  #--------------------------------------------------------------------------
  unless method_defined?(:actor_name)
    def actor_name(n)
      actor = n >= 1 ? $game_actors[n] : nil
      actor ? actor.name : ""
    end
  end
  #--------------------------------------------------------------------------
  # * Redefined method: party_member_name
  #--------------------------------------------------------------------------
  unless method_defined?(:party_member_name)
    def party_member_name(n)
      actor = n >= 1 ? $game_party.instance_variable_get(:@actors)[n - 1] : nil
      actor ? actor.name : ""
    end
  end
  #--------------------------------------------------------------------------
  # * Redefined method: process_character
  #--------------------------------------------------------------------------
  unless method_defined?(:process_character)
    def process_character(c, text, pos)
      case c
      when "\n"   # New line
        process_new_line(text, pos)
      when "\f"   # New page
        process_new_page(text, pos)
      when "\e"   # Control character
        process_escape_character(obtain_escape_code(text), text, pos)
      else        # Normal character
        process_normal_character(c, pos)
      end
    end
  end
  #--------------------------------------------------------------------------
  # * Redefined method: process_normal_character
  #--------------------------------------------------------------------------
  unless method_defined?(:process_normal_character)
    def process_normal_character(c, pos)
      text_width = text_size(c).width
      draw_text(pos[:x], pos[:y], text_width * 2, pos[:height], c)
      pos[:x] += text_width
    end
  end
  #--------------------------------------------------------------------------
  # * Redefined method: process_new_line
  #--------------------------------------------------------------------------
  unless method_defined?(:process_new_line)
    def process_new_line(text, pos)
      pos[:x] = pos[:new_x]
      pos[:y] += pos[:height]
      pos[:height] = calc_line_height(text)
    end
  end
  #--------------------------------------------------------------------------
  # * Redefined method: process_new_page
  #--------------------------------------------------------------------------
  unless method_defined?(:process_new_page)
    def process_new_page(text, pos)
    end
  end
  #--------------------------------------------------------------------------
  # * Redefined method: obtain_escape_code
  #--------------------------------------------------------------------------
  unless method_defined?(:obtain_escape_code)
    def obtain_escape_code(text)
      text.slice!(/^[\$\.\|\^!><\{\}\\]|^[\/\w+\/]+/i)
    end
  end
  #--------------------------------------------------------------------------
  # * Redefined method: obtain_escape_param
  #--------------------------------------------------------------------------
  unless method_defined?(:obtain_escape_param)
    def obtain_escape_param(text)
      text.slice!(/^\[\d+\]/)[/\d+/].to_i rescue 0
    end
  end
  #--------------------------------------------------------------------------
  # * Redefined method: process_escape_character
  #--------------------------------------------------------------------------
  unless method_defined?(:process_escape_character)
    def process_escape_character(code, text, pos)
      case code.upcase
      when 'C' then change_color(text_color(obtain_escape_param(text)))
      when 'I' then process_draw_icon(obtain_escape_code(text), pos)
      when '{' then make_font_bigger
      when '}' then make_font_smaller
      end
    end
  end
  #--------------------------------------------------------------------------
  # * Redefined method: process_draw_icon
  #--------------------------------------------------------------------------
  unless method_defined?(:process_draw_icon)
    def process_draw_icon(icon_index, pos)
      icon_index = icon_index.to_i if icon_index.to_i.to_s == icon_index
      draw_icon(icon_index, pos[:x], pos[:y])
      pos[:x] += 24
    end
  end
  #--------------------------------------------------------------------------
  # * Redefined method: make_font_bigger
  #--------------------------------------------------------------------------
  unless method_defined?(:make_font_bigger)
    def make_font_bigger
      contents.font.size += 8 if contents.font.size <= 64
    end
  end
  #--------------------------------------------------------------------------
  # * Redefined method: make_font_smaller
  #--------------------------------------------------------------------------
  unless method_defined?(:make_font_smaller)
    def make_font_smaller
      contents.font.size -= 8 if contents.font.size >= 16
    end
  end
  #--------------------------------------------------------------------------
  # * Redefined method: calc_line_height
  #--------------------------------------------------------------------------
  unless method_defined?(:calc_line_height)
    def calc_line_height(text, restore_font_size = true)
      result = [line_height, contents.font.size].max
      last_font_size = contents.font.size
      text.slice(/^.*$/).scan(/\e[\{\}]/).each do |esc|
        make_font_bigger  if esc == "\e{"
        make_font_smaller if esc == "\e}"
        result = [result, contents.font.size].max
      end
      contents.font.size = last_font_size if restore_font_size
      result
    end
  end
  #--------------------------------------------------------------------------
  # * New method: currency_unit
  #--------------------------------------------------------------------------
  unless method_defined?(:currency_unit)
    def currency_unit
      gold = $data_system.words.gold
      return gold
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: draw_map_name
  #--------------------------------------------------------------------------
  unless method_defined?(:draw_map_name)
    def draw_map_name(x, y, width, height)
      map_id  = $game_map.map_id
      mapInfo = $game_map.mapInfo
      draw_text(x, y, width, height, mapInfo[map_id].name.to_s)
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: draw_enter_text
  #--------------------------------------------------------------------------
  unless method_defined?(:draw_enter_text)
    def draw_enter_text(x, y, width, height, text)
      info_box = text.split(/\n/)
      info_box.size.times do |i|
        draw_text( x, y + i * line_height, width, line_height, info_box)
        break if (y + i * line_height) > (self.height - line_height)
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: draw_picture_number
  #--------------------------------------------------------------------------
  unless method_defined?(:draw_picture_number)
    def draw_picture_number(x, y, value, file_name,align = 0,
                  space = 0, frame_max = 1,frame_index = 0)     
      number_image = LiTTleDRAgo.cache.windowskin(file_name)
      frame_max = [frame_max, 1].max
      frame_index = frame_max - 1 if frame_index > frame_max - 1
      align = [[align,2].min,0].max
      cw = number_image.width / 10
      ch = number_image.height / frame_max
      h = ch * frame_index
      number = value.abs.to_s.split(//)
      case align
      when 0 then plus_x = (-cw + space) * number.size
      when 1 then plus_x = ((-cw + space) * number.size) / 2
      when 2 then plus_x = 0
      end
      for r in 0..number.size - 1      
        rect = Rect.new(cw * number[r].to_i, h, cw, ch)
        contents.blt(plus_x + x + ((cw - space) * r), y , number_image, rect)
      end     
      number_image.dispose
    end     
  end
end

#==============================================================================
# ■ Bitmap
#------------------------------------------------------------------------------
#
#==============================================================================
class Bitmap  
  #----------------------------------------------------------------------------
  # ● Constant
  #----------------------------------------------------------------------------
  RtlMoveMemory_pi = LiTTleDRAgo.rtlmemory_pi
  RtlMoveMemory_ip = LiTTleDRAgo.rtlmemory_ip
  Blur_Setting     = "{ 'offset' => 2, 'spacing' => 1, 'opacity' => 255 }"
  #----------------------------------------------------------------------------
  # ● Public Instance Variables
  #----------------------------------------------------------------------------
  attr_sec_accessor :blur_settings,  Blur_Setting
  #----------------------------------------------------------------------------
  # ● Redirect Listing
  #----------------------------------------------------------------------------
  redirect_method :change_hue,          :hue_change
  #-------------------------------------------------------------------------
  # ● Define Secondary Listing
  #-------------------------------------------------------------------------
  define_sec_method(:full_fill) { |color|  fill_rect(rect, color) }
  #----------------------------------------------------------------------------
  # ● Alias Listing
  #----------------------------------------------------------------------------
  alias_sec_method :invert!,            :reversing!  
  alias_sec_method :grayscale!,         :gray_scale!
  alias_sec_method :frost,              :diffusion   
  alias_sec_method :frost!,             :diffusion!  
  alias_sec_method :drg_ce_stretch_blt, :stretch_blt
  alias_method     :drg_bitmap_load,    :initialize
  #--------------------------------------------------------------------------
  # * Object Initialization
  #----------------------------------------------------------------------------
  def initialize(*args)
    if (a = args.flatten).size == 4 && a.all? {|s| s.is_a?(Table)}
      bitmap = BitmapDump.read_bitmap_data(*a)
      drg_bitmap_load(bitmap.width,bitmap.height)
      return blt(0,0,bitmap,rect) && bitmap.dispose
    end
    drg_bitmap_load(*args)
  end
  #----------------------------------------------------------------------------
  # ● New method: address
  #----------------------------------------------------------------------------
  unless method_defined?(:address)
    def address
      @address ||= (  RtlMoveMemory_pi.call(a="\0"*4, __id__*2+16, 4)
                      RtlMoveMemory_pi.call(a, a.unpack('L')[0]+8, 4)
                      RtlMoveMemory_pi.call(a, a.unpack('L')[0]+16, 4)
                      a.unpack('L')[0]    )
    end
  end
  #----------------------------------------------------------------------------
  # ● New method: export
  #----------------------------------------------------------------------------
  unless method_defined?(:export)
    def export(filename)
      file = File.open(filename, 'wb')
        size, vxace = width * height * 4, LiTTleDRAgo::RGSS3
        case format = File.extname(filename)
        when '.bmp'
          data = String.new
          RtlMoveMemory_pi.call(empty_rString_struct="\0"*16,data.__id__*2,16)
          flags = vxace ? 5267461 : 8199
          klass = empty_rString_struct.unpack('@4L')[0]
          pack  = [flags,klass,size,address].pack('L4')
          weiss = [size+54,0,54,40,width,height,1,32,0,size,0,0,0,0]
          RtlMoveMemory_ip.call(data.__id__*2, pack, 16)
          file.write("BM#{weiss.pack('L6S2L6')}")
          file.write(data)
          RtlMoveMemory_ip.call(data.__id__*2, empty_rString_struct, 16)
        when '.png'
          write_chunk = Proc.new do |chunk|
            file.write([(vxace ? chunk.bytesize : chunk.size)-4].pack('N'))
            file.write(chunk)
            file.write([Zlib.crc32(chunk)].pack('N'))
          end
          null_char, w4, i, byte = "\0", width*4, 0, (t_Fx = 0)
          RtlMoveMemory_pi.call(data=null_char*size, address, size)
          if vxace
            data.force_encoding('ASCII-8BIT')
            (0).step(size-4, 4) do |i|
              Graphics.update if (t_Fx += 1) % 10000 == 0
              byte = data.getbyte(i)
              data.setbyte(i, data.getbyte(i+=2))
              data.setbyte(i, byte)
            end
          else
            (0).step(size-4, 4) do |i|
              Graphics.update if (t_Fx += 1) % 10000 == 0
              data[i,3] = data[i,3].reverse!
            end
          end
          deflate = Zlib::Deflate.new(9)
            (size-w4).step(0, -w4) {|i| deflate << null_char << data[i,w4]}
            file.write("\211PNG\r\n\32\n")
            write_chunk.call("IHDR#{[width,height,8,6,0,0,0].pack('N2C5')}")
            write_chunk.call("IDAT#{deflate.finish}")
            write_chunk.call('IEND')
          deflate.close
        when ''
          script_report("Error: Export Bitmap Failed\n"+
              "Extension '#{filename}' is missing.")
        else         
          script_report("Error: Export Bitmap Failed\n"+
               "Extension '#{format}' is not supported.")
        end
      file.close
    end
  end
  #----------------------------------------------------------------------------
  # ● New method: blt_cache
  #----------------------------------------------------------------------------
  unless method_defined?(:blt_cache)
    def blt_cache(x, y, width, height, text, align, edging)
      cache_bitmap = LiTTleDRAgo.cache.draw_text(
          width, height, text, self.font.name, self.font.size,
          self.font.bold, self.font.italic, self.font.color, edging
      )
      x_plus = uncache_align_exe(width, text, align)
      blt(x + x_plus , y , cache_bitmap, Rect.new(0, 0, width, height))
    end
  end
  #----------------------------------------------------------------------------
  # ● New method: uncache_align_exe
  #----------------------------------------------------------------------------
  unless method_defined?(:uncache_align_exe)
    def uncache_align_exe(width, text, align)
      recter = self.text_size(text)
      case align
      when 0 then x_index = 0
      when 1 then x_index = (width / 2) - recter.width / 2
      when 2 then x_index = width - recter.width
      else
        raise "Text Cache : align is wrong"
      end
      return x_index
    end
  end
  #----------------------------------------------------------------------------
  # ● New method: draw_cache_text
  #----------------------------------------------------------------------------
  unless method_defined?(:draw_cache_text)
    def draw_cache_text(x, y, width, height, text, align = 0)
      blt_cache(x, y, width, height, text, align, false)
    end
  end
  #----------------------------------------------------------------------------
  # ● New method: draw_edging_cache_text
  #----------------------------------------------------------------------------
  unless method_defined?(:draw_edging_cache_text)
    def draw_edging_cache_text(x, y, width, height, text, align = 0)
      blt_cache(x, y, width, height, text, align, true)
    end
  end
  #----------------------------------------------------------------------------
  # ● New method: draw_easy_cache_text
  #----------------------------------------------------------------------------
  unless method_defined?(:draw_easy_cache_text)
    def draw_easy_cache_text(x, y, text)
      t_rect = text_size(text)
      blt_cache(x, y, t_rect.width, t_rect.height, text, 0, false)
    end
  end
  #----------------------------------------------------------------------------
  # ● New method: draw_easy_edging_cache_text
  #----------------------------------------------------------------------------
  unless method_defined?(:draw_easy_edging_cache_text)
    def draw_easy_edging_cache_text(x, y, text)
      t_rect = text_size(text)
      blt_cache(x, y, t_rect.width, t_rect.height, text, 0, true)
    end
  end
  #--------------------------------------------------------------------------
  # * New method: change_color
  #--------------------------------------------------------------------------
  unless method_defined?(:change_color)
    def change_color(color, enabled = true)
      font.color = color
      font.color.alpha = translucent_alpha unless enabled
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: draw_picture
  #--------------------------------------------------------------------------
  unless method_defined?(:draw_picture)
    def draw_picture(file_name, x, y, opacity = 255)
      bitmap = LiTTleDRAgo.cache.picture(file_name)
      cw = bitmap.width
      ch = bitmap.height
      src_rect = Rect.new(0, 0, cw, ch)
      blt(x, y, bitmap, src_rect, opacity)
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: draw_icon
  #--------------------------------------------------------------------------
  unless method_defined?(:draw_icon)
    def draw_icon(file_name, x, y, enabled = true)
      if file_name.is_a?(Numeric)
        bitmap = LiTTleDRAgo.cache.system("Iconset")
        src_rect = Rect.new(file_name % 16 * 24, file_name / 16 * 24, 24, 24)
        blt(x, y, bitmap, src_rect, enabled ? 255 : 160)
      elsif file_name.is_a?(String)
        bitmap = LiTTleDRAgo.cache.icon(file_name)
        src_rect = Rect.new(0, 0, 24, 24)
        blt(x, y, bitmap, bitmap.rect, enabled ? 255 : 160)
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: draw_battler
  #--------------------------------------------------------------------------
  unless method_defined?(:draw_battler)
    def draw_battler(file_name, x, y, hue = 0, enabled = true)
      bitmap = LiTTleDRAgo.cache.battler(file_name, hue)
      cw = bitmap.width
      ch = bitmap.height
      src_rect = Rect.new(0, 0, cw, ch)
      blt(x, y, bitmap, src_rect, enabled ? 255 : 160)
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: draw_bar
  #--------------------------------------------------------------------------
  unless method_defined?(:draw_bar)
    def draw_bar(x, y, current, file)
      bitmap = LiTTleDRAgo.cache.picture(file)
      cw = bitmap.width * current / 100
      ch = bitmap.height
      src_rect = Rect.new(0, 0, cw, ch)
      blt(x, y, bitmap, src_rect)
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: draw_edging_text
  #--------------------------------------------------------------------------
  unless method_defined?(:draw_edging_text)
    def draw_edging_text(x, y, width, height, text, align=0)
      old_color = font.color.dup
      font.color = Color.new(0, 0, 0)
      draw_text(x-1, y-1, width, height, text, align)
      draw_text(x-1, y+1, width, height, text, align)
      draw_text(x+1, y-1, width, height, text, align)
      draw_text(x+1, y+1, width, height, text, align)
      font.color = old_color
      draw_text(x, y, width, height, text, align)
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: draw_enter_text
  #--------------------------------------------------------------------------
  unless method_defined?(:draw_enter_text)
    def draw_enter_text(x, y, width, height, text, align=0)
      rect = text_size(text)
      info_box = text.split(/\n/)
      info_box.size.times do |i|
        draw_text( x, y+i*rect.height, width, height, info_box, align)
        break if (y+i*rect.height) > self.height
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: draw_enter_edging_text
  #--------------------------------------------------------------------------
  unless method_defined?(:draw_enter_edging_text)
    def draw_enter_edging_text(x, y, width, height, text, align=0)
      rect = text_size(text)
      info_box = text.split(/\n/)
      info_box.size.times do |i|
        draw_edging_text( x, y+i*rect.height,width,height,info_box,align)
        break if (y+i*rect.height) > self.height
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: draw_easy_text
  #--------------------------------------------------------------------------
  unless method_defined?(:draw_easy_text)
    def draw_easy_text(x, y, text)
      rect = text_size(text)
      draw_text(x, y, rect.width + rect.height/2, rect.height, text)
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: draw_auto_text
  #--------------------------------------------------------------------------
  unless method_defined?(:draw_auto_text)
    def draw_auto_text(x, y, width, height, text)
      ini_x = 0
      law = 0
      text_box = []
      text_box[law] = []
      otxto = text.split(//)
      otxto.size.times do |i|
        text_rect = text_size(otxto)
        if (x + ini_x + text_rect.width) < width
          ini_x += text_rect.width
        else
          law += 1
          ini_x = text_rect.width
          text_box[law] = []
        end
        text_box[law].push(otxto)
      end
      for l in 0..law
        ini_x = 0
        text_box[l].size.times do |i|
          rect = text_size(text_box[l])
          draw_text(x + ini_x, y+l*height, rect.width, height, text_box[l])
          ini_x += rect.width
        end
      end
    end
  end
  #-------------------------------------------------------------------------
  # ● New method: erase
  #-------------------------------------------------------------------------
  unless method_defined?(:erase)
    def erase(*a)
      rect = nil
      if a.at(0).is_a?(Rect) then rect = a.at(0)
      elsif a.size == 4 then rect = Rect.new(*a)
      elsif a.size == 0 then rect = Rect.new(0,0,width,height)
      end
      fill_rect(rect.x, rect.y, rect.width, rect.height, Color.erase) if rect
    end
  end
  #-------------------------------------------------------------------------
  # ● New method: stretch
  #-------------------------------------------------------------------------
  unless method_defined?(:stretch)
    def stretch(width, height)
      dummy = Bitmap.new(width, height)
      dummy.stretch_blt(*[dummy.rect, self, self.rect])
      dummy
    end
  end
  #-------------------------------------------------------------------------
  # ● New method: crop
  #-------------------------------------------------------------------------
  unless method_defined?(:crop)
    def crop(*a)
      return unless a.size == 1 or a.size == 4
      rect = rect.at(0)   if a.size == 1 && a.at(0).is_a?(Rect)
      rect = Rect.new(*a) if a.size == 4
      cropped = Bitmap.new([rect.width,width-rect.x].min,
                           [rect.height,height-rect.y].min)
      cropped.blt(0,0,self,rect)
      cropped
    end
  end
  #-------------------------------------------------------------------------
  # ● Aliased method: stretch_blt
  #-------------------------------------------------------------------------
  def stretch_blt(*a)
    if respond_to?(:stretch_blend_blt)
      a = [a[0..2],0,1,a.at(3)||255].flatten
      stretch_blend_blt(*a)
    else
      drg_ce_stretch_blt(*a)
    end
  end
  #-------------------------------------------------------------------------
  # ● Aliased method: hue_change
  #-------------------------------------------------------------------------
  define_post_alias(:hue_change) { self }
  #--------------------------------------------------------------------------
  # ● New method: invert, etc
  #--------------------------------------------------------------------------
  [:invert, :brighten, :darken, :grayscale, :pixelate, :frost, :flip_horizontal,
   :flip_vertical, :rotate90, :rotate180, :rotate270].each do |meth|
    define_sec_method(meth) do |*args|
      bitmap = self.clone
      bitmap.send(:"#{meth}!",*args)
      return bitmap
    end
  end
  #-------------------------------------------------------------------------
  # ● New method: flip_horizontal!
  #-------------------------------------------------------------------------
  define_sec_method(:flip_horizontal!) do
    flipped = Bitmap.new(width, height)
    fliprect = Rect.new(width,0,-width,height)
    flipped.blt(0,0, self,fliprect)
    (clear || 0) && blt(0,0,flipped,rect)
    flipped.dispose
  end
  #-------------------------------------------------------------------------
  # ● New method: flip_vertical!
  #-------------------------------------------------------------------------
  define_sec_method(:flip_vertical!) do
    flipped = Bitmap.new(width, height)
    fliprect = Rect.new(0,height,width,-height)
    flipped.blt(0,0, self,fliprect)
    (clear || 0) && blt(0,0,flipped,rect)
    flipped.dispose
  end
  #-------------------------------------------------------------------------
  # ● New method: rotate90! (clockwise)
  #-------------------------------------------------------------------------
  define_sec_method(:rotate90!) do
    copy = self.clone
    (t_Fx = width).times do |i|
      height.times do |j|
        Graphics.update if (t_Fx += 1) % 10000 == 0
        a = (clockwise = true) ? [width - i - 1, j] : [i, height - j - 1]
        self.set_pixel(a[0],a[1], copy.get_pixel(j, i))
      end
    end
    copy.dispose
  end
  #-------------------------------------------------------------------------
  # ● New method: rotate180!
  #-------------------------------------------------------------------------
  define_sec_method(:rotate180!) do
    flip_vertical!
    flip_horizontal!
  end
  #-------------------------------------------------------------------------
  # ● New method: rotate270!
  #-------------------------------------------------------------------------
  define_sec_method(:rotate270!) do
    rotate90!
    rotate180!
  end  
  #----------------------------------------------------------------------------
  # ● New method: invert!
  #----------------------------------------------------------------------------
  unless method_defined?(:invert!)
    def invert!
      (t_Fx = width).times do |i|
        height.times do |j|
           color = get_pixel(i, j)
           Graphics.update if (t_Fx += 1) % 10000 == 0
           set_pixel(i, j, color.invert) if color.alpha > 0
         end
      end
    end
  end
  #--------------------------------------------------------------------------
  # * New method: brighten!
  #--------------------------------------------------------------------------
  unless method_defined?(:brighten!)
    def brighten!(amount = 10)
      (t_Fx = width).times do |w|
        height.times do |h|
          color = get_pixel(w, h)
          Graphics.update if (t_Fx += 1) % 10000 == 0
          set_pixel(w, h, Color.new([color.red + amount, 255].min,
                                    [color.green + amount, 255].min,
                                    [color.blue + amount, 255].min,
                                    color.alpha)) if color.alpha > 0
        end
      end
    end
  end
  #--------------------------------------------------------------------------
  # * New method: darken!
  #--------------------------------------------------------------------------
  unless method_defined?(:darken!)
    def darken!(amount = 10)
      (t_Fx = width).times do |w|
        height.times do |h|
          color = get_pixel(w, h)
          Graphics.update if (t_Fx += 1) % 10000 == 0
          set_pixel(w, h, Color.new([color.red - amount, 0].max,
                                    [color.green - amount, 0].max,
                                    [color.blue - amount, 0].max,
                                    color.alpha)) if color.alpha > 0
        end
      end
    end
  end
  #--------------------------------------------------------------------------
  # * New method: grayscale!
  # NOTE: calling this method repeatedly has no effect on the bitmap, but will
  #       still waste processing power. Do not call it repeatedly.
  #--------------------------------------------------------------------------
  unless method_defined?(:grayscale!)
    def grayscale!
      (t_Fx = width).times do |w|
        height.times do |h|
          color = get_pixel(w, h)
          if (a = color.alpha) > 0
            Graphics.update if (t_Fx += 1) % 10000 == 0
            num = (color.red + color.green + color.blue) / 3
            set_pixel(w, h, Color.new(num, num, num, a))
          end
        end
      end
    end
  end
  #--------------------------------------------------------------------------
  # * New method: drg_pixelate! (0.2 second)
  # NOTE: Pixelateing bitmaps to a larger pixel size is less process consuming.
  #       for best results, don't pixelate to numbers below four.
  #       This works much better for solid images, due to bugs.
  #--------------------------------------------------------------------------
  unless method_defined?(:drg_pixelate!)
    def drg_pixelate!(size = 10)
      return self if size <= (t_Fx = 1)
      c = lambda {|a,b| (a / b**2) * Math.sqrt(b) }
      for w in 0..((width - 1) / size)
        w *= size
        for h in 0..((height - 1) / size)
          h *= size
          r, g, b, a = 0, 0, 0, 0
          size.times do |i|
            color = get_pixel(w, h)
            r += color.red
            g += color.green
            b += color.blue
            a += color.alpha
            color = get_pixel(w + i, h)
            r += color.red
            g += color.green
            b += color.blue
            a += color.alpha
            color = get_pixel(w, h + i)
            r += color.red
            g += color.green
            b += color.blue
            a += color.alpha
          end
          Graphics.update if (t_Fx += 1) % 10000 == 0
          fill_rect(w, h, size, size, Color.new(c.call(r,size),c.call(g,size),
                                                c.call(b,size),c.call(a,size)))
        end
      end
    end
  end
  #--------------------------------------------------------------------------
  # * New method: pixelate!
  #--------------------------------------------------------------------------
  unless method_defined?(:pixelate!)
    def pixelate!(size = 10)
      return mosaic!(size,size) if respond_to?(:mosaic!)
      return drg_pixelate!(size)
    end
  end
  #--------------------------------------------------------------------------
  # * New method: drg_frost! (5 second)
  # NOTE: Frosting a bitmap randomly scatters its pixels. As such, Consistant
  #       results are impossible to get.
  #       Frosting a bitmap beyond eight won't result in a more scattered image
  #--------------------------------------------------------------------------
  unless method_defined?(:drg_frost!)
    def drg_frost!(noise = 10)
      for pass in 1..noise
        (t_Fx = width).times do |w|
          height.times do |h|
            Graphics.update if (t_Fx += 1) % 10000 == 0
            set_pixel(w, h, get_pixel(w + rand(3) - 1, h + rand(3) - 1))
          end
        end
      end
    end
  end
  #-------------------------------------------------------------------------
  # ● New method: bltapiinit
  #-------------------------------------------------------------------------
  unless method_defined?(:bltapiinit)
    def bltapiinit
      info = [40,width,height,1,32,0,0,0,0,0,0].pack('LllSSLLllLL')
      hWndDC = LiTTleDRAgo.getdc.call(LiTTleDRAgo.hwnd)
      hMemDC = LiTTleDRAgo.ccdc.call(hWndDC)
      hMemBM = LiTTleDRAgo.ccbitmap.call(hWndDC, width, height)
      LiTTleDRAgo.releasedc.call(LiTTleDRAgo.hwnd, hWndDC)
      LiTTleDRAgo.selectobject.call(hMemDC, hMemBM)
      LiTTleDRAgo.setdibits.call(hMemDC, hMemBM, 0, height, address, info, 0)
      return hMemDC, hMemBM, info
    end
  end
  #-------------------------------------------------------------------------
  # ● New method: bit_blt
  #-------------------------------------------------------------------------
  unless method_defined?(:bit_blt)
    def bit_blt(x, y, src_bmp, src_rect, rastor_operation = 0xCC0020)
      hDC1, hBM1, info = *self.bltapiinit
      hDC2, hBM2 = *src_bmp.bltapiinit
      LiTTleDRAgo.bitblt.call(hDC1, x, y, src_rect.width, src_rect.height,
                  hDC2, src_rect.x, src_rect.y, rastor_operation)
      LiTTleDRAgo.getdibits.call(hDC1, hBM1, 0, height, address, info, 0)
      LiTTleDRAgo.deleteobject.call(hBM1)
      LiTTleDRAgo.deleteobject.call(hDC1)
      LiTTleDRAgo.deleteobject.call(hBM2)
      LiTTleDRAgo.deleteobject.call(hDC2)
    end
  end  
  #-------------------------------------------------------------------------
  # ● New method: crop_blt
  #-------------------------------------------------------------------------
  unless method_defined?(:crop_blt)
    def crop_blt(x, y, width, height, bitmap, dir = 1, align = 1, opacity = 255)
      w, h = bitmap.width, bitmap.height
      if w < width and h < height
        x += (width - w) / 2 if align == 1
        x += width - w       if align == 2
        return full_blt(x, y, bitmap, opacity)
      end
      i, j = dir % 3, dir / 3
      crop_x, crop_y = 0, 0
      crop_x = (w - width) / 2  if i == 1
      crop_x = w - width        if i == 2
      crop_y = (h - height) / 2 if j == 1
      crop_y = h - height       if j == 2
      blt(x, y, bitmap, Rect.new(crop_x, crop_y, width, height), opacity)
    end
  end
  #-------------------------------------------------------------------------
  # ● New method: fit_blt
  #-------------------------------------------------------------------------
  unless method_defined?(:fit_blt)  
    def fit_blt(x, y, width, height, bitmap, opacity = 255, align = 1)
      w, h = bitmap.width, bitmap.height
      if w > width or h > height
        conversion = w / h.to_f
        zoom_x, zoom_y = width * conversion, height if conversion <= 1
        zoom_x, zoom_y = width, height / conversion unless conversion <= 1
        x += (width - zoom_x) / 2 if align == 1
        x += width - zoom_x       if align == 2
        dest_rect = Rect.new(x, y, zoom_x, zoom_y)
        stretch_blt(dest_rect, bitmap, bitmap.rect, opacity)
      else
        x += (width - w) / 2 if align == 1
        x += width - w       if align == 2
        full_blt(x, y, bitmap, opacity)
      end
    end
  end
  #-------------------------------------------------------------------------
  # ● New method: full_blt
  #-------------------------------------------------------------------------
  unless method_defined?(:full_blt)
    def full_blt(x, y, bitmap, opacity = 255)
      blt(x, y, bitmap, bitmap.rect, opacity)
    end
  end
  #-------------------------------------------------------------------------
  # ● New method: scale_blt
  #-------------------------------------------------------------------------
  unless method_defined?(:scale_blt)
    def scale_blt(dest_rect, src_bitmap, src_rect = src_bitmap.rect, o = 255)
      w, h = src_rect.width, src_rect.height
      scale = [w / dest_rect.width.to_f, h / dest_rect.height.to_f].max
      ow, oh = (w / scale).to_i, (h / scale).to_i
      ox, oy = (dest_rect.width - ow) / 2, (dest_rect.height - oh) / 2
      stretch_blt(Rect.new(ox + dest_rect.x, oy + dest_rect.y, ow, oh),
        src_bitmap, src_rect, o)
    end
  end
  #-------------------------------------------------------------------------
  # ● New method: frames_flip_horizontal
  #-------------------------------------------------------------------------
  unless method_defined?(:frames_flip_horizontal)
    def frames_flip_horizontal(frames)
      frame_width = width / frames
      frame_bitmap = Bitmap.new(frame_width, height)
      rect = Rect.new(0, 0, frame_width, height)
      frames.times do |i|
        frame_bitmap.clear
        rect.x = (x = i * frame_width)
        frame_bitmap.blt(0, 0, self, rect)
        frame_bitmap.flip_horizontal!
        blt(x, 0, frame_bitmap, frame_bitmap.rect)
      end
      frame_bitmap.dispose
    end
  end
  #-------------------------------------------------------------------------
  # ● New method: frames_flip_vertical
  #-------------------------------------------------------------------------
  unless method_defined?(:frames_flip_vertical)
    def frames_flip_vertical(frames)
      frame_height = height / frames
      frame_bitmap = Bitmap.new(width, frame_height)
      rect = Rect.new(0, 0, width, frame_height)
      frames.times do |i|
        frame_bitmap.clear        
        rect.y = (y = i * frame_height)
        frame_bitmap.blt(0, 0, self, rect)
        frame_bitmap.flip_vertical!
        blt(0, y, frame_bitmap, frame_bitmap.rect)
      end
      frame_bitmap.dispose
    end
  end
  #-------------------------------------------------------------------------
  # ● New method: blur_area
  #-------------------------------------------------------------------------
  unless method_defined?(:blur_area)
    def blur_area(settings = {})
      blur_settings.each do |default, setting|
        settings[default] = setting unless settings.has_key?(default)
      end
      keys = settings.keys
      rect_defined = keys.include?('rect')
      rect_p_defined = keys.include?('x') && keys.include?('y') &&
                       keys.include?('w') && keys.include?('h')
      if rect_defined
        rect = settings['rect']
        x, y, w, h = rect.x, rect.y, rect.width, rect.height
      elsif rect_p_defined
        x, y, w, h = settings['x'], settings['y'], settings['w'], settings['h']
      else
        x, y, w, h = 0, 0, self.width, self.height
      end
      dummy = self.dup
      spacing = settings['spacing']
      opacity = settings['opacity']
      settings['offset'].times do |i|
        src_rects = []
        src_rects << Rect.new(x + i * spacing, y + i * spacing, w, h)
        src_rects << Rect.new(x - i * spacing, y + i * spacing, w, h)
        src_rects << Rect.new(x + i * spacing, y - i * spacing, w, h)
        src_rects << Rect.new(x - i * spacing, y - i * spacing, w, h)
        o = Integer(opacity * (settings['offset'] - i) / (settings['offset']))
        src_rects.each { |src_rect|  blt(x, y, dummy, src_rect, o)}
      end
      dummy.dispose
      self
    end
  end
  #-------------------------------------------------------------------------
  # ● New method: sub_bitmap_blend
  #-------------------------------------------------------------------------
  unless method_defined?(:sub_bitmap_blend)
    def sub_bitmap_blend(x = 0, y = 0, bitmap = self, src_rect = bitmap.rect)
      src_rect.width.times do |i|
        src_rect.height.times do |j|
          c1 = get_pixel(x + i, y + j)
          c2 = bitmap.get_pixel(src_rect.x + i, src_rect.y + j)
          nc = Color.new(c1.red-c2.red, c1.green-c2.green, c1.blue-c2.blue)
          set_pixel(x + i, y + j, nc) if c2.alpha > 0
        end
      end
    end
  end
  #-------------------------------------------------------------------------
  # ● New method: add_bitmap_blend
  #-------------------------------------------------------------------------
  unless method_defined?(:add_bitmap_blend)
    def add_bitmap_blend(x = 0, y = 0, bitmap = self, src_rect = bitmap.rect)
      src_rect.width.times do |i|
        src_rect.height.times do |j|
          c1 = get_pixel(x + i, y + j)
          c2 = bitmap.get_pixel(src_rect.x + i, src_rect.y + j)
          nc = Color.new(c1.red+c2.red, c1.green+c2.green, c1.blue+c2.blue)
          set_pixel(x + i, y + j, nc) if c2.alpha > 0
        end
      end
    end
  end
  #--------------------------------------------------------------------------
  # * Alias Listing
  #--------------------------------------------------------------------------
  alias_sec_method :frost!,      :drg_frost!
  alias_sec_method :blur,        :blur_area
  alias_sec_method :entire_fill, :full_fill
        #--------------------------------------------------------------------------
        # * Replicated method: gradient_fill_rect
        #--------------------------------------------------------------------------
  unless method_defined?(:gradient_fill_rect)
    def gradient_fill_rect(*a)
      if a.first.is_a?(Rect)
        x, y, width, height = a[0].x, a[0].y, a[0].width, a[0].height
        color1 = a.at(1).dup
        color2 = a.at(2)
        vertical = a.at(3)
      else
        x, y, width, height = a[0..3]
        color1 = a.at(4).dup
        color2 = a.at(5)
        vertical = a.at(6)
      end
      dr = color2.red   - color1.red
      dg = color2.green - color1.green
      db = color2.blue  - color1.blue
      da = color2.alpha - color1.alpha
      start_rgba = [color1.red, color1.green, color1.blue, color1.alpha]
      if vertical
        dr, dg, db, da = dr / height, dg / height, db / height, da / height
        for i in (y.round...(y + height).round)
          fill_rect(x, i, width, 1, color1)
          start_rgba[0] = [start_rgba.at(0) + dr, 0].max.round
          start_rgba[1] = [start_rgba.at(1) + dg, 0].max.round
          start_rgba[2] = [start_rgba.at(2) + db, 0].max.round
          start_rgba[3] = [start_rgba.at(3) + da, 0].max.round
          color1.set(*start_rgba)
        end
      else
        dr, dg, db, da = dr / width, dg / width, db / width, da / width
        for i in (x.round...(x + width).round)
          fill_rect(i, y, 1, height, color1)
          start_rgba[0] = [start_rgba.at(0) + dr, 0].max.round
          start_rgba[1] = [start_rgba.at(1) + dg, 0].max.round
          start_rgba[2] = [start_rgba.at(2) + db, 0].max.round
          start_rgba[3] = [start_rgba.at(3) + da, 0].max.round
          color1.set(*start_rgba)
        end
      end
    end
  end
end
#==============================================================================
# ** String     
#------------------------------------------------------------------------------
#  
#==============================================================================
class String
  #-------------------------------------------------------------------------
  # ● New method: get_int
  #-------------------------------------------------------------------------
  unless method_defined?(:get_int)
    def get_int
      m = self.scan(/([-]?\d+)/i).flatten
      return m.join.to_i
    end
  end
  #-------------------------------------------------------------------------
  # ● New method: get_ints
  #-------------------------------------------------------------------------
  unless method_defined?(:get_ints)
    def get_ints
      array = self.scan(/([-]?\d+)/i).flatten.relay(:i)
      return array
    end
  end
  #-------------------------------------------------------------------------
  # ● New method: encrypt
  #-------------------------------------------------------------------------
  unless method_defined?(:encrypt)
    def encrypt(encryption_string = 'encrypt')
      encryption_bytes = []
      encryption_string.each_byte {|c| encryption_bytes << c}
      string = ''
      self.size.times do |i|
        byte = self * encryption_bytes[i % encryption_bytes.size]
        base, mod = byte / 255, byte % 255
        string += base.chr + mod.chr
      end
      return string
    end
  end
  #-------------------------------------------------------------------------
  # ● New method: encrypt!
  #-------------------------------------------------------------------------
  unless method_defined?(:encrypt!)
    def encrypt!(encryption_string = 'encrypt')
      replace(encrypt(encryption_string))
    end
  end
  #-------------------------------------------------------------------------
  # ● New method: decrypt
  #-------------------------------------------------------------------------
  unless method_defined?(:decrypt)
    def decrypt(encryption_string = 'encrypt')
      encryption_bytes = []
      encryption_string.each_byte {|c| encryption_bytes << c}
      string = ''
      (self.size / 2).times do |i|
        b, m = self[i * 2] * 255, self[i * 2 + 1]
        string += ((b + m) / encryption_bytes[i % encryption_bytes.size]).chr
      end
      return string
    end
  end
  #-------------------------------------------------------------------------
  # ● New method: decrypt!
  #-------------------------------------------------------------------------
  unless method_defined?(:decrypt!)
    def decrypt!(encryption_string = 'encrypt')
      replace(decrypt(encryption_string))
    end
  end
  #-------------------------------------------------------------------------
  # ● New method: clear, words, characters
  #-------------------------------------------------------------------------
  define_sec_method(:clear)      { replace('')      }
  define_sec_method(:words)      { split(' ')       }
  define_sec_method(:characters) { split('')        }
  define_sec_method(:last)       { characters.last  }
  define_sec_method(:first)      { characters.first }
end

#==============================================================================
# ** Game_Interpreter
#------------------------------------------------------------------------------
#  An interpreter for executing event commands. This class is used within the
# Game_Map, Game_Troop, and Game_Event classes.
#==============================================================================
Klass = LiTTleDRAgo::VX ? Game_Interpreter : Interpreter
class Klass
  #--------------------------------------------------------------------------
  # * Constant
  #--------------------------------------------------------------------------
  SCRIPT_WAIT_RESULTS = [:wait, FalseClass]
  #--------------------------------------------------------------------------
  # ● Redirect Listing
  #--------------------------------------------------------------------------
  redirect_method :picture_sprite,        '$game_map.picture_sprite'
  #--------------------------------------------------------------------------
  # ● New method: random_teleport
  #--------------------------------------------------------------------------
  unless method_defined?(:random_teleport)
    def random_teleport(id = 0)
      character = id.is_a?(Game_Character) ? id : get_character(id)
      character.random_teleport if character.is_a?(Game_Character)
    end
  end
  #--------------------------------------------------------------------------
  # ● Redefined method: same_map?, next_event_code
  #--------------------------------------------------------------------------
  define_sec_method(:same_map?)       { @map_id == $game_map.map_id    }
  define_sec_method(:next_event_code) { @list[@index + 1].code         }
  #--------------------------------------------------------------------------
  # * Overwriten method: command_355
  #--------------------------------------------------------------------------
  def command_355
    script = @list[index = @index].parameters[0] + "\n"
    while [655, 355].include?(next_event_code) do
      script += @list[@index+=1].parameters[0] + "\n"
    end
    wait = SCRIPT_WAIT_RESULTS.include?(eval(script)) && LiTTleDRAgo::XP
    return wait ? !(@index = index) : true
  end  
end

#==============================================================================
# ** Sprite
#------------------------------------------------------------------------------
#  A sprite class for bitmap processing.
#==============================================================================
class Sprite
  #---------------------------------------------------------------------------
  # * Alias Listing
  #---------------------------------------------------------------------------
  alias_sec_method(:angle_fix_alias, :"angle=")
  alias_sec_method(:drg_core_dispose,:"dispose")
  alias_sec_method(:set_x_alias,     :"x=")
  alias_sec_method(:set_y_alias,     :"y=")
  alias_sec_method(:get_x_alias,     :"x")
  alias_sec_method(:get_y_alias,     :"y")
  #---------------------------------------------------------------------------
  # * New method: method_missing
  #---------------------------------------------------------------------------
  def method_missing(val,*a,&b)
    return bitmap.send(val.to_s,*a,&b) if bitmap.respond_to?(val.to_sym)
    text = "Undefined method #{val} for #{self.inspect}"
    raise(NoMethodError, text, caller(1))               
  end
  #---------------------------------------------------------------------------
  # * Aliased method: x=, y=
  #---------------------------------------------------------------------------
  define_method(:x=)      {|amt| set_x_alias((@intfloat_x = amt).to_i) }
  define_method(:y=)      {|amt| set_y_alias((@intfloat_y = amt).to_i) }
  define_method(:x)       { @intfloat_x ||= get_x_alias }
  define_method(:y)       { @intfloat_y ||= get_y_alias }
  define_method(:dispose) { disposed? || drg_core_dispose }
  define_method(:rotate_correction) { self.ox,self.oy = width/2, height/2 }
  #---------------------------------------------------------------------------
  # * Aliased method: angle=
  #---------------------------------------------------------------------------
  def angle=(v)
    return if @angle == v
    sign = (v % 360 == 180 || v % 180 == 90) ? 1.00001 : 1
    angle_fix_alias((@angle = v) * sign)
  end
  #--------------------------------------------------------------------------
  # ● Redefined method: width, height
  #--------------------------------------------------------------------------
  define_sec_method(:width)       { src_rect.width }
  define_sec_method(:height)      { src_rect.height }
  #--------------------------------------------------------------------------
  # ● Overwriten method: dup
  #--------------------------------------------------------------------------
  def dup
    sprite = self.class.new(self.viewport)
    sprite.bitmap                = self.bitmap.clone
    sprite.zoom_x, sprite.zoom_y = self.zoom_x, self.zoom_y
    sprite.x, sprite.y           = self.x, self.y
    sprite.ox, sprite.oy         = self.ox, self.oy
    sprite.color, sprite.tone    = self.color.dup, self.tone.dup
    sprite.src_rect,sprite.angle = self.src_rect, self.angle
    return sprite
  end
  #--------------------------------------------------------------------------
  # ● Overwriten method: clone
  #--------------------------------------------------------------------------
  def clone
    (sprite = self.dup) && instance_variables.each do |var|
      temp = instance_variable_get("#{var}")
      sprite.instance_variable_set("#{var}",temp) rescue nil
    end
    (frozen? && sprite.freeze)
    return sprite   
  end
  #--------------------------------------------------------------------------
  # ● New method: scale
  #--------------------------------------------------------------------------
  unless method_defined?(:scale)
    def scale(w, h)
      tmp = self.bitmap.clone
      self.bitmap = Bitmap.new(w, h)
      self.bitmap.stretch_blt(Rect.new(0, 0, w, h), tmp, tmp.rect)
      tmp.dispose
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: in_rect?
  #--------------------------------------------------------------------------
  unless method_defined?(:in_rect?)
    def in_rect?(*rect)
      if rect.size == 1
        x, y, w, h = rect[0].x, rect[0].y, rect[0].width, rect[0].height
        return self.x.between?(x, x + w) && self.y.between?(y, y + h)
      elsif rect.size == 4
        x, y, w, h = rect
        return self.x.between?(x, x + w) && self.y.between?(y, y + h)
      end
      return false
    end
  end
end

#==============================================================================
# ** Scheduler
#------------------------------------------------------------------------------
#  This class allows to schedule a proc or method call a given amount of frames
#  into the future with any amount of arguments
#==============================================================================
unless defined?(Scheduler)
  class Scheduler
    #==========================================================================
    # ** Order
    #--------------------------------------------------------------------------
    #  An order is a proc, method or something else which has 'call' as a
    #  method, and the arguments to pass along.
    #==========================================================================
    unless method_defined?(:update)
      Order = Struct.new(:callable, :arguments)
      class Order
        #----------------------------------------------------------------------
        # * New Methods: call
        #----------------------------------------------------------------------
        define_method(:call) { callable.call(*arguments) }
      end
      #========================================================================
      # ** RecurringOrder
      #------------------------------------------------------------------------
      #  An order which is recurring every specified amount of time until
      #  FalseClass is returned from the call.
      #  Note that arguments remain the same for each call
      #========================================================================
      RecurringOrder = Struct.new(:callable, :arguments, :frames)
      class RecurringOrder
        #----------------------------------------------------------------------
        # * New Methods: call
        #----------------------------------------------------------------------
        def call
          result = callable.call(*arguments)
          unless result == FalseClass
            Scheduler.schedule_recurring(frames, frames, callable, *arguments)
          end
        end
      end
      #========================================================================
      # ** Mapping
      #------------------------------------------------------------------------
      # Maps an index to an array. Values can be added to these value.
      # Each array starts empty.
      #========================================================================
      class Mapping
        #----------------------------------------------------------------------
        # * New method: add, get, empty
        #----------------------------------------------------------------------
        define_method(:add)   { |i, v| ((@mapping ||= {}) ||=[]) << v }
        define_method(:get)   { |i|    ((@mapping ||= {}) || [])   }
        define_method(:empty) { |i|     (@mapping ||= {}).delete(i)   }
      end
      #------------------------------------------------------------------------
      # * New method: schedule
      #------------------------------------------------------------------------
      def schedule(frames, callable, *arguments)
        order = Order.new(callable, arguments)
        (@mapping ||= Mapping.new).add(frames + (@tick||=0), order)
      end
      #------------------------------------------------------------------------
      # * New method: schedule_recurring
      #------------------------------------------------------------------------
      def schedule_recurring(frames, frames_to_wait, callable, *arguments)
        order = RecurringOrder.new(callable, arguments, frames_to_wait)
        (@mapping ||= Mapping.new).add(frames + (@tick||=0), order)
      end
      #------------------------------------------------------------------------
      # * New method: update
      #------------------------------------------------------------------------
      def update
        orders = (@mapping ||= Mapping.new).get((@tick||=0))
        @mapping.empty(@tick)
        orders.each {|s| s.call }
        @tick += 1
      end
      #------------------------------------------------------------------------
      # * Self
      #------------------------------------------------------------------------
      @@instance = self.new
      class << self
        define_method(:instance) { @@instance }
        redirect_method :schedule_recurring, 'instance.schedule_recurring'
        redirect_method :schedule,           'instance.schedule'
        redirect_method :update,             'instance.update'
      end
    end
  end
  Graphics.auto_update.push([Scheduler,:update])
end
#==============================================================================
# ** Dir     
#------------------------------------------------------------------------------
#
#==============================================================================
class << Dir
  #--------------------------------------------------------------------------
  # ● New method: make_dir
  #--------------------------------------------------------------------------
  def make_dir(path)
    (dir = path.split("/")).size.times do |i|
      next if dir == "."
      Dir.mkdir(dir[0..i].join("/")) rescue nil
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: files_with_extension
  #--------------------------------------------------------------------------
  def files_with_extension(directory, extension)
    entries(directory).select{|file| File.extname(file) == extension}
  end
end

#==============================================================================
# ** BitmapDump
#------------------------------------------------------------------------------
#
#==============================================================================
module BitmapDump; end
class << BitmapDump
  #--------------------------------------------------------------------------
  # ● New method: self.bitmap_data
  #--------------------------------------------------------------------------
  unless method_defined?(:bitmap_data)
    def bitmap_data(bitmap)
      red = Table.new(bitmap.width, bitmap.height)
      green, blue, alpha = red.clone, red.clone, red.clone      
      bitmap.width.times do |i|
        bitmap.height.times do |j|
          color = bitmap.get_pixel(i, j)
          red[i, j],  green[i, j] = color.red, color.green
          blue[i, j], alpha[i, j] = color.blue, color.alpha
        end
      end
      return [red, green, blue, alpha]
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: self.read_bitmap_data
  #--------------------------------------------------------------------------
  unless method_defined?(:read_bitmap_data)
    def read_bitmap_data(red, green, blue, alpha)
      bitmap = Bitmap.new(red.xsize, red.ysize)
      bitmap.width.times do |i|
        bitmap.height.times do |j|
          color_table = [red[i, j], green[i, j], blue[i, j], alpha[i, j]]
          bitmap.set_pixel(i, j, Color.new(*color_table))
        end
      end
      return bitmap
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: self.save_bitmap
  #--------------------------------------------------------------------------
  unless method_defined?(:save_bitmap)
    def save_bitmap(bitmap, filename, folder = '')
      bitmap_data = bitmap_data(bitmap)
      if folder && folder != ''
        Dir.make_dir(folder) unless FileTest.directory?(folder)
        filename = "#{folder}/#{filename}"
      end
      filename = filename.gsub("\\","/").gsub("//","/")
      file = File.open(filename,'wb')
      Marshal.dump(bitmap_data, file)
      file.close
    end
  end
  #--------------------------------------------------------------------------
  # ● New method: self.load_bitmap
  #--------------------------------------------------------------------------
  unless method_defined?(:load_bitmap)
    def load_bitmap(filename, folder = '')
      if folder && folder != ''
        Dir.make_dir(folder) unless FileTest.directory?(folder)
        filename = "#{folder}/#{filename}"
      end
      filename = filename.gsub("\\","/").gsub("//","/")
      file = File.open(filename,"rb")
      colors = Marshal.load(file)
      file.close
      bitmap = read_bitmap_data(colors)
      return bitmap
    end
  end
end[/pre]



[pre lang="ruby"]#==============================================================================
# ** Drago - Custom Resolution
# Version : 2.17
# Contact : littledrago.blogspot.com / forum.chaos-project.com
#==============================================================================
($imported ||= {})[:drg_custom_resolution] = 2.17
#==============================================================================
#
# Introduction :
#
#   Version 2 from previous Drago - Custom Resolution
#
# Issue :
#   
#  - Normal transition didn't work when resolution is more than 640x480
#  - ALT+Enter is disabled by default
#  - Custom menu system will require an edit to match the new resolution
#  - Anything that modify Sprite_Character & Spriteset_Map will require an edit
#
# Script Call :
#
#  Graphics.window
#  Graphics.fullscreen
#  Graphics.fullscreen?     # returns true if game is fullscreen
#
#    $game_map.start_zoom(X, Y, ZOOM_VALUE, DURATION = 20)     
#    $game_map.zoom(X = nil, Y = nil, ZOOM_VALUE)   
#    $game_map.zoom_in(X = nil, Y = nil, DURATION = 20)
#    $game_map.zoom_out(X = nil, Y = nil, DURATION = 20)
#
#    $game_map.reverse(true / false) # Flip the map
#
#    $game_map.start_tilemap_opacity(OPACITY = 255, DURATION = 20)
#    $game_map.start_tilemap_tone(TONE = Tone.new(0,0,0,0), DURATION = 0)
#
#
#    change_tilemap_tone(TONE,*CHARACTER)     # change tilemap tone
#    change_character_tone(TONE,*CHARACTER)   # change character tone without
#                                               changing the tilemap
#
#   X, Y       = Zoom focus
#
#   ZOOM_VALUE = Integer from 1-12
#
#   OPACITY    = Integer from 0-255
#
#   TONE       = [R,G,B,A] or Tone.new(R,G,B,A)
#
#   CHARACTER  = $game_map.events.values # all events
#              = $game_map.events.keys   # all events
#              = $game_player            # player
#              = -1                      # player
#              = 0                       # this event
#              = [2,3,4,6]               # events with selected id
#              = [-1,2,3,4,6]            # player & events with selected id
#              = [0,2,3,4,6]             # this event & events with selected id
#              = (1..99)                 # events in range
#              = [(1..8),20,25,(30..42)] # events in range
#
#    * will not change the character tone if left out
#
# Links :
#
#  - Fantasist's Transitions Pack
#    http://forum.chaos-project.com/index.php/topic,1390.0.html
#  - ForeverZer0's Add-ons
#    http://forum.chaos-project.com/index.php/topic,7862.0.html
#  - ThallionDarkshine's Add-ons
#    http://forum.chaos-project.com/index.php/topic,12655.0.html
#  - Drago Transition Pack
#    http://forum.chaos-project.com/index.php/topic,13488.0.html
#
#  - Adjust Menu Position
#    http://forum.chaos-project.com/index.php/topic,13781.0.html
#
#  - ThallionDarkshine's F12 Fix
#    http://forum.chaos-project.com/index.php/topic,13629.0.html
#  - Zeriab's F12 Pause with images
#    http://forum.chaos-project.com/index.php/topic,3613.0.html
#
# Special Thanks :
#  
# - ForeverZer0 & KK20 for method used in this script
# - Wecoc for autotile addon
#
#==============================================================================

module LiTTleDRAgo
  
  SCREEN_SIZE = [640,490]
  # Define the resolution of the game screen. These values can be anything
  # within reason. Centering, viewports, etc. will all be taken care of, but it
  # is recommended that you use values divisible by 32 for best results.
  
  
  AUTOTILE_SPEED = {}
  
  AUTOTILE_SPEED[:map_id] = :speed
  AUTOTILE_SPEED[0]       = 6                              # default speed
  #AUTOTILE_SPEED[35]      = 0                              # unchanged autotile
  #AUTOTILE_SPEED[159]     = 16                             
  # Speed of the autotile based on map_id
  
  CONTROL_SCREEN_SIZE = false
  # Control screen size with a mouse
  
  HIGH_PRIORITY = true
  # Change Game process priority to high
  
  SPRITE_COMPACT = true
  # Keep the sprite to the very minimum number
  
  CHARACTER_Z_FIX = {
    '178-Switch01'  => 0,
    '180-Switch03'  => 0,
    '181-Switch04'  => 0,
    '199-Support07' => 0,
  }
  # Fix the screen_z value for events based on Graphic name.
  # You can also define z value for event by inserting <z: Z_VALUE>
  # on event name.
  # This way, flat events such as pitfall won't overlap with player z value.
  
end


core = "This script needs Drago - Core Engine ver 1.47 or above"
rmvx = "This script not for RMVX"
implemented = "%1$s has already implemented, Please remove the %1$s script"
zoom = sprintf(implemented,"Map Zoom")
tone = sprintf(implemented,"Tilemap Tone Changer" )

($imported[:drg_core_engine] || 0) >= 1.47 || raise(core)
LiTTleDRAgo::XP || LiTTleDRAgo::VXA  || raise(rmvx)
$imported[:drg_cr_map_zoom]          && raise(zoom)
$imported[:drg_tilemap_tone_changer] && raise(tone)
#==============================================================================
# ** Graphics
#------------------------------------------------------------------------------
#  This module handles all Graphics
#==============================================================================

class << Graphics
  #-------------------------------------------------------------------------
  # * Alias Listing
  #-------------------------------------------------------------------------
  alias_sec_method :zer0_graphics_transition,            :transition
  alias_sec_method :drg_resolution_change_resize_screen, :resize_screen
  alias_sec_method :drg_resolution_change_update,        :update
  #-------------------------------------------------------------------------
  # * Aliased method: resize_screen
  #-------------------------------------------------------------------------
  def resize_screen(width, height)
    width = (width / 32.0).round * 32
    height = (height / 32.0).round * 32
    if $game_map.respond_to?(:screen_size)
      $game_map.screen_size[0] = width
      $game_map.screen_size[1] = height
    end
    drg_resolution_change_resize_screen(width, height)
  end
  #-------------------------------------------------------------------------
  # * Aliased method: transition
  #-------------------------------------------------------------------------
  def transition(duration = 8, *args)
    if width <= 640 && height <= 480
      return zer0_graphics_transition(duration, *args)
    end
    if duration > 0
      viewport = Viewport.new(0,0,width,height)
      sprite  = Sprite.new(viewport)
      sprite.bitmap = Graphics.snap_to_bitmap
      sprite2 = Sprite.new(viewport)
      sprite2.z = sprite.z - 10
      sprite2.blend_type = 1
      zer0_graphics_transition(0)
      fade = 255 / duration
      if (file = args.at(0)).is_a?(String)
        bitmap = Bitmap.new(file)
        sprite2.bitmap = bitmap.stretch(width,height)
        bitmap.dispose
      end
      duration.times {[sprite,sprite2].each {|s|s.opacity -= fade} && update }
      [sprite.bitmap, sprite2.bitmap, sprite, sprite2, viewport].dispose
    end
    zer0_graphics_transition(0)
  end
  #-------------------------------------------------------------------------
  # * Aliased method: update
  #-------------------------------------------------------------------------
  def update
    drg_resolution_change_update
    update_resolution_adjust
  end
  #-------------------------------------------------------------------------
  # * New method: update_resolution_adjust
  #-------------------------------------------------------------------------
  def update_resolution_adjust
    return unless LiTTleDRAgo::XP && $game_player
    return unless Game_Player.const_defined?(:CENTER_X)
    change   = Game_Player.const_get(:CENTER_X) != $game_player.center_x
    change ||= Game_Player.const_get(:CENTER_Y) != $game_player.center_y
    return unless change
    resize_screen(width,height)
    $game_player.center($game_player.x,$game_player.y)
  end
  #-------------------------------------------------------------------------
  # * Overwriten method: fullscreen
  #-------------------------------------------------------------------------
  def fullscreen
    @fullscreen = true
    fill_monitor
    LiTTleDRAgo.hide_borders
  end
  #-------------------------------------------------------------------------
  # * Overwriten method: window
  #-------------------------------------------------------------------------
  def window
    @fullscreen = false
    LiTTleDRAgo.show_borders
    if $game_map && $game_map.screen_size.all? {|s| s.is_a?(Numeric)}
      x,y = $game_map.screen_size[0..1]
      x += ($game_map.screen_size[2] ||= 1)
      $game_map.screen_size[2] *= -1
      drg_resolution_change_resize_screen(x,y)
    else
      x,y = LiTTleDRAgo::SCREEN_SIZE
    end
    resize_screen(x,y)
  end
  #-------------------------------------------------------------------------
  # * Overwriten method: fullscreen?
  #-------------------------------------------------------------------------
  define_method(:fullscreen?) { @fullscreen == true }
end

Graphics.window
Graphics.disable_alt_enter
Graphics.control_screen_size LiTTleDRAgo::CONTROL_SCREEN_SIZE
Graphics.high_priority     = LiTTleDRAgo::HIGH_PRIORITY
GC.start
#==============================================================================
# ** 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 Variable
  #--------------------------------------------------------------------------
  attr_sec_accessor :zoom_x, :zoom_y, 'Integer(1)'
  attr_sec_accessor :screen_size,     'LiTTleDRAgo::SCREEN_SIZE'
  attr_sec_accessor :tilemap_tone,    'Tone.new(0,0,0)'
  attr_sec_accessor :tilemap_opacity, 'Integer(255)'
  attr_sec_accessor :tilemap_hue,     'Integer(0)'
  #---------------------------------------------------------------------------
  # * Redirect Listing
  #---------------------------------------------------------------------------
  [:tilemap_tone,:tilemap_opacity].each do |meth|
    redirect_method :"#{meth}_changing?",   "(@#{meth}_duration ||= 0) > 0"
  end
  #---------------------------------------------------------------------------
  # * Define Sec Listing
  #---------------------------------------------------------------------------
  define_sec_method(:zooming?)      {(@zoom_duration ||= 0) > 0}
  define_sec_method(:screen_tile_x) {(Graphics.width  / 32.0).ceil}
  define_sec_method(:screen_tile_y) {(Graphics.height / 32.0).ceil}
  #-------------------------------------------------------------------------
  # * Alias Listing
  #-------------------------------------------------------------------------
  alias_sec_method(:drg_scroll_right_adjust, :scroll_right)
  alias_sec_method(:drg_scroll_down_adjust,  :scroll_down)
  alias_sec_method(:tilemap_effect_update,   :update)
  alias_sec_method(:get_map_data,            :data)
  #--------------------------------------------------------------------------
  # * Aliased method: Scroll Down
  #--------------------------------------------------------------------------
  def scroll_down(distance)
    times = vxa_map_multiplier
    if loop_vertical?
      @display_y += distance
      @display_y %= height * times
      @parallax_y += distance if @parallax_y && @parallax_loop_y
    else
      last_y = @display_y
      result = [@display_y + distance, (map_edge.at(1) / zoom_y)].min
      drg_scroll_down_adjust(distance)
      @display_y = result
    end
  end
  #--------------------------------------------------------------------------
  # * Aliased method: Scroll Right
  #--------------------------------------------------------------------------
  def scroll_right(distance)
    times = vxa_map_multiplier
    if loop_horizontal?
      @display_x += distance
      @display_x %= width * times
      @parallax_x += distance if @parallax_x && @parallax_loop_x
    else
      last_x = @display_x
      result = [@display_x + distance, (map_edge.at(0) / zoom_x)].min
      drg_scroll_right_adjust(distance)
      @display_x = result
    end
  end
  #--------------------------------------------------------------------------
  # * New method: zoom
  #--------------------------------------------------------------------------
  def zoom(*zoom)
    if zoom.size == 1
      zoom = (zoom.first)
    elsif zoom.size == 3
      x,y,zoom = zoom[0..2]
    end
    return unless zoom.is_a?(Numeric)
    old_zoom = @zoom_x
    @zoom_x = [[zoom,12].min, 1].max
    @zoom_y = [[zoom,12].min, 1].max
    $game_player.center(x,y) if x && y
  end
  #--------------------------------------------------------------------------
  # * New method: zoom_in
  #--------------------------------------------------------------------------
  def zoom_in(x = nil,y = nil, duration = 20)
    start_zoom(x,y, zoom_x >= 1 ? zoom_x + 1 : 1, duration)
  end   
  #--------------------------------------------------------------------------
  # * New method: zoom_out
  #--------------------------------------------------------------------------
  def zoom_out(x = nil,y = nil,duration = 20)
    start_zoom(x,y, zoom_x - 1 >= 1 ? zoom_x - 1 : zoom_x - 0.5, duration)
  end
  #--------------------------------------------------------------------------
  # * New method: map_edge
  #--------------------------------------------------------------------------
  def map_edge
    times = vxa_map_multiplier
    [_w = [(width  * zoom_x - screen_tile_x).ceil * times, 0].max,
     _h = [(height * zoom_y - screen_tile_y).ceil * times, 0].max]
  end
  #--------------------------------------------------------------------------
  # * New method: autotile_speed
  #--------------------------------------------------------------------------
  def autotile_speed(id = @map_id)
    speed = LiTTleDRAgo::AUTOTILE_SPEED
    @autotile_speed.is_a?(Array) || @autotile_speed = []
    @autotile_speed[id] ||= (speed[id] || speed[0] || 0)
  end
  #--------------------------------------------------------------------------
  # * New method: autotile_speed=
  #--------------------------------------------------------------------------
  def autotile_speed=(*value)
    @autotile_speed.is_a?(Array) || @autotile_speed = []
    @autotile_speed[@map_id]     = [value.first,0].max if value.size == 1
    @autotile_speed[value.first] = [value.at(1),0].max if value.size > 1
  end
  #--------------------------------------------------------------------------
  # * New method: vxa_map_multiplier
  #--------------------------------------------------------------------------
  def vxa_map_multiplier
    LiTTleDRAgo::VXA ? 1 : 128
  end
  #--------------------------------------------------------------------------
  # * New method: screen_is_solid?
  #--------------------------------------------------------------------------
  def screen_is_solid?
    tone = screen.tone.to_s.gsub(/([(),0 ])/i){''}
    return true if tone['255.255.255.']
    return true if tone['255.-255.-255.']
    return true if tone['-255.255.-255.']
    return true if tone['-255.-255.255.']
    return true if tone['255.255.-255.']
    return true if tone['255.-255.255.']
    return true if tone['-255.255.255.']
    return true if tone['-255.-255.-255.']
  end
  #--------------------------------------------------------------------------
  # * Aliased method: data
  #--------------------------------------------------------------------------
  def data
    data = self.reverse ? reverse_data : get_map_data
    data.make_changes = true
    data
  end
  #--------------------------------------------------------------------------
  # * New method: reverse_data
  #--------------------------------------------------------------------------
  def reverse_data
    @reverse_data ||= []
    @reverse_data[@map_id] ||= get_map_data.reverse(true,false,false)
  end
  #--------------------------------------------------------------------------
  # * New method: reverse=
  #--------------------------------------------------------------------------
  def reverse=(val)
    return val if @reverse == val
    @reverse = ((@reverse_data||=[])[@map_id] = nil) || val
    spriteset && spriteset.reload_tilemap
    @reverse
  end
  #--------------------------------------------------------------------------
  # * New method: reverse
  #--------------------------------------------------------------------------
  def reverse
    @reverse && LiTTleDRAgo::XP
  end
  #--------------------------------------------------------------------------
  # * New method: start_tilemap_tone
  #--------------------------------------------------------------------------
  def start_tilemap_tone(tone = Tone.new(0,0,0,0), duration = 0)
    @tilemap_tone_target = tone.is_a?(Array) ? Tone.new(*tone) : tone.clone
    @tilemap_tone_duration = duration
    tilemap_tone_changing? || @tilemap_tone = @tilemap_tone_target.clone
  end
  #--------------------------------------------------------------------------
  # * New method: start_tilemap_opacity
  #--------------------------------------------------------------------------
  def start_tilemap_opacity(opacity = 255, duration = 0)
    @tilemap_opacity_target = opacity * 1.0
    @tilemap_opacity_duration = duration
    tilemap_opacity_changing? || @tilemap_opacity = @tilemap_opacity_target
  end
  #--------------------------------------------------------------------------
  # * New method: update_tilemap_tone
  #--------------------------------------------------------------------------
  def update_tilemap_tone
    if tilemap_tone_changing?
      d = @tilemap_tone_duration
      target = @tilemap_tone_target
      @tilemap_tone.red   = (@tilemap_tone.red   * (d - 1) + target.red) / d
      @tilemap_tone.green = (@tilemap_tone.green * (d - 1) + target.green) / d
      @tilemap_tone.blue  = (@tilemap_tone.blue  * (d - 1) + target.blue) / d
      @tilemap_tone.gray  = (@tilemap_tone.gray  * (d - 1) + target.gray) / d
      @tilemap_tone_duration -= 1
      tilemap_tone_changing? || @tilemap_tone = @tilemap_tone_target.clone
    end
  end
  #--------------------------------------------------------------------------
  # * New method: update_tilemap_opacity
  #--------------------------------------------------------------------------
  def update_tilemap_opacity
    if tilemap_opacity_changing?
      d = @tilemap_opacity_duration
      @tilemap_opacity = (@tilemap_opacity * (d - 1) +
      @tilemap_opacity_target) / d
      @tilemap_opacity_duration -= 1
      tilemap_opacity_changing? || @tilemap_opacity = @tilemap_opacity_target
    end
  end
  #--------------------------------------------------------------------------
  # * New method: start_zoom
  #--------------------------------------------------------------------------
  def start_zoom(x,y, zoom_target, duration=20)
    @x_zoom = x
    @y_zoom = y
    @zoom_target = zoom_target * 1.0
    @zoom_duration = @zoom_x == @zoom_target ? 0 : duration
    zooming? || zoom(@x_zoom,@y_zoom,@zoom_target)
  end
  #--------------------------------------------------------------------------
  # * New method: update_zooming
  #--------------------------------------------------------------------------
  def update_zooming
    if zooming?
      d = @zoom_duration
      power = (@zoom_x * (d - 1) + @zoom_target) / d
      @zoom_duration -= 1
      zoom(@x_zoom,@y_zoom,power)
      zoom(@x_zoom,@y_zoom,@zoom_target) unless zooming?
    end
  end
  #--------------------------------------------------------------------------
  # * Aliased method: update
  #--------------------------------------------------------------------------
  def update(*args)
    tilemap_effect_update(*args)
    update_tilemap_tone
    update_tilemap_opacity
    update_zooming
  end
end
#==============================================================================
# ** Interpreter
#------------------------------------------------------------------------------
#  This interpreter runs event commands. This class is used within the
#  Game_System class and the Game_Event class.
#==============================================================================
unless LiTTleDRAgo::VX  
  class Interpreter
    #---------------------------------------------------------------------------
    # * Redirect Listing
    #---------------------------------------------------------------------------
    redirect_method :zoom,                  '$game_map.zoom'
    redirect_method :zoom_in,               '$game_map.zoom_in'
    redirect_method :zoom_out,              '$game_map.zoom_out'
    redirect_method :start_zoom,            '$game_map.start_zoom'
    redirect_method :start_tilemap_opacity, '$game_map.start_tilemap_opacity'
    redirect_method :start_tilemap_tone,    '$game_map.start_tilemap_tone'
    [:change_tilemap_tone,:change_character_tone].each do |meth|
      redirect_method :"#{meth}", :"$game_map.spriteset.#{meth}"
    end
  end
end

#==============================================================================
# ** Game_Player
#------------------------------------------------------------------------------
#  This class handles the player. Its functions include event starting
#  determinants and map scrolling. Refer to "$game_player" for the one
#  instance of this class.
#==============================================================================
class Game_Player
  #---------------------------------------------------------------------------
  # * Define Sec Listing
  #---------------------------------------------------------------------------
  define_sec_method(:center_x) {((Graphics.width/2)  / $game_map.zoom_x-16) * 4}
  define_sec_method(:center_y) {((Graphics.height/2) / $game_map.zoom_y-16) * 4}
  #-------------------------------------------------------------------------
  # * Alias Listing
  #-------------------------------------------------------------------------
  alias_sec_method(:drg_adjust_viewport_center, :center)
  #-------------------------------------------------------------------------
  # * Aliased method: center
  #-------------------------------------------------------------------------
  def center(x, y)
    if LiTTleDRAgo::XP
      Game_Player.const_set(:CENTER_X, center_x)
      Game_Player.const_set(:CENTER_Y, center_y)
    end
    drg_adjust_viewport_center(x, y)
    max_x = $game_map.map_edge.at(0) / $game_map.zoom_x
    max_y = $game_map.map_edge.at(1) / $game_map.zoom_y
    if LiTTleDRAgo::XP
      $game_map.display_x = [0, [(x * 32*4) - center_x, max_x.ceil].min].max
      $game_map.display_y = [0, [(y * 32*4) - center_y, max_y.ceil].min].max
    elsif $game_map.respond_to?(:set_display_pos)
      $game_map.set_display_pos(x - center_x, y - center_y)
    end
  end  
end

#==============================================================================
# ** Tilemap
#------------------------------------------------------------------------------
#  
#==============================================================================
class Tilemap
  #---------------------------------------------------------------------------
  # * Public Instance Variables
  #---------------------------------------------------------------------------
  method_defined?(:tileset)   || attr_accessor(:tileset)
  method_defined?(:priorities)|| attr_accessor(:priorities)
  method_defined?(:autotiles) || attr_sec_accessor(:autotiles,'Array.new')
end

#==============================================================================
# ** Table
#------------------------------------------------------------------------------
#  
#==============================================================================
class Table
  #--------------------------------------------------------------------------
  # * Public Instance Variable
  #--------------------------------------------------------------------------
  attr_sec_accessor :table_changes, :orig_value, 'Array.new'
  attr_accessor     :make_changes
  #--------------------------------------------------------------------------
  # * Alias Listing
  #--------------------------------------------------------------------------
  alias_sec_method :set_method, :"[]="
  #--------------------------------------------------------------------------
  # * Set Data
  #--------------------------------------------------------------------------
  def []=(*args)
    if @make_changes
      table_changes.push([*args]) && orig_value.push(self[*args[0..-2]])
      @make_changes = false
    end
    set_method(*args)
  end
  #--------------------------------------------------------------------------
  # * Reverse
  #--------------------------------------------------------------------------
  def reverse(rx=true,ry=true,rz=true)
    reverse = self.clone
    _x = (0...xsize).to_a
    _y = (0...ysize).to_a
    _z = (0...zsize).to_a
    _x.each do |x|
      _rx = rx ? _x[-1-x] : x
       ysize == 1 && (reverse[x] = self[_rx]) && next
      _y.each do |y|
        _ry = ry ? _y[-1-y] : y
        zsize == 1 && (reverse[x,y] = self[_rx,_ry]) && next
        _z.each do |z|
          _rz = rz ? _z[-1-z] : z
          reverse[x,y,z] = self[_rx,_ry,_rz]
        end
      end
    end
    reverse
  end
end

#==============================================================================
# ** RPG::Cache
#==============================================================================
ModCache = LiTTleDRAgo.cache
module ModCache
  #----------------------------------------------------------------------------
  # * Self
  #----------------------------------------------------------------------------
  class << self
    #--------------------------------------------------------------------------
    # * Constant
    #--------------------------------------------------------------------------
    AUTO_INDEX = [[
      [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]],
      
     [[27,28,33,34],  [49,50,55,56],  [51,52,57,58],  [49,52,55,58],
      [63,64,69,70],  [65,66,71,72],  [51,52,69,70],  [ 5, 6,33,12],
      [61,62,67,68],  [49,50,67,68],  [53,54,59,60],  [ 5, 6,11,34],
      [61,64,67,70],  [ 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]]
    ].freeze
    #--------------------------------------------------------------------------
    # * Public Instance Variable
    #--------------------------------------------------------------------------
    attr_sec_reader :cache, 'Hash.new'
    #--------------------------------------------------------------------------
    # * New method: autotile_cr_tilemap
    #--------------------------------------------------------------------------
    def autotile_cr_tilemap(filename)
      key = "Graphics/Autotiles/CR#{filename}"
      if !@cache.include?(key) || @cache[key].disposed?
        @cache[key] = (filename=='') ? Bitmap.new(128,96) : autotile(filename)
        new_bm = self.format_autotiles(@cache[key], filename)
        @cache[key].dispose
        @cache[key] = new_bm
        @cache[key].instance_variable_set(:@autotile_name, filename)
      end
      return @cache[key]
    end
    #--------------------------------------------------------------------------
    # * New method: include?
    #--------------------------------------------------------------------------
    unless method_defined?(:include?)
      def include?(key)
        @cache[key] && !@cache[key].disposed?
      end
    end
    #--------------------------------------------------------------------------
    # * New method: format_autotiles
    #--------------------------------------------------------------------------
    def format_autotiles(bitmap, filename)
      if bitmap.height > 32
        frames = bitmap.width / 96
        index = bitmap.height == 192 ? AUTO_INDEX[1] : AUTO_INDEX[0]
        template = Bitmap.new(256*frames,192)
        frames.times {|a| (0...6).each { |i| (0...8).each { |j|
          index[8*i+j].each { |number|
            number -= 1
            x, y = 16 * (number % 6), 16 * (number / 6)
            ox, oy = (32 * j + x % 32) + (a * 256), 32 * i + y % 32
            rect = Rect.new(x + (a * 96), y, 16, 16)
            template.blt(ox, oy, bitmap, rect)
        }}}}
        return template
      else
        return bitmap
      end
    end
    #--------------------------------------------------------------------------
    # * New method: tile
    #--------------------------------------------------------------------------
    unless method_defined?(:format_tile)
      def format_tile(bitmap, tile_id, hue)
        filename = bitmap.pathname
        key = [filename, tile_id, hue]
        unless include?(key)
          @cache[key] = empty_bitmap
          x = (tile_id - 384) % 8 * 32
          y = (tile_id - 384) / 8 * 32
          rect = Rect.new(x, y, 32, 32)
          @cache[key].blt(0, 0, bitmap, rect)
          @cache[key].hue_change(hue)
        end
        @cache[key]
      end
    end
    #--------------------------------------------------------------------------
    # * New method: clear_tile_cache
    #--------------------------------------------------------------------------
    def clear_tile_cache
      @cache ||= {}
      @cache.reject! do |keys|
        keys.is_a?(Array) && keys.size == 3 &&
        keys[0].is_a?(String) && keys[0].downcase["tilemap"]
      end
      GC.start
    end
  end
end

#==============================================================================
# ** Bitmap
#------------------------------------------------------------------------------
#  
#==============================================================================
class Bitmap
  #--------------------------------------------------------------------------
  # * Public Instance Variable
  #--------------------------------------------------------------------------
  attr_sec_accessor :pathname, 'String.new'
  #--------------------------------------------------------------------------
  # ● Alias Method
  #--------------------------------------------------------------------------
  $@ || alias_method(:cr_path_init, :initialize)
  #--------------------------------------------------------------------------
  # ● Object Initialization
  #--------------------------------------------------------------------------
  def initialize(*args)
    @pathname = args.at(0) if args.at(0).is_a?(String)
    cr_path_init(*args)
  end
end
#==============================================================================
# ** RPG::Weather
#------------------------------------------------------------------------------
#  A class for weather effects (rain, storm, and snow). It is used within the
# Spriteset_Map class.
#==============================================================================
CRWeather = LiTTleDRAgo::VX ? Spriteset_Weather : RPG::Weather
class CRWeather
  #--------------------------------------------------------------------------
  # * Public Instance Variable
  #--------------------------------------------------------------------------
  attr_reader :viewport
  attr_accessor :zoom_x, :zoom_y
  #--------------------------------------------------------------------------
  # * Alias Listing
  #--------------------------------------------------------------------------
  $@ || alias_method(:init_custom_resolution, :initialize)
  #--------------------------------------------------------------------------
  # * Aliased method: initialize
  #--------------------------------------------------------------------------
  def initialize(viewport)
    @viewport = viewport
    init_custom_resolution(@viewport)
  end
  #--------------------------------------------------------------------------
  # * Overwriten method: update
  #--------------------------------------------------------------------------
  def update
    return if @type == 0
    return if $game_map && $game_map.screen_is_solid?
    update_screen if respond_to?(:update_screen)
    @sprites.each {|sprite| update_sprite(sprite) }
  end
  #--------------------------------------------------------------------------
  # * Update Sprite
  #--------------------------------------------------------------------------
  def update_sprite(sprite)
    sprite.ox = @ox
    sprite.oy = @oy
    case @type
    when 1, :rain  then update_sprite_rain(sprite)
    when 2, :storm then update_sprite_storm(sprite)
    when 3, :snow  then update_sprite_snow(sprite)
    end
    create_new_particle(sprite) if sprite.opacity < 64
  end
  #--------------------------------------------------------------------------
  # * Update Sprite [Rain]
  #--------------------------------------------------------------------------
  def update_sprite_rain(sprite)
    sprite.bitmap = @rain_bitmap
    sprite.x -= 2 * sprite.zoom_x
    sprite.y += 16 * sprite.zoom_y
    sprite.opacity -= 8
  end
  #--------------------------------------------------------------------------
  # * Update Sprite [Storm]
  #--------------------------------------------------------------------------
  def update_sprite_storm(sprite)
    sprite.bitmap = @storm_bitmap
    sprite.x -= 8 * sprite.zoom_x
    sprite.y += 16 * sprite.zoom_y
    sprite.opacity -= 12
  end
  #--------------------------------------------------------------------------
  # * Update Sprite [Snow]
  #--------------------------------------------------------------------------
  def update_sprite_snow(sprite)
    sprite.bitmap = @snow_bitmap
    sprite.x -= 2 * sprite.zoom_x
    sprite.y += 8 * sprite.zoom_y
    sprite.opacity -= 8
  end
  #--------------------------------------------------------------------------
  # * Create New Particle
  #--------------------------------------------------------------------------
  def create_new_particle(sprite)
    sprite.x = rand(Graphics.width + 100) - 100 + @ox
    sprite.y = rand(Graphics.height + 200) - 200 + @oy
    sprite.zoom_x = @zoom_x || 1
    sprite.zoom_y = @zoom_y || 1
    sprite.x *= sprite.zoom_x
    sprite.y *= sprite.zoom_y
    sprite.opacity = 160 + rand(96)
  end
  #---------------------------------------------------------------------------
  # * New method: method_missing
  #---------------------------------------------------------------------------
  def method_missing(val,*a,&b)
    en = @sprites.flatten.find_all {|s|s.respond_to?(val.to_sym)}
    if en.empty?
      text = "Undefined method #{val} at #{self.inspect}"
      raise(NoMethodError,text,caller(1))
    end
    return en.map {|s| s.send(val.to_sym,*a,&b)}
  end  
end
  
#==============================================================================
# ** Plane
#------------------------------------------------------------------------------
#  This class is the rewrite of the default plane class
#==============================================================================

class CRPlane < Sprite
  #---------------------------------------------------------------------------
  # * Public Instance Variable
  #---------------------------------------------------------------------------
  attr_reader :bitmap
  #---------------------------------------------------------------------------
  # * New method: z=
  #---------------------------------------------------------------------------
  def z=(z)
    super(z * 1000)
  end
  #---------------------------------------------------------------------------
  # * New method: ox=
  #---------------------------------------------------------------------------
  def ox=(ox)
    return if $game_map && $game_map.screen_is_solid?
    return if bitmap.nil? || bitmap.disposed?
    super(ox % bitmap.width)  if bitmap.is_a?(Bitmap)
  end
  #---------------------------------------------------------------------------
  # * New method: oy=
  #---------------------------------------------------------------------------
  def oy=(oy)
    return if $game_map && $game_map.screen_is_solid?
    return if bitmap.nil? || bitmap.disposed?
    super(oy % bitmap.height) if bitmap.is_a?(Bitmap)
  end
  #---------------------------------------------------------------------------
  # * New method: dispose
  #---------------------------------------------------------------------------
  def dispose
    @plane && (@plane.disposed? || @plane.dispose)
    super unless disposed?
  end
  #---------------------------------------------------------------------------
  # * New method: bitmap=
  #---------------------------------------------------------------------------
  def bitmap=(tile)
    return if @bitmap == tile
    @bitmap = tile
    if @bitmap.is_a?(Bitmap)
      xx = 1 + (Graphics.width.to_f / tile.width).ceil
      yy = 1 + (Graphics.height.to_f / tile.height).ceil
      @plane.dispose if @plane.respond_to?(:dispose) && @plane.not.disposed?
      @plane = Bitmap.new(@bitmap.width * xx, @bitmap.height * yy)
      (0..xx).each {|x| (0..yy).each {|y|
        @plane.blt(x * @bitmap.width, y * @bitmap.height, @bitmap, @bitmap.rect)
      }}
      super(@plane)
    else
      super(nil)
    end
  end
  #---------------------------------------------------------------------------
  # * Undefine methods dealing with coordinates to do nothing.
  #---------------------------------------------------------------------------
  undef :x, :x=, :y, :y=   if method_defined?(:x)
end

#==============================================================================
# ** Viewport
#------------------------------------------------------------------------------
#  
#==============================================================================
class Viewport
  #--------------------------------------------------------------------------
  # * Overwriten method: update_viewport_sizes
  #--------------------------------------------------------------------------
  def update_viewport_sizes
    map = $game_map
    w, h = Graphics.width, Graphics.height
    hor = $game_map.loop_horizontal?
    ver = $game_map.loop_vertical?
    _w = ($game_map.width  * 32 * $game_map.zoom_x).floor
    _h = ($game_map.height * 32 * $game_map.zoom_y).floor
    dx = w > _w && !hor ? ((w - _w).floor.abs / 32) * 16 : 0
    dw = hor ? w : [w, $game_map.width  * 32 * $game_map.zoom_x].min  
    dy = h > _h && !ver ? ((h - _h).floor.abs / 32) * 16 : 0
    dh = ver ? h : [h, $game_map.height * 32 * $game_map.zoom_y].min
    resize(Rect.new(dx, dy, dw, dh))
  end
end
#==============================================================================
# ** ZTilemap
#------------------------------------------------------------------------------
#  This class is the rewrite of the default tilemap class
#==============================================================================

class ZTilemap  
  #---------------------------------------------------------------------------
  # * Public Instance Variables
  #---------------------------------------------------------------------------
  attr_reader       :map_data,  :viewport
  attr_accessor     :tileset,   :tone,    :priorities, :sprite_compact
  attr_sec_accessor :autotiles, 'Array.new'
  attr_sec_accessor :ox, :oy,   :zoom_x,  :zoom_y, :hue, 'Integer(1)'
  attr_sec_accessor :opacity,  'Integer(255)'
  attr_sec_reader   :layers, :bitmap_layers, :extra_map_data, 'Array.new'
  #---------------------------------------------------------------------------
  # * Redirect Listing
  #---------------------------------------------------------------------------
  redirect_method :width,       '$game_map.screen_tile_x + 2'
  redirect_method :height,      '$game_map.screen_tile_y + 2'
  #---------------------------------------------------------------------------
  # * Define Sec Listing
  #---------------------------------------------------------------------------
  define_sec_method(:all_sprites) { layers.flatten.select {|s| is_sprite?(s)}}
  define_sec_method(:is_sprite?)  { |s|  s.is_a?(Sprite) && s.not.disposed?  }
  #---------------------------------------------------------------------------
  # * Alias Listing
  #---------------------------------------------------------------------------
  alias_method :bitmaps, :autotiles
  #---------------------------------------------------------------------------
  # * Object Initialization
  #---------------------------------------------------------------------------
  def initialize(viewport)
    @viewport       = viewport
    @sprite_compact = false#LiTTleDRAgo::SPRITE_COMPACT
    create_sprites
    create_carrot
  end
  #---------------------------------------------------------------------------
  # * New method: create_sprites
  #---------------------------------------------------------------------------
  def create_sprites
    6.times do |i|
      layers ||= []
      (i % 6 == 0 ? 1 : height).times do |s|
        layers = Sprite.new(@viewport) unless is_sprite?(layers)
      end
      layers.each_with_index do |s,r|
        next unless is_sprite?(s)
        s.y = r * 32 * zoom_y      
        s.z = (i % 6 == 0) ? 0 : (r * 32 + 32 + (i % 6) * 32)
        s.mirror = $game_map.reverse
      end
    end
  end
  #---------------------------------------------------------------------------
  # * New method: create_carrot
  #---------------------------------------------------------------------------
  def create_carrot
    @draw_tiles = carrot do |x,y,data,prio|
      [0,1,2].each do |r|
        if (id = data[x,y,r]).to_i == 0 || (layer = prio[id]).nil?
          next
        elsif @layer_clear && @layer_clear.not.include?(layer)
          @bitmap_layers[layer].fill_rect(x*32,y*32,32,32,Color.erase)
          @layer_clear.push(layer)
        end
        refresh_tiles(x,y,r,id)
      end
    end
    @change_tone         = carrot {|s| all_sprites.tone    = (@tone = s)   }
    @change_opacity      = carrot {|s| all_sprites.opacity = (@opacity = s)}
    @change_autotile_hue = carrot do |a,old,hue|
      [old.to_i != 0 && a.hue_change((old - 360).abs)] && a.hue_change(hue)
    end
  end
  #---------------------------------------------------------------------------
  # * New method: ox=, oy=, zoom_x=, zoom_y=
  #---------------------------------------------------------------------------
  [:ox, :oy, :zoom_x, :zoom_y].each do |a|
    meth = "def %1$s=(%1$s) (@%1$s != %1$s) && (@%1$s = %1$s) && %2$s end"
    module_eval(sprintf(meth, a ,'adjust_sprites'))
  end
  #---------------------------------------------------------------------------
  # * New method: tone=
  #---------------------------------------------------------------------------
  def tone=(*tone)
    new_tone = tone.flatten.size == 4 ? Tone.new(*tone.flatten) :
               tone.first.is_a?(Tone) ? tone.first : nil
    @tone.to_s == new_tone.to_s || @change_tone.call(new_tone.clone)
  end
  #---------------------------------------------------------------------------
  # * New method: opacity=
  #---------------------------------------------------------------------------
  def opacity=(opacity)
    opacity = [[opacity.round,255].min,0].max
    @opacity == opacity || @change_opacity.call(opacity)
  end
  #---------------------------------------------------------------------------
  # * New method: hue=
  #---------------------------------------------------------------------------
  def hue=(hue)
    return if @hue == (hue % 360)
    old = self.hue
    @hue = hue % 360
    all_autotiles = @autotiles + extra_map_data.map {|m| m[:autotiles]}.flatten
    @change_autotile_hue.call(all_autotiles.uniq, old, @hue)
    refresh     
  end
  #---------------------------------------------------------------------------
  # * New method: Adjust Sprites
  #---------------------------------------------------------------------------
  def adjust_sprites
    @times_compact ||= []
    @layers_used && @layers.size.times do |i|
      layer = @layers
      (i % 6 == 0 ? 1 : height).times do |r|
        sprite = layer[r]
        d = 32
        _r = 32 + (i % 6) * 32
        _y = r * 32 * zoom_y
        _z = i % 6 == 0 ? 0 : r * d + _r # (r * d + _r)
        unless is_sprite?(sprite)
          change = _y <= @viewport.height
          if @sprite_compact
            change &&= !char_out_range?(_r, (height-1)*d+_r)
            change &&= @layers_used > 0
          end
          change || next
          sprite = (layer[r] = Sprite.new(@viewport))
          sprite.bitmap  = bitmap_layers
          sprite.tone    = tone if tone
          sprite.opacity = opacity
          sprite.mirror  = $game_map.reverse
          sprite.zoom_x, sprite.zoom_y = zoom_x, zoom_y
        else
          change = _y > @viewport.height
          if (@times_compact ||= 0) < 10 && @sprite_compact
            change ||=  (r > 0 && char_out_range?(_r, (height-1)*d+_r))
            change ||=  (r > 0 && @layers_used == 0)
          end
          sprite.y, sprite.z = _y, _z.ceil
          change && [sprite.dispose, @times_compact += 1] && next
        end
        sprite.y, sprite.z = _y, _z.ceil
        _wd = @viewport.width/zoom_x
        _ox = sprite.mirror ? (sprite.bitmap.width-ox)-_wd  : (_wd+=10) && ox
        if layer.select { |s| is_sprite?(s) }.size == 1
          sprite.src_rect.set(_ox, oy, _wd, @viewport.height/zoom_x + 10)
        else
          sprite.src_rect.set(_ox, (oy + r*32), _wd, 33)
        end         
        sprite.zoom_x, sprite.zoom_y = zoom_x, zoom_y
      end
    end
  end
  #---------------------------------------------------------------------------
  # * New method: char_out_range?
  #---------------------------------------------------------------------------
  def char_out_range?(z1,z2)
    return false unless (s = $game_map.spriteset).is_a?(Spriteset_Map)
    s.character_sprites.all? do |d|
      d.not.disposed? && d.opacity > 0 && d.visible &&
      (d.z).not.between?(z1,z2)
    end
  end
  #---------------------------------------------------------------------------
  # * New method: Frame Dispose
  #---------------------------------------------------------------------------
  def dispose
    all_sprites.each   { |s| s.dispose }
    bitmap  = bitmap_layers
    bitmap += extra_map_data.map {|m| m[:autotiles]}.flatten - @autotiles
    bitmap += extra_map_data.map {|m| m[:tileset]}.flatten
    bitmap.compact.each { |s| s.disposed? || s.dispose }
    @layers.clear
    GC.start
  end
  #---------------------------------------------------------------------------
  # * New method: Change Map Data
  #---------------------------------------------------------------------------
  def map_data=(data)
    return if @map_data == data
    @map_data = data
    @map_data_reverse = data.reverse(true,false,false)
    6.times do |i|
      bitmap_layers.dispose if bitmap_layers && bitmap_layers.disposed?
      bitmap_layers =  Bitmap.new($game_map.width*32,$game_map.height*32)
      layers.each { |s| is_sprite?(s) && s.bitmap = bitmap_layers }
    end
    refresh
  end
  #---------------------------------------------------------------------------
  # * New method: Map Data
  #---------------------------------------------------------------------------
  def map_data
    $game_map.reverse ? @map_data_reverse : @map_data
  end
  #---------------------------------------------------------------------------
  # * New method: Change priorities
  #---------------------------------------------------------------------------
  def priorities=(priorities)
    return if @priorities == priorities
    @priorities = priorities
    refresh
  end
  #---------------------------------------------------------------------------
  # * New method: Frame Refresh
  #---------------------------------------------------------------------------
  def refresh   
    return unless @priorities && @map_data
    LiTTleDRAgo.cache.clear_tile_cache
    @animated_tiles   = []
    @unrefreshed_tile = []
    @layers_used      = []
    7.times do |i|
      @total_frames   = [] if i == 0
      @current_frame  = [] if i == 0
      bm = (@current_frame = @layers_used = 0) && autotiles
      bm.nil? && @total_frames = 1
      bm.nil? || @total_frames = bm.width / (bm.height > 32 ? 256 : 32)
      extra_map_data.each do |data|
        data[:total_frames]  = [] if i == 0
        data[:current_frame] = [] if i == 0
        bm = (data[:current_frame] = 0) && data[:autotiles]
        bm.nil? && data[:total_frames] = 1
        bm.nil? || data[:total_frames] = bm.width / (bm.height>32 ? 256 : 32)
      end
    end
    _w = @viewport.width
    _h = @viewport.height
    layers[0][0].src_rect.set(ox, oy, _w/zoom_x, _h/zoom_y )
    (0...map_data.xsize).each do |x|
      (0...map_data.ysize).each do |y|
        if in_range?(x,y)
          update_map_changes(x,y)
        else
          next if @unrefreshed_tile.include?([x,y])
          @unrefreshed_tile.push([x,y])
          @unrefreshed_tile.uniq!
        end
      end
    end
    adjust_sprites
  end
  #---------------------------------------------------------------------------
  # * New method: Refresh Tiles
  #---------------------------------------------------------------------------
  def refresh_tiles(x,y,z,i,d = nil)
    return if i.nil? || i == 0
    i < 384 ? refresh_autotile(x,y,z,i,d) : refresh_regular_tile(x,y,z,i,d)
  end
  #---------------------------------------------------------------------------
  # * New method: Refresh Autotile
  #---------------------------------------------------------------------------
  def refresh_autotile(x,y,z,id,data)
    layer  = data.nil? ? @priorities[id]        : data[:priorities][id]
    tframe = data.nil? ? @total_frames          : data[:total_frames]
    cframe = data.nil? ? @current_frame         : data[:current_frame]
    bitmap = data.nil? ? @autotiles.at(id/48-1) : data[:autotiles].at(id/48-1)
    return if bitmap.nil? || layer.nil?
    div = (fid = id / 48 - 1) &&(id % 48)
    if @animated_tiles.not.include?([x,y]) && tframe[fid] > 1
      @animated_tiles.push([x,y])
      @animated_tiles.uniq!
    end
    rect = Rect.new((div % 8)*32 + cframe[fid] * 256, (div / 8)*32, 32, 32)
    bitmap_layers[layer].blt(x*32, y*32, bitmap, rect)  
    @layers_used[layer] = [(@layers_used[layer] + 1) % 10000,1].max   
  end
  #---------------------------------------------------------------------------
  # * New method: Refresh Regular Tile
  #---------------------------------------------------------------------------
  def refresh_regular_tile(x,y,z,id,data)
    tileset = data.nil? ? @tileset        : data[:tileset]
    layer   = data.nil? ? @priorities[id] : data[:priorities][id]
    return if layer.nil? || tileset.not.is_a?(Bitmap)
    bitmap  = LiTTleDRAgo.cache.format_tile(tileset, id, hue)
    bitmap_layers[layer].blt(x*32, y*32, bitmap, Rect.new(0, 0, 32, 32))
    @layers_used[layer] = [(@layers_used[layer] + 1) % 10000, 1].max  
  end   
  #---------------------------------------------------------------------------
  # * New method: force_refresh
  #---------------------------------------------------------------------------
  def force_refresh
    refresh
    (@unrefreshed_tile ||= []).each {|x,y| update_map_changes(x,y)}
    (@unrefreshed_tile.clear)
  end
  #---------------------------------------------------------------------------
  # * New method: Frame Update
  #---------------------------------------------------------------------------
  def update
    update_map_data
    update_autotile
    update_unrefreshed_tile
  end
  #---------------------------------------------------------------------------
  # * New method: Update Unrefreshed Tile
  #---------------------------------------------------------------------------
  def update_unrefreshed_tile
    if @unrefreshed_tile && @unrefreshed_tile.not.empty?
      unrefreshed = @unrefreshed_tile.select { |x,y| in_range?(x,y) }
      if unrefreshed.not.empty?
        (unrefreshed).each {|x,y| update_map_changes(x,y)}
        (@unrefreshed_tile -= unrefreshed) && adjust_sprites
      end
    end
  end
  #---------------------------------------------------------------------------
  # * New method: Update Map Data
  #---------------------------------------------------------------------------
  def update_map_data
    if map_data.table_changes.not.empty?
      map_data.table_changes.each do|item|
        x,y,z,tile_id = item
        update_map_changes(x,y)
      end
      map_data.table_changes.clear
      map_data.make_changes = false
      adjust_sprites
    end
  end
  #---------------------------------------------------------------------------
  # * New method: Update the autotile
  #---------------------------------------------------------------------------
  def update_autotile
    return if $game_map.screen_is_solid?
    speed = $game_map.autotile_speed
    total = [(@autotile_total || 0) / 10, 0].max
    if speed > 0 && Graphics.frame_count % (speed + total) == 0
      7.times do |i|
        extra_map_data.each do |data|
          next if (total = data[:total_frames].at(i)) == 0
          data[:current_frame] = (data[:current_frame].at(i) + 1) % total
        end
        next if (total = @total_frames.at(i)) == 0
        @current_frame = (@current_frame.at(i) + 1) % total
      end
      animated = @animated_tiles.select { |x,y| in_range?(x,y) }
      animated.each {|x,y| update_map_changes(x,y) }
      @autotile_total = animated.size
    end
  end
  #---------------------------------------------------------------------------
  # * New method: in_range?
  #---------------------------------------------------------------------------
  def in_range?(x=nil,y=nil)
    return false if layers[0].nil? || layers[0][0].nil?
    rect = @layers[0][0].src_rect
    _x = x && (x * 32).between?(rect.x-32, rect.x + rect.width)
    _y = y && (y * 32).between?(rect.y-32, rect.y + rect.height)
    return _x && _y if x && y
    return _x if x
    return _y if y
    return false
  end
  #---------------------------------------------------------------------------
  # * New method: Update Map Changes
  #---------------------------------------------------------------------------
  def update_map_changes(x,y)
    @layer_clear ||= []
    @layer_clear.clear
    draw = [[x,y,map_data,priorities]]  
    draw += extra_map_data.map {|data|[x,y,data[:map].data,data[:priorities]]}
    draw.each {|data| @draw_tiles.call(*data)}
  end   
end
#==============================================================================
# ** Game_Character
#------------------------------------------------------------------------------
#  This class deals with characters. It's used as a superclass for the
#  determinants and map scrolling. Refer to "$game_player" for the one
#  Game_Player and Game_Event classes.
#==============================================================================
class Game_Character
  #--------------------------------------------------------------------------
  # * Alias Listing
  #--------------------------------------------------------------------------
  alias_sec_method(:screen_x_before_zoom, :screen_x)
  alias_sec_method(:screen_y_before_zoom, :screen_y)
  alias_sec_method(:screen_z_before_zoom, :screen_z)
  #--------------------------------------------------------------------------
  # * Aliased method: screen_x
  #--------------------------------------------------------------------------
  def screen_x(*args)
    screen_x_before_zoom(*args) * $game_map.zoom_x
  end
  #--------------------------------------------------------------------------
  # * Aliased method: screen_y
  #--------------------------------------------------------------------------
  def screen_y(*args)
    screen_y_before_zoom(*args) * $game_map.zoom_y
  end
  #--------------------------------------------------------------------------
  # * Aliased method: screen_z
  #--------------------------------------------------------------------------
  def screen_z(*args)
    if self.is_a?(Game_Event)
      return 999                  if @always_on_top
      return $1.to_i              if self.name[/\<Z:\s*([-]?\d+)\s*\>/i]
      return screen_z_tilemap_fix if screen_z_tilemap_fix.is_a?(Integer)
    end
    return screen_z_before_zoom(*args)
  end
  #--------------------------------------------------------------------------
  # * New method: screen_z_tilemap_fix
  #--------------------------------------------------------------------------
  def screen_z_tilemap_fix
    LiTTleDRAgo::CHARACTER_Z_FIX.each do |key,value|
      if value.is_a?(Array) && key.is_a?(Integer)
        return key if value.any?{|v|"#{v}".downcase == @character_name.downcase}
      elsif key.is_a?(Array) && value.is_a?(Integer)
        return value if key.any?{|v|"#{v}".downcase == @character_name.downcase}
      elsif (key.is_a?(String) || key.is_a?(Symbol)) && value.is_a?(Integer)
        return value if "#{key}".downcase == @character_name.downcase
      end
    end
    return nil
  end
end

#==============================================================================
# ** Sprite_Character
#------------------------------------------------------------------------------
#  This sprite is used to display the character.It observes the Game_Character
#  class and automatically changes sprite conditions.
#==============================================================================
class Sprite_Character
  #--------------------------------------------------------------------------
  # * Alias Listing
  #--------------------------------------------------------------------------
  alias_sec_method(:zoom_update_scrolling, :update)
  #--------------------------------------------------------------------------
  # * Aliased method: update
  #--------------------------------------------------------------------------
  def update(*args)
    if @old_character_zoom_x
      self.zoom_x = @old_character_zoom_x
      self.zoom_y = @old_character_zoom_y
    end
    zoom_update_scrolling(*args)
    @old_character_zoom_x = self.zoom_x
    @old_character_zoom_y = self.zoom_y
    self.zoom_x *= $game_map.zoom_x
    self.zoom_y *= $game_map.zoom_y
  end
  #--------------------------------------------------------------------------
  # * New method: in_range?
  #--------------------------------------------------------------------------
  unless method_defined?(:in_range?)
    def in_range?
      cw = self.src_rect ? self.src_rect.width : 32
      ch = self.src_rect ? self.src_rect.height : 32
      return @character.screen_x.round.between?(self.viewport.x - cw,
        self.viewport.x + self.viewport.width) &&
      @character.screen_y.round.between?(self.viewport.y - ch,
        self.viewport.y + self.viewport.height)
    end
  end
end

#==============================================================================
# ** 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_reader :character_sprites, :tilemap
  attr_reader :viewport1, :viewport2, :viewport3
  #--------------------------------------------------------------------------
  # * Alias Listing
  #--------------------------------------------------------------------------
  $@ || alias_method(:init_drgcr_tilemap, :initialize)
  alias_sec_method(:update_drgcr_tilemap, :update)
  #--------------------------------------------------------------------------
  # * Aliased method: initialize
  #--------------------------------------------------------------------------
  def initialize(*args)
    check_autotile_height
    init_drgcr_tilemap(*args)
  end
  #---------------------------------------------------------------------------
  # * New method: check_autotile_height
  #---------------------------------------------------------------------------
  def check_autotile_height
    return unless LiTTleDRAgo::XP
    $game_map.autotile_names.each do |autotile_name|
      bitmap = ModCache.autotile(autotile_name)
      [@force_tilemap_enabled = true] && break if bitmap.height == 192
    end
  end
  #--------------------------------------------------------------------------
  # * Aliased method: update
  #--------------------------------------------------------------------------
  def update(*args)
    adjust_viewport
    adjust_tilemap
    adjust_old_zoom
    update_drgcr_tilemap(*args)
    update_tilemap_zoom
  end
  #---------------------------------------------------------------------------
  # * New method: adjust_old_zoom
  #---------------------------------------------------------------------------
  def adjust_old_zoom
    if @old_fog_zoom_x
      @fog.zoom_x = @old_fog_zoom_x
      @fog.zoom_y = @old_fog_zoom_y
      @panorama.zoom_x = @old_panorama_zoom_x
      @panorama.zoom_y = @old_panorama_zoom_y
    end
  end
  #---------------------------------------------------------------------------
  # * New method: viewport_sprite
  #---------------------------------------------------------------------------
  def viewport_sprite(*v)
    v.collect! {|s| s.is_a?(Symbol) ? instance_variable_get(:"@#{s}") : s }
    v.reject!  {|s| s.not.is_a?(Viewport)}
    all = instance_variables.map {|s| instance_variable_get("#{s}")}.flatten
    all.select {|s| s.respond_to?(:viewport) && v.include?(s.viewport)}
  end
  #---------------------------------------------------------------------------
  # * New method: change_tilemap_tone
  #---------------------------------------------------------------------------
  def change_tilemap_tone(tone = Tone.new(0,0,0,0), *char)
    if tone.is_a?(Array) && (3..4) === tone.size
      result = $game_map.tilemap_tone = Tone.new(*tone)
    elsif tone.is_a?(Tone)
      result = $game_map.tilemap_tone = tone
    else
      return
    end
    sprite = viewport_sprite(:viewport1)
    sprite.reject! {|s| s.is_a?(Sprite_Character)}
    sprite.each    {|s| s.tone = result if s.respond_to?(:tone=) }
    change_character_tone(tone, *char) unless char.empty?
  end
  #---------------------------------------------------------------------------
  # * New method: change_character_tone
  #---------------------------------------------------------------------------
  def change_character_tone(tone = Tone.new(0,0,0,0), *char)
    char = char.collect {|c| c.is_a?(Range) ? c.to_a : c}.flatten
    char = char.collect {|c| c.is_a?(Range) ? c.to_a : c}.flatten
    char.collect! {|c| c.is_a?(Game_Character) ? c :
                       $game_map.interpreter.get_character(c)}
    sprite = viewport_sprite(:viewport1)
    sprite.reject! {|s| s.not.is_a?(Sprite_Character) }
    sprite.reject! {|s| char.not.include?(s.character)}
    if tone.is_a?(Array) && (3..4) === tone.size
      sprite.tone(:tone=, Tone.new(*tone))
    elsif tone.is_a?(Tone)
      sprite.send(:tone=, tone)
    end
  end
  #--------------------------------------------------------------------------
  # * New method: reload_tilemap
  #--------------------------------------------------------------------------
  def reload_tilemap
    return [dispose_tilemap, create_tilemap] if LiTTleDRAgo::VXA
    @tilemap.respond_to?(:dispose) && @tilemap.dispose
    7.times do |i|
      auto = @tilemap.autotiles
      auto.respond_to?(:dispose) && (auto.disposed? || auto.dispose)
    end
    res = tilemap_enabled? ? ZTilemap : Tilemap
    @tilemap = res.new(@viewport1)
    @tilemap.tileset = ModCache.tileset($game_map.tileset_name)
    7.times do |i|
      autotile_name = $game_map.autotile_names
      @tilemap.autotiles = @tilemap.is_a?(ZTilemap) ?
      ModCache.autotile_cr_tilemap(autotile_name) :
      ModCache.autotile(autotile_name)
    end
    update_tilemap_effect
    @tilemap.priorities = $game_map.priorities
    @tilemap.map_data   = $game_map.data
    @tilemap.update
    @viewport_screen_width = 0
  end   
  #--------------------------------------------------------------------------
  # * New method: reload_plane
  #--------------------------------------------------------------------------
  def reload_plane
    z1  = @panorama.respond_to?(:z) ? @panorama.z : -1000
    z2  = @fog.respond_to?(:z)      ? @fog.z      :  5000
    z1 /= 1000 if @panorama.is_a?(CRPlane)
    z2 /= 1000 if @fog.is_a?(CRPlane)
    res =  plane_enabled? ? CRPlane : Plane
    bitmap1 = @panorama.respond_to?(:bitmap) ? @panorama.bitmap : nil
    bitmap2 = @fog.respond_to?(:bitmap)      ? @fog.bitmap      : nil
    @panorama.respond_to?(:dispose) && @panorama.dispose
    @fog.respond_to?(:dispose) && @fog.dispose      
    @panorama = res.new(@viewport1)
    @fog      = res.new(@viewport1)
    @panorama.bitmap = bitmap1 if bitmap1.is_a?(Bitmap)
    @fog.bitmap      = bitmap2 if bitmap2.is_a?(Bitmap)
    @panorama.z, @fog.z = z1, z2
    @viewport_screen_width = 0
  end
  #--------------------------------------------------------------------------
  # * New method: update_tilemap_zoom
  #--------------------------------------------------------------------------
  def update_tilemap_zoom
    @weather.zoom_x      = $game_map.zoom_x
    @weather.zoom_y      = $game_map.zoom_y
    @old_fog_zoom_x      = @fog.zoom_x
    @old_fog_zoom_y      = @fog.zoom_y
    @old_panorama_zoom_x = @panorama.zoom_x
    @old_panorama_zoom_y = @panorama.zoom_y
    @fog.zoom_x         *= $game_map.zoom_x
    @fog.zoom_y         *= $game_map.zoom_y
    @panorama.zoom_x    *= $game_map.zoom_x
    @panorama.zoom_y    *= $game_map.zoom_y
    update_tilemap_effect
  end
  #--------------------------------------------------------------------------
  # * New method: update_tilemap_effect
  #--------------------------------------------------------------------------
  def update_tilemap_effect
    return if @tilemap.not.is_a?(ZTilemap)
    @tilemap.zoom_x  = $game_map.zoom_x
    @tilemap.zoom_y  = $game_map.zoom_y
    @tilemap.opacity = $game_map.tilemap_opacity
    @tilemap.hue     = $game_map.tilemap_hue
    @tilemap.tone    = $game_map.tilemap_tone
  end
  #--------------------------------------------------------------------------
  # * Overwriten method: viewport_size_change?
  #--------------------------------------------------------------------------
  def viewport_size_change?
    return true if @viewport_map_width  != $game_map.width  * $game_map.zoom_x
    return true if @viewport_map_height != $game_map.height * $game_map.zoom_y
    return true if @viewport_screen_width  != Graphics.width
    return true if @viewport_screen_height != Graphics.height
  end
  #--------------------------------------------------------------------------
  # * New method: adjust_viewport
  #--------------------------------------------------------------------------
  def adjust_viewport
    if viewport_size_change?
      @viewport_map_width     = $game_map.width * $game_map.zoom_x
      @viewport_map_height    = $game_map.height * $game_map.zoom_y
      @viewport_screen_width  = Graphics.width
      @viewport_screen_height = Graphics.height
      [@viewport1,@viewport2,@viewport3].compact.update_viewport_sizes
    end
  end
  #--------------------------------------------------------------------------
  # * New method: adjust_tilemap
  #--------------------------------------------------------------------------
  def adjust_tilemap
    if LiTTleDRAgo::XP
      if tilemap_enabled?
        reload_tilemap if @tilemap.is_a?(Tilemap)
      else
        reload_tilemap if @tilemap.is_a?(ZTilemap)
      end
    end
    if plane_enabled?
      reload_plane   if @panorama.is_a?(Plane)   || @fog.is_a?(Plane)
    else
      reload_plane   if @panorama.is_a?(CRPlane) || @fog.is_a?(CRPlane)
    end
  end
  #--------------------------------------------------------------------------
  # * New method: tilemap_enabled?
  #--------------------------------------------------------------------------
  def tilemap_enabled?
    return true if @force_tilemap_enabled
    return true unless LiTTleDRAgo::RGSS1
    return true unless @viewport1.width <= 640 && @viewport1.height <= 480
    return true unless (map = $game_map) && map.zoom_x * map.zoom_y == 1
    return true unless map.tilemap_opacity >= 255
    return true unless map.tilemap_hue <= 0
    return true unless map.tilemap_tone.to_s.get_int == 0
    return true if map.reverse
    return false  
  end
  #--------------------------------------------------------------------------
  # * New method: plane_enabled?
  #--------------------------------------------------------------------------
  def plane_enabled?
    return true unless LiTTleDRAgo::RGSS1
    return true unless @viewport1.width <= 640 && @viewport1.height <= 480
    return false
  end
end[/pre]

评分

参与人数 2赞 +2 收起 理由
Nil2018 + 1 塞糖
Dayn + 1 塞糖

查看全部评分

我是梅林,人称花之魔术师。
梦石
0
星屑
431
在线时间
43 小时
注册时间
2009-5-6
回帖
58
发表于 2019-8-23 17:25:08 | 显示全部楼层
本帖最后由 yumeyuuya 于 2019-8-23 21:41 编辑

谢谢楼主,经测试能在VA里用XP地图了,可是VA的地图编辑器并不显示……它只是用了黑魔法让VA读取XP的地图数据并在运行中显示。编辑时VA地图还是VA的样子。
如果要编辑事件的话,要找到某些位置只能对着XP编辑好的地图数格子?
===============================================
搜索到了旧帖子,感觉这个比较好,能在VA的地图编辑器里面能看得到。
https://rpg.blue/thread-397621-1-1.html
捕获2.PNG

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部