查看: 1965|回复: 11

[已经过期] 求一个对话框显示字同时伴有声音的脚本

[复制链接]
梦石
0
星屑
915
在线时间
107 小时
注册时间
2017-12-2
回帖
51
发表于 2018-2-10 12:08:21 | 显示全部楼层 |阅读模式

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

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

×
本帖最后由 wskai 于 2018-2-10 12:37 编辑

这是放在我的工程里出的错误

这是放在我的工程里出的错误
可以给个范例工程,不要FUKI对话框之类的,和我游戏的脚本冲突了还什么怎么了不清楚导致无法使用或是帮我解决一下也行,谢谢!!!!!!!

按图片顺序发布

在别的工程也不行,一个个脚本排查也排查不出来



[pre lang="ruby"]#==============================================================================
#
# ▼ Yami Engine Ace - 气泡对话框
# -- 最后更新: 2012.06.07
# -- 使用难度: Normal
# -- 需要脚本: 无
#
#==============================================================================

$imported = {} if $imported.nil?
$imported["YSE-PopMessage"] = true

#==============================================================================
# ▼ Updates
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# 2012.06.07 - Fixed Compatible: YEA - Ace Message System.
# 2012.05.11 - Fixed Message Position.
#            - Remove Requirement: YSE - Fix Events Order.
# 2012.05.07 - Fixed Face position.
#            - Added Requirement: YSE - Fix Events Order.
# 2012.04.06 - You can change Bubble Tag filename.
# 2012.03.28 - Fixed Default Message Position and Sizes.
# 2012.03.27 - Fixed Default Message.
# 2012.03.27 - Added Bubble Tag.
# 2012.03.25 - Fixed Escape Message.
# 2012.03.24 - Fixed Battle Message.
# 2012.03.24 - Rewrote script.
#
#==============================================================================
# ▼ 介绍
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# 本脚本可以将对话框改变为气泡对话框,使用"BubbleTag"作为气泡标志图片,放在:
# \Graphics\System 文件夹中.
# 需要配合脚本:Yami Engine Ace - Bug修复: 事件ID顺序 一起使用.
#==============================================================================
# ▼ 安装方式
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# 打开脚本编辑器,将本脚本拷贝/复制到一个在▼ 插件脚本之下▼ Main之上的新
# 脚本页/槽中.记得保存你的工程以使脚本生效.
#
# -----------------------------------------------------------------------------
# 文本代码 - 可以在文字窗口中使用的代码.
# -----------------------------------------------------------------------------
#     代码:    效果:
#    \bm[x]    - 在x号事件处显示气泡对话框. *注释
#    \cbm      - 关闭气泡对话框效果.
#
#              *注释: 设定为 0 则会在角色处显示.
#
#==============================================================================
# ▼ 兼容性
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# 本脚本仅为RPG Maker VX Ace编写.极不可能在无任何修改的情况下运行于RPG Maker VX.
#
#==============================================================================

module YSE
  module POP_MESSAGE
   
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # - 视觉效果设置 -
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    LIMIT = { # 开始.
      :limit_width    =>  0,  # 宽度限制,设定为0则无限制.
      :limit_line     =>  6,  # 行数限制,设定为0则无限制.
    } # 结束.
   
    POSITION = { # 开始.
      :x_buffer       =>  0,   #调整气泡对话框的x坐标
      :y_buffer       =>  -36, #调整气泡对话框的y坐标
      :face_x_buffer  =>  8,   #调整角色肖像图的x坐标
      :face_y_buffer  =>  24,  #调整角色肖像图的y坐标
      :tag_y_buffer   =>  -6,  #调整角色肖像图的y坐标
      :name_x_buffer  =>  112, #调整名称窗口的x坐标,需要脚本 YEA - 文本系统.
    } # 结束.
   
    EFFECT = { # 开始.
      :fade_face       =>  true, #是否显示角色肖像图淡入效果
      :move_face       =>  true, #是否显示角色肖像图移动效果
      :use_bubble_tag  =>  true, #是否显示气泡标志图片
      :bubble_tag_name => "BubbleTag",#气泡标志图片的文件名
    } # 结束.
   
  end
end

#==============================================================================
# ▼ 编辑以下内容可能会出现电脑损坏、死机,电脑主人脑袋爆炸、昏迷、死亡或口臭
# 所以编辑了后果自负。
#==============================================================================

#==============================================================================
# ■ Spriteset_Map
#==============================================================================

class Spriteset_Map
  
  #--------------------------------------------------------------------------
  # public instance variables
  #--------------------------------------------------------------------------
  attr_accessor :character_sprites
  
end # Spriteset_Map

#==============================================================================
# ■ Window_Message_Face
#==============================================================================

class Window_Message_Face < Window_Base
  
  #--------------------------------------------------------------------------
  # initialize
  #--------------------------------------------------------------------------
  def initialize
    super(0, 0, 120, 120)
    self.opacity = 0
    @face_name = ""
    @face_index = 0
    @move_x = 0
    close
  end
  
  #--------------------------------------------------------------------------
  # message_window=
  #--------------------------------------------------------------------------
  def message_window=(window)
    @message_window = window
  end
  
  #--------------------------------------------------------------------------
  # set_face
  #--------------------------------------------------------------------------
  def set_face
    contents.clear
    return unless @message_window
    if !$game_message.face_name.empty?
      draw_face($game_message.face_name, $game_message.face_index, 0, 0)
      set_position
      show_face
    else
      hide_face
    end
  end
  
  #--------------------------------------------------------------------------
  # set_position
  #--------------------------------------------------------------------------
  def set_position
    return unless @message_window
    self.x = @message_window.x
    self.y = @message_window.y - 96
    self.x += YSE::POP_MESSAGE::POSITION[:face_x_buffer]
    self.y += YSE::POP_MESSAGE::POSITION[:face_y_buffer]
    self.y += (@message_window.real_lines - 1) * 24
    self.z = @message_window.z + 1
    if (@face_name != $game_message.face_name || @face_index != $game_message.face_index)
      if YSE::POP_MESSAGE::EFFECT[:move_face]
        @move_x = 30
        self.x -= 30
      end
      @face_name = $game_message.face_name
      @face_index = $game_message.face_index
      self.contents_opacity = 0 if YSE::POP_MESSAGE::EFFECT[:fade_face]
    end
  end
  
  #--------------------------------------------------------------------------
  # show_face
  #--------------------------------------------------------------------------
  def show_face
    open
  end
  
  #--------------------------------------------------------------------------
  # hide_face
  #--------------------------------------------------------------------------
  def hide_face
    contents.clear
    close
  end
  
  #--------------------------------------------------------------------------
  # update
  #--------------------------------------------------------------------------
  def update
    super
    self.contents_opacity += 15 if self.contents_opacity < 255
    unless @move_x <= 0
      self.x += 2
      @move_x -= 2
    end
  end
  
end # Sprite_Message_Face

#==============================================================================
# ■ Window_Message
#==============================================================================

class Window_Message < Window_Base
  
  #--------------------------------------------------------------------------
  # new method: face_window=
  #--------------------------------------------------------------------------
  def face_window=(window)
    @face_window = window
  end
  
  #--------------------------------------------------------------------------
  # new method: bubble_tag=
  #--------------------------------------------------------------------------
  def bubble_tag=(sprite)
    @bubble_tag = sprite
  end
  
  #--------------------------------------------------------------------------
  # new method: message_escape_characters_pop_message
  #--------------------------------------------------------------------------
  def message_escape_characters_pop_message(result)
    result.gsub!(/\eBM\[(\d+)\]/i) { event_pop_message_setup($1.to_i, false) }
    result.gsub!(/\eBMF\[(\d+)\]/i) { event_pop_message_setup($1.to_i, true) }
    result.gsub!(/\eCBM/i) { event_pop_message_setup(nil, false) }
    result
  end
  
  #--------------------------------------------------------------------------
  # alias method: convert_escape_characters
  #--------------------------------------------------------------------------
  alias yse_convert_escape_characters_pm convert_escape_characters
  def convert_escape_characters(text)
    result = yse_convert_escape_characters_pm(text)
    result = message_escape_characters_pop_message(result)
    result
  end
  
  #--------------------------------------------------------------------------
  # new method: event_pop_message_setup
  #--------------------------------------------------------------------------
  def event_pop_message_setup(event_id, follower = false)
    if follower && $game_player.followers[event_id].nil?
      @event_pop_id = nil
      @event_pop_follower = false
      return ""
    end
    @event_pop_follower = follower
    @event_pop_id = event_id
    return ""
  end
  
  #--------------------------------------------------------------------------
  # new method: set_face_position
  #--------------------------------------------------------------------------
  def set_face_position
    return unless SceneManager.scene_is?(Scene_Map)
    return unless @event_pop_id
    return unless @face_window
    contents.clear
    @face_window.set_face
    return unless $imported["YEA-MessageSystem"]
    return if @face_window.close?
    #@name_window.x = self.x + YSE::POP_MESSAGE::POSITION[:face_x_buffer] + YSE::POP_MESSAGE::POSITION[:name_x_buffer] if (@name_position == 1 || @name_position == 2)
  end
  
  #--------------------------------------------------------------------------
  # alias method: new_page
  #--------------------------------------------------------------------------
  alias window_message_new_page_pm_yse new_page
  def new_page(text, pos)
    window_message_new_page_pm_yse(text, pos)
    set_face_position
  end
  
  #--------------------------------------------------------------------------
  # alias method: close
  #--------------------------------------------------------------------------
  alias pop_message_close close
  def close
    pop_message_close
    return unless SceneManager.scene_is?(Scene_Map)
    return unless @event_pop_id
    @event_pop_id = nil
    @event_pop_follower = false
    @face_window.hide_face
    return unless YSE::POP_MESSAGE::EFFECT[:use_bubble_tag]
    @bubble_tag.visible = false if @bubble_tag
  end
  
  #--------------------------------------------------------------------------
  # alias method: open_and_wait
  #--------------------------------------------------------------------------
  alias pop_message_open_and_wait open_and_wait
  def open_and_wait
    pop_message_open_and_wait
    return unless YSE::POP_MESSAGE::EFFECT[:use_bubble_tag]
    @bubble_tag.visible = true if @event_pop_id && @bubble_tag
  end
  
  #--------------------------------------------------------------------------
  # alias method: process_all_text
  #--------------------------------------------------------------------------
  alias pop_message_process_all_text process_all_text
  def process_all_text
    @event_pop_id = nil
    convert_escape_characters($game_message.all_text)
    update_placement
    adjust_pop_message($game_message.all_text)
    pop_message_process_all_text
  end

  #--------------------------------------------------------------------------
  # alias method: update_placement
  #--------------------------------------------------------------------------
  alias event_pop_message_update_placement update_placement
  def update_placement
    if SceneManager.scene_is?(Scene_Map)
      if @event_pop_id.nil?
        fix_default_message
        event_pop_message_update_placement
      elsif @event_pop_id == 0
        character = $game_player
        self.y = character.screen_y - self.height + YSE::POP_MESSAGE::POSITION[:y_buffer]
        self.x = character.screen_x - self.width / 2 + YSE::POP_MESSAGE::POSITION[:x_buffer]
        fix_position_bubble(character)
        set_bubble_tag(character)
      elsif @event_pop_id > 0
        hash = @event_pop_follower ? $game_player.followers : $game_map.events
        character = hash[@event_pop_id]
        self.y = character.screen_y - self.height + YSE::POP_MESSAGE::POSITION[:y_buffer]
        self.x = character.screen_x - self.width / 2 + YSE::POP_MESSAGE::POSITION[:x_buffer]
        fix_position_bubble(character)
        set_bubble_tag(character)
      end
    else
      event_pop_message_update_placement
    end
  end
  
  #--------------------------------------------------------------------------
  # new method: fix_default_message
  #--------------------------------------------------------------------------
  def fix_default_message
    self.width = window_width
    self.height = window_height
    self.x = 0
    @face_window.hide_face if @face_window
    create_contents
    return unless YSE::POP_MESSAGE::EFFECT[:use_bubble_tag]
    @bubble_tag.visible = false if @bubble_tag
  end
  
  #--------------------------------------------------------------------------
  # new method: fix_position_bubble
  #--------------------------------------------------------------------------
  def fix_position_bubble(character)
    end_x = self.x + self.width
    end_y = self.y + self.height
    self.x = 0 if self.x < 0
    self.y = character.screen_y if self.y < 0
    self.x = Graphics.width - self.width if end_x > Graphics.width
    self.y = Graphics.height - self.height if end_y > Graphics.height
  end
  
  #--------------------------------------------------------------------------
  # new method: set_bubble_tag
  #--------------------------------------------------------------------------
  def set_bubble_tag(character)
    return unless YSE::POP_MESSAGE::EFFECT[:use_bubble_tag]
    return unless @bubble_tag
    up = self.y == character.screen_y
    self.y += up ? @bubble_tag.height / 2 : -@bubble_tag.height / 2
    @bubble_tag.x = character.screen_x - @bubble_tag.width / 2
    if up
      @bubble_tag.src_rect.set(0, @bubble_tag.height, @bubble_tag.width, @bubble_tag.height)
      @bubble_tag.y = self.y - @bubble_tag.height - YSE::POP_MESSAGE::POSITION[:tag_y_buffer]
    else
      @bubble_tag.src_rect.set(0, 0, @bubble_tag.width, @bubble_tag.height)
      @bubble_tag.y = self.y + self.height + YSE::POP_MESSAGE::POSITION[:tag_y_buffer]
    end
  end
  
  #--------------------------------------------------------------------------
  # new method: cal_number_line
  #--------------------------------------------------------------------------
  def cal_number_line(text)
    result = 0
    text.each_line { result += 1 }
    return result
  end
  
  #--------------------------------------------------------------------------
  # new method: cal_width_line
  #--------------------------------------------------------------------------
  def cal_width_line(text)
    result = 0
    text.each_line { |line|
      result = text_size(line).width if result < text_size(line).width
    }
    return result
  end

  #--------------------------------------------------------------------------
  # alias method: adjust_message_window_size
  #--------------------------------------------------------------------------
  if $imported["YEA-MessageSystem"]
  alias yse_pop_message_adjust_message_window_size adjust_message_window_size
  def adjust_message_window_size
    start_name_window if @event_pop_id
    return if @event_pop_id
    yse_pop_message_adjust_message_window_size
  end
  end
  
  #--------------------------------------------------------------------------
  # new method: adjust_pop_message
  #--------------------------------------------------------------------------
  def adjust_pop_message(text = " ")
    return unless SceneManager.scene_is?(Scene_Map)
    unless @event_pop_id
      if $imported["YEA-MessageSystem"]
        #adjust_message_window_size
      end
      return
    end
    n_line = cal_number_line(text)
    n_line = YSE::POP_MESSAGE::LIMIT[:limit_line] if YSE::POP_MESSAGE::LIMIT[:limit_line] > 0 && cal_number_line(text) > YSE::POP_MESSAGE::LIMIT[:limit_line]
    @real_lines = n_line
    self.height = fitting_height(n_line)
    self.width = cal_width_line(text) + 24
    self.width += new_line_x
    if self.width > YSE::POP_MESSAGE::LIMIT[:limit_width] && YSE::POP_MESSAGE::LIMIT[:limit_width] > 0
      self.width = YSE::POP_MESSAGE::LIMIT[:limit_width]
    end
    create_contents
    update_placement
  end
  
  #--------------------------------------------------------------------------
  # overwrite method: new_line_x
  #--------------------------------------------------------------------------
  def new_line_x
    if $game_message.face_name.empty?
      return 0
    else
      result = YSE::POP_MESSAGE::POSITION[:face_x_buffer]
      p_x = $imported["YEA-MessageSystem"] ? YEA::MESSAGE::FACE_INDENT_X : 112
      result += p_x
      return result
    end
  end
  
  #--------------------------------------------------------------------------
  # new method: real_lines
  #--------------------------------------------------------------------------
  def real_lines
    @real_lines
  end
  
end # Window_Message

#==============================================================================
# ■ Scene_Map
#==============================================================================

class Scene_Map < Scene_Base
  
  #--------------------------------------------------------------------------
  # alias method: create_message_window
  #--------------------------------------------------------------------------
  alias yse_pm_create_message_window create_message_window
  def create_message_window
    yse_pm_create_message_window
    @face_window = Window_Message_Face.new
    @face_window.message_window = @message_window
    if YSE::POP_MESSAGE::EFFECT[:use_bubble_tag]
      @bubble_tag_sprite = Sprite.new
      @bubble_tag_sprite.visible = false
      @bubble_tag_sprite.bitmap = Cache.system(YSE::POP_MESSAGE::EFFECT[:bubble_tag_name])
      @bubble_tag_sprite.src_rect.set(0, 0, @bubble_tag_sprite.width, @bubble_tag_sprite.height / 2)
      @message_window.bubble_tag = @bubble_tag_sprite
    end
    @message_window.face_window = @face_window
  end
  
  #--------------------------------------------------------------------------
  # alias method: dispose_spriteset
  #--------------------------------------------------------------------------
  alias pop_message_dispose_spriteset dispose_spriteset
  def dispose_spriteset
    pop_message_dispose_spriteset
    return unless @bubble_tag_sprite
    @bubble_tag_sprite.dispose
  end
  
end # Scene_Map

#==============================================================================
#
# ▼ End of File
#
#==============================================================================[/pre]










[pre lang="ruby"]#==============================================================================
#
# ▼ Yanfly Engine Ace - 文本系统 v1.05
# -- 最后更新: 2012.01.13
# -- 使用难度: 普通
# -- 需要脚本: 无
#
#==============================================================================

$imported = {} if $imported.nil?
$imported["YEA-MessageSystem"] = true

#==============================================================================
# ▼ Updates
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# 2012.07.21 - Fixed REGEXP error at line 824
# 2012.01.13 - Bug Fixed: Negative tags didn't display other party members.
# 2012.01.12 - Compatibility Update: Message Actor Codes
# 2012.01.10 - Added Feature: \pic[x] text code.
# 2012.01.04 - Bug Fixed: \ic tag was \ii. No longer the case.
#            - Added: Scroll Text window now uses message window font.
# 2011.12.31 - Started Script and Finished.
#
#==============================================================================
# ▼ 介绍
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# 尽管RPG Maker VX Ace已经为文本系统添加各种实用的功能,再加多一点新功能也未尝
# 不可,像新的窗口,转换文本编码,以更快的方式输出物品,武器,护甲等的图标和/或
# 名称。本脚本还为脚本开发人员提供在游戏过程中调整文本窗口大小的功能,使用单
# 独的字体,并为玩家提供文本快进功能。
#
#==============================================================================
# ▼ 安装方式
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# 打开脚本编辑器,将本脚本拷贝/复制到一个在▼ 插件脚本之下▼ Main之上的新
# 脚本页/槽中.记得保存你的工程以使脚本生效.
#
# -----------------------------------------------------------------------------
# 文本代码 - 在文本窗口中可以使用的代码.
# -----------------------------------------------------------------------------
#    代码:       效果:
#    \v[x]     - 显示x号变量的值.
#    \n[x]     - 显示x号角色的名字.
#    \p[x]     - 显示队伍中x号队友的名字.
#    \g        - 显示当前金币名.
#    \c[x]     - 改变字体颜色为x.
#    \i[x]     - 显示index为x的图标.
#    \{        - 文字增大8点.
#    \}        - 文字缩小8点.
#    \$        - 打开金币窗口.
#    \.        - 等待15帧 (1/4秒).
#    \|        - 等待60帧 (1秒).
#    \!        - 等待直到玩家按下确定键.
#    \>        - 立即显示完剩下的文本.
#    \<        - 停止立即显示剩下的文本.
#    \^        - 跳到下一个文本框.
#    \\        - 显示一个"\".
#
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#
#    等待:       效果:
#    \w[x]     - 等待x帧 (60 帧 = 1 秒). 仅用于文本窗口.
#
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#
#  名称窗口:     效果:
#    \n<x>     - 创建一个显示"x"的名称窗口. 靠左. *注释
#    \nc<x>    - 创建一个显示"x"的名称窗口. 居中. *注释
#    \nr<x>    - 创建一个显示"x"的名称窗口. 靠右. *注释
#
#              *注释: 仅用于文本窗口.
#
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#
#    位置:       效果:
#    \px[n]    - 将文本的x坐标设定为n.
#    \py[n]    - 将文本的y坐标设定为n.
#
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#
#     图片:       效果:
#    \pic[x]   - 显示图片x,其放在文件夹:Graphics\Pictures .
#
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#
#     轮廓:      效果:
#    \oc[x]    - 设定轮廓颜色为x.
#    \oo[x]    - 设定轮廓不透明度为x.
#
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#
#    字体:       效果:
#    \fr       - 重置全部字体的变化.
#    \fz[x]    - 改变字体大小为x.
#    \fn[x]    - 改变字体名为x.
#    \fb       - 切换字体加粗状态.
#    \fi       - 切换字体斜体状态.
#    \fo       - 切换字体轮廓状态.
#    \fs       - 切换字体阴影状态.
#
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#
#     角色:       效果:
#    \af[x]    - 显示x号角色的脸图. *注释
#    \ac[x]    - 显示x号角色的职业名. *注释
#    \as[x]    - 显示x号角色的副职业名. 需要脚本: Class System. *注释
#    \an[x]    - 显示x号角色的称号. *注释
#
#              *注释: 如果x是0或负数,则视为当前角色(玩家操控的队长)或队友:
#                   0 - 队长
#                  -1 - 第一个非队长角色.
#                  -2 - 第二个非队长角色. 以此类推.
#
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#
#     名字:      效果:
#    \nc[x]    - 显示x号职业的名字.
#    \ni[x]    - 显示x号物品的名字.
#    \nw[x]    - 显示x号武器的名字.
#    \na[x]    - 显示x号防具的名字.
#    \ns[x]    - 显示x号技能的名字.
#    \nt[x]    - 显示x号状态的名字.
#
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#
#  图标+名字:    效果:
#    \ic[x]    - 显示x号职业的名字和图标. *
#    \ii[x]    - 显示x号物品的名字和图标.
#    \iw[x]    - 显示x号武器的名字和图标.
#    \ia[x]    - 显示x号防具的名字和图标.
#    \is[x]    - 显示x号技能的名字和图标.
#    \it[x]    - 显示x号状态的名字和图标.
#
#              *注释: 需要脚本 YEA - Class System
#
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#
# 以上就为本脚本全部可用的文本代码。请记住某些代码仅可用于文本窗口,其他的则可以
# 使用于物品/技能/武器/防具等的描述、角色说明或其他地方。
#
#==============================================================================
# ▼ 兼容性
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# 本脚本仅为RPG Maker VX Ace编写.极不可能在无任何修改的情况下运行于RPG Maker VX.
#
#==============================================================================

module YEA
  module MESSAGE
   
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # - 通用设置 -
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # 下面是文本窗口的通用设置.
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # 快速跳过文本的按钮。按住时将加速显示文本,但是不会跳过等待。按住时会自动
    # 跳到下一个文本窗口
    TEXT_SKIP = :A     #  :A 为键盘上的Shift键.
   
    # 存储文本窗口中最大行数的变量。如果你不想使用这个功能,请设定为0。当
    # 设定为0或以下时,脚本会自动默认为4行
    VARIABLE_ROWS  = 21
   
    # 存储文本窗口中最大列数的变量。如果你不想使用这个功能,请设定为0。当
    # 设定为0或以下时,脚本会自动默认列宽度为游戏窗口的宽度
    VARIABLE_WIDTH = 22
   
    # 这是文本窗口在显示脸图时将缩进的空间量。 默认: 112
    FACE_INDENT_X = 112
   
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # - 名称窗口设置 -
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # 名称窗口是区别于文本窗口的另一个窗口,用于显示角色的名字。
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    NAME_WINDOW_X_BUFFER = -20     # 调整名称窗口的x坐标.
    NAME_WINDOW_Y_BUFFER = 0       # 调整名称窗口的y坐标.
    NAME_WINDOW_PADDING  = 20      # 横向增加的宽度.
    NAME_WINDOW_OPACITY  = 255     # 名称窗口的不透明度.
    NAME_WINDOW_COLOUR   = 6       # 默认文本颜色.
   
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # - 文本字体设置 -
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # Ace 文本系统将游戏中的系统字体于文本字体中脱离。
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # 在数组中放置要使用的字体,若在玩家的电脑中第一种字体不存在,则会使用第二
    # 种字体,以此类推。
    MESSAGE_WINDOW_FONT_NAME = ["黑体", "宋体", "微软雅黑"]
   
    # 关于字体的其他设置.
    MESSAGE_WINDOW_FONT_SIZE    = 24       # 字体大小.
    MESSAGE_WINDOW_FONT_BOLD    = false    # 是否默认加粗?
    MESSAGE_WINDOW_FONT_ITALIC  = false    # 是否默认斜体?
    MESSAGE_WINDOW_FONT_OUTLINE = true     # 是否默认显示轮廓?
    MESSAGE_WINDOW_FONT_SHADOW  = false    # 是否默认显示阴影?
   
  end # MESSAGE
end # YEA

#==============================================================================
# ▼ 编辑以下内容可能会出现电脑损坏、死机,电脑主人脑袋爆炸、昏迷、死亡或口臭
# 所以编辑了后果自负。
#==============================================================================

#==============================================================================
# ■ Variable
#==============================================================================

module Variable
  
  #--------------------------------------------------------------------------
  # self.message_rows
  #--------------------------------------------------------------------------
  def self.message_rows
    return 4 if YEA::MESSAGE::VARIABLE_ROWS <= 0
    return 4 if $game_variables[YEA::MESSAGE::VARIABLE_ROWS] <= 0
    return $game_variables[YEA::MESSAGE::VARIABLE_ROWS]
  end
  
  #--------------------------------------------------------------------------
  # self.message_width
  #--------------------------------------------------------------------------
  def self.message_width
    return Graphics.width if YEA::MESSAGE::VARIABLE_WIDTH <= 0
    return Graphics.width if $game_variables[YEA::MESSAGE::VARIABLE_WIDTH] <= 0
    return $game_variables[YEA::MESSAGE::VARIABLE_WIDTH]
  end
  
end # Variable

#==============================================================================
# ■ Game_Interpreter
#==============================================================================

class Game_Interpreter
  
  #--------------------------------------------------------------------------
  # overwrite method: command_101
  #--------------------------------------------------------------------------
  def command_101
    wait_for_message
    $game_message.face_name = @params[0]
    $game_message.face_index = @params[1]
    $game_message.background = @params[2]
    $game_message.position = @params[3]
    while continue_message_string?
      @index += 1
      if @list[@index].code == 401
        $game_message.add(@list[@index].parameters[0])
      end
      break if $game_message.texts.size >= Variable.message_rows
    end
    case next_event_code
    when 102
      @index += 1
      setup_choices(@list[@index].parameters)
    when 103
      @index += 1
      setup_num_input(@list[@index].parameters)
    when 104
      @index += 1
      setup_item_choice(@list[@index].parameters)
    end
    wait_for_message
  end
  
  #--------------------------------------------------------------------------
  # new method: continue_message_string?
  #--------------------------------------------------------------------------
  def continue_message_string?
    return true if next_event_code == 101 && Variable.message_rows > 4
    return next_event_code == 401
  end
  
end # Game_Interpreter

#==============================================================================
# ■ Window_Base
#==============================================================================

class Window_Base < Window
  
  #--------------------------------------------------------------------------
  # new method: setup_message_font
  #--------------------------------------------------------------------------
  def setup_message_font
    @message_font = true
    change_color(normal_color)
    contents.font.out_color = Font.default_out_color
    contents.font.name = YEA::MESSAGE::MESSAGE_WINDOW_FONT_NAME
    contents.font.size = YEA::MESSAGE::MESSAGE_WINDOW_FONT_SIZE
    contents.font.bold = YEA::MESSAGE::MESSAGE_WINDOW_FONT_BOLD
    contents.font.italic = YEA::MESSAGE::MESSAGE_WINDOW_FONT_ITALIC
    contents.font.outline = YEA::MESSAGE::MESSAGE_WINDOW_FONT_OUTLINE
    contents.font.shadow = YEA::MESSAGE::MESSAGE_WINDOW_FONT_SHADOW
  end
  
  #--------------------------------------------------------------------------
  # alias method: reset_font_settings
  #--------------------------------------------------------------------------
  alias window_base_reset_font_settings_ams reset_font_settings
  def reset_font_settings
    if @message_font
      setup_message_font
    else
      window_base_reset_font_settings_ams
      contents.font.out_color = Font.default_out_color
      contents.font.outline = Font.default_outline
      contents.font.shadow = Font.default_shadow
    end
  end
  
  #--------------------------------------------------------------------------
  # alias method: convert_escape_characters
  #--------------------------------------------------------------------------
  alias window_base_convert_escape_characters_ams convert_escape_characters
  def convert_escape_characters(text)
    result = window_base_convert_escape_characters_ams(text)
    result = convert_ace_message_system_new_escape_characters(result)
    return result
  end
  
  #--------------------------------------------------------------------------
  # new method: convert_ace_message_system_new_escape_characters
  #--------------------------------------------------------------------------
  def convert_ace_message_system_new_escape_characters(result)
    #---
    result.gsub!(/\eFR/i) { "\eAMSF[0]" }
    result.gsub!(/\eFB/i) { "\eAMSF[1]" }
    result.gsub!(/\eFI/i) { "\eAMSF[2]" }
    result.gsub!(/\eFO/i) { "\eAMSF[3]" }
    result.gsub!(/\eFS/i) { "\eAMSF[4]" }
    #---
    result.gsub!(/\eAC\[([-+]?\d+)\]/i) { escape_actor_class_name($1.to_i) }
    result.gsub!(/\eAS\[([-+]?\d+)\]/i) { escape_actor_subclass_name($1.to_i) }
    result.gsub!(/\eAN\[([-+]?\d+)\]/i) { escape_actor_nickname($1.to_i) }
    #---
    result.gsub!(/\eNC\[(\d+)\]/i) { $data_classes[$1.to_i].name }
    result.gsub!(/\eNI\[(\d+)\]/i) { $data_items[$1.to_i].name }
    result.gsub!(/\eNW\[(\d+)\]/i) { $data_weapons[$1.to_i].name }
    result.gsub!(/\eNA\[(\d+)\]/i) { $data_armors[$1.to_i].name }
    result.gsub!(/\eNS\[(\d+)\]/i) { $data_skills[$1.to_i].name }
    result.gsub!(/\eNT\[(\d+)\]/i) { $data_states[$1.to_i].name }
    #---
    result.gsub!(/\eIC\[(\d+)\]/i) { escape_icon_item($1.to_i, :class) }
    result.gsub!(/\eII\[(\d+)\]/i) { escape_icon_item($1.to_i, :item) }
    result.gsub!(/\eIW\[(\d+)\]/i) { escape_icon_item($1.to_i, :weapon) }
    result.gsub!(/\eIA\[(\d+)\]/i) { escape_icon_item($1.to_i, :armour) }
    result.gsub!(/\eIS\[(\d+)\]/i) { escape_icon_item($1.to_i, :skill) }
    result.gsub!(/\eIT\[(\d+)\]/i) { escape_icon_item($1.to_i, :state) }
    #---
    return result
  end
  
  #--------------------------------------------------------------------------
  # new method: escape_actor_class_name
  #--------------------------------------------------------------------------
  def escape_actor_class_name(actor_id)
    actor_id = $game_party.members[actor_id.abs].id if actor_id <= 0
    actor = $game_actors[actor_id]
    return "" if actor.nil?
    return actor.class.name
  end
  
  #--------------------------------------------------------------------------
  # new method: actor_subclass_name
  #--------------------------------------------------------------------------
  def escape_actor_subclass_name(actor_id)
    return "" unless $imported["YEA-ClassSystem"]
    actor_id = $game_party.members[actor_id.abs].id if actor_id <= 0
    actor = $game_actors[actor_id]
    return "" if actor.nil?
    return "" if actor.subclass.nil?
    return actor.subclass.name
  end
  
  #--------------------------------------------------------------------------
  # new method: escape_actor_nickname
  #--------------------------------------------------------------------------
  def escape_actor_nickname(actor_id)
    actor_id = $game_party.members[actor_id.abs].id if actor_id <= 0
    actor = $game_actors[actor_id]
    return "" if actor.nil?
    return actor.nickname
  end
  
  #--------------------------------------------------------------------------
  # new method: escape_icon_item
  #--------------------------------------------------------------------------
  def escape_icon_item(data_id, type)
    case type
    when :class
      return "" unless $imported["YEA-ClassSystem"]
      icon = $data_classes[data_id].icon_index
      name = $data_items[data_id].name
    when :item
      icon = $data_items[data_id].icon_index
      name = $data_items[data_id].name
    when :weapon
      icon = $data_weapons[data_id].icon_index
      name = $data_weapons[data_id].name
    when :armour
      icon = $data_armors[data_id].icon_index
      name = $data_armors[data_id].name
    when :skill
      icon = $data_skills[data_id].icon_index
      name = $data_skills[data_id].name
    when :state
      icon = $data_states[data_id].icon_index
      name = $data_states[data_id].name
    else; return ""
    end
    text = "\eI[#{icon}]" + name
    return text
  end
  
  #--------------------------------------------------------------------------
  # alias method: process_escape_character
  #--------------------------------------------------------------------------
  alias window_base_process_escape_character_ams process_escape_character
  def process_escape_character(code, text, pos)
    case code.upcase
    #---
    when 'FZ'
      contents.font.size = obtain_escape_param(text)
    when 'FN'
      text.sub!(/\[(.*?)\]/, "")
      font_name = $1.to_s
      font_name = Font.default_name if font_name.nil?
      contents.font.name = font_name.to_s
    #---
    when 'OC'
      colour = text_color(obtain_escape_param(text))
      contents.font.out_color = colour
    when 'OO'
      contents.font.out_color.alpha = obtain_escape_param(text)
    #---
    when 'AMSF'
      case obtain_escape_param(text)
      when 0; reset_font_settings
      when 1; contents.font.bold = !contents.font.bold
      when 2; contents.font.italic = !contents.font.italic
      when 3; contents.font.outline = !contents.font.outline
      when 4; contents.font.shadow = !contents.font.shadow
      end
    #---
    when 'PX'
      pos[:x] = obtain_escape_param(text)
    when 'PY'
      pos[:y] = obtain_escape_param(text)
    #---
    when 'PIC'
      text.sub!(/\[(.*?)\]/, "")
      bmp = Cache.picture($1.to_s)
      rect = Rect.new(0, 0, bmp.width, bmp.height)
      contents.blt(pos[:x], pos[:y], bmp, rect)
    #---
    else
      window_base_process_escape_character_ams(code, text, pos)
    end
  end
  
end # Window_Base

#==============================================================================
# ■ Window_ChoiceList
#==============================================================================

class Window_ChoiceList < Window_Command
  
  #--------------------------------------------------------------------------
  # alias method: initialize
  #--------------------------------------------------------------------------
  alias window_choicelist_initialize_ams initialize
  def initialize(message_window)
    window_choicelist_initialize_ams(message_window)
    setup_message_font
  end
  
end # Window_ChoiceList

#==============================================================================
# ■ Window_ScrollText
#==============================================================================

class Window_ScrollText < Window_Base
  
  #--------------------------------------------------------------------------
  # alias method: initialize
  #--------------------------------------------------------------------------
  alias window_scrolltext_initialize_ams initialize
  def initialize
    window_scrolltext_initialize_ams
    setup_message_font
  end
  
end # Window_ScrollText

#==============================================================================
# ■ Window_NameMessage
#==============================================================================

class Window_NameMessage < Window_Base
  
  #--------------------------------------------------------------------------
  # initialize
  #--------------------------------------------------------------------------
  def initialize(message_window)
    @message_window = message_window
    super(0, 0, Graphics.width, fitting_height(1))
    self.opacity = YEA::MESSAGE::NAME_WINDOW_OPACITY
    self.z = @message_window.z + 1
    self.openness = 0
    setup_message_font
    @close_counter = 0
    deactivate
  end
  
  #--------------------------------------------------------------------------
  # update
  #--------------------------------------------------------------------------
  def update
    super
    return if self.active
    return if self.openness == 0
    return if @closing
    @close_counter -= 1
    return if @close_counter > 0
    close
  end
  
  #--------------------------------------------------------------------------
  # start_close
  #--------------------------------------------------------------------------
  def start_close
    @close_counter = 4
    deactivate
  end
  
  #--------------------------------------------------------------------------
  # force_close
  #--------------------------------------------------------------------------
  def force_close
    @close_counter = 0
    deactivate
    close
  end
  
  #--------------------------------------------------------------------------
  # start
  #--------------------------------------------------------------------------
  def start(text, x_position)
    @text = text.clone
    set_width
    create_contents
    set_x_position(x_position)
    set_y_position
    refresh
    activate
    open
  end
  
  #--------------------------------------------------------------------------
  # set_width
  #--------------------------------------------------------------------------
  def set_width
    text = @text.clone
    dw = standard_padding * 2 + text_size(text).width
    dw += YEA::MESSAGE::NAME_WINDOW_PADDING * 2
    dw += calculate_size(text.slice!(0, 1), text) until text.empty?
    self.width = dw
  end
  
  #--------------------------------------------------------------------------
  # calculate_size
  #--------------------------------------------------------------------------
  def calculate_size(code, text)
    case code
    when "\e"
      return calculate_escape_code_width(obtain_escape_code(text), text)
    else
      return 0
    end
  end
  
  #--------------------------------------------------------------------------
  # calculate_escape_code_width
  #--------------------------------------------------------------------------
  def calculate_escape_code_width(code, text)
    dw = -text_size("\e").width - text_size(code).width
    case code.upcase
    when 'C', 'OC', 'OO'
      dw += -text_size("[" + obtain_escape_param(text).to_s + "]").width
      return dw
    when 'I'
      dw += -text_size("[" + obtain_escape_param(text).to_s + "]").width
      dw += 24
      return dw
    when '{'
      make_font_bigger
    when '}'
      make_font_smaller
    when 'FZ'
      contents.font.size = obtain_escape_param(text)
    when 'FN'
      text.sub!(/\[(.*?)\]/, "")
      font_name = $1.to_s
      font_name = Font.default_name if font_name.nil?
      contents.font.name = font_name.to_s
    when 'AMSF'
      case obtain_escape_param(text)
      when 0; reset_font_settings
      when 1; contents.font.bold = !contents.font.bold
      when 2; contents.font.italic = !contents.font.italic
      when 3; contents.font.outline = !contents.font.outline
      when 4; contents.font.shadow = !contents.font.shadow
      end
    else
      return dw
    end
  end
  
  #--------------------------------------------------------------------------
  # set_y_position
  #--------------------------------------------------------------------------
  def set_x_position(x_position)
    case x_position
    when 1 # Left
      self.x = @message_window.x
      self.x += YEA::MESSAGE::NAME_WINDOW_X_BUFFER
    when 2 # 3/10
      self.x = @message_window.x
      self.x += @message_window.width * 3 / 10
      self.x -= self.width / 2
    when 3 # Center
      self.x = @message_window.x
      self.x += @message_window.width / 2
      self.x -= self.width / 2
    when 4 # 7/10
      self.x = @message_window.x
      self.x += @message_window.width * 7 / 10
      self.x -= self.width / 2
    when 5 # Right
      self.x = @message_window.x + @message_window.width
      self.x -= self.width
      self.x -= YEA::MESSAGE::NAME_WINDOW_X_BUFFER
    end
    self.x = [[self.x, Graphics.width - self.width].min, 0].max
  end
  
  #--------------------------------------------------------------------------
  # set_y_position
  #--------------------------------------------------------------------------
  def set_y_position
    case $game_message.position
    when 0
      self.y = @message_window.height
      self.y -= YEA::MESSAGE::NAME_WINDOW_Y_BUFFER
    else
      self.y = @message_window.y - self.height
      self.y += YEA::MESSAGE::NAME_WINDOW_Y_BUFFER
    end
  end
  
  #--------------------------------------------------------------------------
  # refresh
  #--------------------------------------------------------------------------
  def refresh
    contents.clear
    reset_font_settings
    @text = sprintf("\eC[%d]%s", YEA::MESSAGE::NAME_WINDOW_COLOUR, @text)
    draw_text_ex(YEA::MESSAGE::NAME_WINDOW_PADDING, 0, @text)
  end
  
end # Window_NameMessage

#==============================================================================
# ■ Window_Message
#==============================================================================

class Window_Message < Window_Base
  
  #--------------------------------------------------------------------------
  # alias method: initialize
  #--------------------------------------------------------------------------
  alias window_message_initialize_ams initialize
  def initialize
    window_message_initialize_ams
    setup_message_font
  end
  
  #--------------------------------------------------------------------------
  # overwrite method: window_width
  #--------------------------------------------------------------------------
  def window_width
    return Variable.message_width
  end
  
  #--------------------------------------------------------------------------
  # overwrite method: window_height
  #--------------------------------------------------------------------------
  def window_height
    return fitting_height(Variable.message_rows)
  end
  
  #--------------------------------------------------------------------------
  # alias method: create_all_windows
  #--------------------------------------------------------------------------
  alias window_message_create_all_windows_ams create_all_windows
  def create_all_windows
    window_message_create_all_windows_ams
    @name_window = Window_NameMessage.new(self)
  end
  
  #--------------------------------------------------------------------------
  # overwrite method: create_back_bitmap
  #--------------------------------------------------------------------------
  def create_back_bitmap
    @back_bitmap = Bitmap.new(width, height)
    rect1 = Rect.new(0, 0, Graphics.width, 12)
    rect2 = Rect.new(0, 12, Graphics.width, fitting_height(4) - 24)
    rect3 = Rect.new(0, fitting_height(4) - 12, Graphics.width, 12)
    @back_bitmap.gradient_fill_rect(rect1, back_color2, back_color1, true)
    @back_bitmap.fill_rect(rect2, back_color1)
    @back_bitmap.gradient_fill_rect(rect3, back_color1, back_color2, true)
  end
  
  #--------------------------------------------------------------------------
  # alias method: dispose_all_windows
  #--------------------------------------------------------------------------
  alias window_message_dispose_all_windows_ams dispose_all_windows
  def dispose_all_windows
    window_message_dispose_all_windows_ams
    @name_window.dispose
  end
  
  #--------------------------------------------------------------------------
  # alias method: update_all_windows
  #--------------------------------------------------------------------------
  alias window_message_update_all_windows_ams update_all_windows
  def update_all_windows
    window_message_update_all_windows_ams
    @name_window.update
    @name_window.back_opacity = self.back_opacity
    @name_window.opacity = self.opacity
  end
  
  #--------------------------------------------------------------------------
  # alias method: update_show_fast
  #--------------------------------------------------------------------------
  alias window_message_update_show_fast_ams update_show_fast
  def update_show_fast
    @show_fast = true if Input.press?(YEA::MESSAGE::TEXT_SKIP)
    window_message_update_show_fast_ams
  end
  
  #--------------------------------------------------------------------------
  # overwrite method: input_pause
  #--------------------------------------------------------------------------
  def input_pause
    self.pause = true
    wait(10)
    Fiber.yield until Input.trigger?(:B) || Input.trigger?(:C) ||
      Input.press?(YEA::MESSAGE::TEXT_SKIP)
    Input.update
    self.pause = false
  end
  
  #--------------------------------------------------------------------------
  # overwrite method: convert_escape_characters
  #--------------------------------------------------------------------------
  def convert_escape_characters(text)
    result = super(text.to_s.clone)
    result = namebox_escape_characters(result)
    result = message_escape_characters(result)
    return result
  end
  
  #--------------------------------------------------------------------------
  # new method: namebox_escape_characters
  #--------------------------------------------------------------------------
  def namebox_escape_characters(result)
    result.gsub!(/\eN\<(.+?)\>/i)  { namewindow($1, 1) }
    result.gsub!(/\eN1\<(.+?)\>/i) { namewindow($1, 1) }
    result.gsub!(/\eN2\<(.+?)\>/i) { namewindow($1, 2) }
    result.gsub!(/\eNC\<(.+?)\>/i) { namewindow($1, 3) }
    result.gsub!(/\eN3\<(.+?)\>/i) { namewindow($1, 3) }
    result.gsub!(/\eN4\<(.+?)\>/i) { namewindow($1, 4) }
    result.gsub!(/\eN5\<(.+?)\>/i) { namewindow($1, 5) }
    result.gsub!(/\eNR\<(.+?)\>/i) { namewindow($1, 5) }
    return result
  end
  
  #--------------------------------------------------------------------------
  # new method: namebox
  #--------------------------------------------------------------------------
  def namewindow(text, position)
    @name_text = text
    @name_position = position
    return ""
  end
  
  #--------------------------------------------------------------------------
  # new method: message_escape_characters
  #--------------------------------------------------------------------------
  def message_escape_characters(result)
    result.gsub!(/\eAF\[(-?\d+)]/i) { change_face($1.to_i) }
    return result
  end
  
  #--------------------------------------------------------------------------
  # new method: change_face
  #--------------------------------------------------------------------------
  def change_face(actor_id)
    actor_id = $game_party.members[actor_id.abs].id if actor_id <= 0
    actor = $game_actors[actor_id]
    return "" if actor.nil?
    $game_message.face_name = actor.face_name
    $game_message.face_index = actor.face_index
    return ""
  end
  
  #--------------------------------------------------------------------------
  # alias method: new_page
  #--------------------------------------------------------------------------
  alias window_message_new_page_ams new_page
  def new_page(text, pos)
    adjust_message_window_size
    window_message_new_page_ams(text, pos)
  end
  
  #--------------------------------------------------------------------------
  # overwrite method: new_line_x
  #--------------------------------------------------------------------------
  def new_line_x
    return $game_message.face_name.empty? ? 0 : YEA::MESSAGE::FACE_INDENT_X
  end
  
  #--------------------------------------------------------------------------
  # new method: adjust_message_window_size
  #--------------------------------------------------------------------------
  def adjust_message_window_size
    self.height = window_height
    self.width = window_width
    create_contents
    update_placement
    self.x = (Graphics.width - self.width) / 2
    start_name_window
  end
  
  #--------------------------------------------------------------------------
  # new method: clear_name_window
  #--------------------------------------------------------------------------
  def clear_name_window
    @name_text = ""
    @name_position = 0
  end
  
  #--------------------------------------------------------------------------
  # new method: start_name_window
  #--------------------------------------------------------------------------
  def start_name_window
    return if @name_text == ""
    @name_window.start(@name_text, @name_position)
  end
  
  #--------------------------------------------------------------------------
  # overwrite method: fiber_main
  #--------------------------------------------------------------------------
  def fiber_main
    $game_message.visible = true
    update_background
    update_placement
    loop do
      process_all_text if $game_message.has_text?
      process_input
      $game_message.clear
      @gold_window.close
      @name_window.start_close
      Fiber.yield
      break unless text_continue?
    end
    close_and_wait
    $game_message.visible = false
    @fiber = nil
  end
  
  #--------------------------------------------------------------------------
  # alias method: open_and_wait
  #--------------------------------------------------------------------------
  alias window_message_open_and_wait_ams open_and_wait
  def open_and_wait
    clear_name_window
    adjust_message_window_size
    window_message_open_and_wait_ams
  end
  
  #--------------------------------------------------------------------------
  # alias method: close_and_wait
  #--------------------------------------------------------------------------
  alias window_message_close_and_wait_ams close_and_wait
  def close_and_wait
    @name_window.force_close
    window_message_close_and_wait_ams
  end
  
  #--------------------------------------------------------------------------
  # alias method: all_close?
  #--------------------------------------------------------------------------
  alias window_message_all_close_ams all_close?
  def all_close?
    return window_message_all_close_ams && @name_window.close?
  end
  
  #--------------------------------------------------------------------------
  # alias method: process_escape_character
  #--------------------------------------------------------------------------
  alias window_message_process_escape_character_ams process_escape_character
  def process_escape_character(code, text, pos)
    case code.upcase
    when 'W' # Wait
      wait(obtain_escape_param(text))
    else
      window_message_process_escape_character_ams(code, text, pos)
    end
  end
  
end # Window_Message

#==============================================================================
#
# ▼ End of File
#
#==============================================================================[/pre]







=begin
#==============================================================================
* 闲谈对话框 (Yami 气泡对话框 的插件) - v1.3c
  作者: Quack
  翻译:nil2018(○┰○)
#==============================================================================
效果:
1-允许你使用"闲谈对话框。和默认对话框区别为,闲谈对话框不会暂停游戏,也不会因为
  玩家按下任何按键而关闭,取而代之的是为对话框设定一个计时器,时间到了会自动将
  其关闭。还有一个特点是:可以同时显示多个闲谈对话框(有最大显示数量限制,默认
  为7,你可以在下面的"MAX_MSGS"中调整最大数)
  
  将普通对话框“变成”闲谈对话框的方法为:在对话框中填入标志:'<cm:X>'
  其中X为显示的时间,单位为秒(注意:这个标志必须放在对话框的第一行!!)
  将X设定为负值时,对话框就不会消失了。你可以使用脚本来关闭所有闲谈对话框:
  clear_chatter
  
2-说话的气泡标志(bubble message)和原来一样,都是: \bm[x]
  新添加了思考(bubble message thought)的气泡标志:  \bmt[x]
  
3-气泡对话框可以在战斗中使用了。可以使用 \bm[x] 或 \bmt[x] 来显示气泡对话框。to show a pop message.
  如果你要在敌人头上显示气泡对话框,请将x替换为负值.
  在战斗中:    \bm[1] 显示在1号敌人头上
                \bm[-1] 显示在1号角色头上
  对于1号敌人,使用 \bm[1] ,4号敌人则使用 \bm[4]
  同时,对于角色: 1号角色 = \bm[-1]
  
  然而,要想在战斗中在角色头上显示气泡对话框,需要你使用“显示角色战斗图”的
  脚本。我不能保证我的脚本适用于所有该功能的脚本。但我可以保证和Jet's sideview
  battlers 相兼容。
  
  有一个问题是,当战斗图的大小过大或过小时,对话框窗口会有些移位。
  使用以下标志来调整对话框的位置:
  \ox[X] - 调整气泡对话框的x坐标
  \oy[X] - 调整气泡对话框的y坐标
  
  有一点需要注意的是,如果你还使用了Yanfly的核心脚本&Yanfly的文本系统,你需要将
  核心脚本中的 FONT_NAME 和文本系统的i MESSAGE_WINDOW_FONT_NAME 设定相匹配(两
  个地方都要设定相同的字体)否则两个脚本的设定结合起来,有时会使文本的宽度计算
  错误。这个问题不大,可是在气泡对话框中,会改变气泡对话框的窗口宽度,这就是个
  大问题了(yanfly两个脚本中,关于字体的其他设定例如是否加粗是否斜体等,也最好
  设定得一模一样)
  
版本 1.1 更新功能:

1-添加文本打字音效,你可以在 TEXT_SOUNDS 的哈希表中设定(在下面查看更多地介绍)
  使用标志:
  <ts:x>   文章打字音x,x为存在于 TEXT_SOUNDS 哈希表中的打字音效名字.
  
2-添加对话框背景色调的功能。你可以在 WINDOW_TONES 哈希表中预设色调种类
  使用标志: <bc:x> ,其中x为存在于 WINDOW_TONES 哈希表中的色调名字.

3-有时,你需要在同一个对话框中显示不同的字体,可能会使对话框变得过大或过小。Sometimes you might want to change font size in your message, multiple times,
  使用标志: <pms:x,y> 可以调整气泡对话框的大小.x为宽度变化,y为高度变化
  例如,你使用了标志<pms:20,-10> ,则对话框的宽度会增加20,高度会减少10.
  
4-如果你和我一样,被记忆事件id、书写一大堆标志而困扰,以下功能会帮到你。
  
  仅使用一个标志<bt:x> (对于谈话气泡) 或 <btt:x> (对于思考气泡)
  就可以让该事件使用你设定的背景颜色和文本打字音效。
  
  那原理是什么?
  举个例子,我有一个作为队伍角色的事件,她叫Emil.在事件名中填入了标志: <emil>.
  然后,当我使用了标志: <bt:emil> 或 <btt:emil> 气泡对话框会自动显示到该事件的
  头上(如果有多个事件名为<emil>的事件,也会只显示一个对话框),且使用
  WINDOW_TONES 中的'emil'作为窗口色调,使用TEXT_SOUNDS中的'emil'作为文本打字音效
  但不能用于btt,因为思考中还会有打字音效不是太奇怪了吗?
  
  
  这也会在你检查事件时,更清楚地明白哪个事件是'emil',而不是去找哪个事件是某某id
  
  如果你想指定用于角色(player) 的话,使用标志'pl',例如:
  <bt:pl>
  这样就可以使设定窗口色调和打字音效的"打包"设定同时应用于角色了。
  或许在队员变化大的情况下不怎么实用,但是我仍然添加了此功能。
  
  如果你很好奇为什么我新添加的标志和以前的不一样...因为!Consistence is overrated
  anyway, who needs it?  (0.0)
  
  使用标志(<bt:x> & <btt:x>) 需要你安装脚本 Qonvenience (你也许会叫它做
  我的'核心' 脚本,类似其他人的 (Yanfly,
  Victor, Yami, etc).
  你可以在下面的'使用条件'部分找到下载地址.
  
版本 1.2 更新功能:

- 显示选项时,会根据你使用的是气泡对话框还是普通的对话框而显示不同的样子。
  使用默认对话框时,选项的外貌不变。使用气泡对话框时选项会变得更大,且显示在对
  话框窗口中.
  
版本 1.3更新功能:

- 修复了一些肖像图和名称窗口的问题。问题并没有完全解决,因为我自己的工程里并
没有使用名称窗口或肖像图,所以本人并不是很感兴趣去花时间到这些地方。
  
-和窗口色调、打字音效一样,你现在可以使用标志来显示名称窗口了。
  
==============================================================================
安装注释:
需要脚本 Yami气泡对话框.
将本脚本放在其之下.

==============================================================================
使用条件:
需要Yami气泡对话框脚本,你可以在这里下载:
​https://github.com/suppayami/rmvxa-collection/blob/master/yami-script-ace/10%20-%20Pop%20Message.txt
同时还需要我的 Qonvenience脚本 ,如果你想使用:<bt:x> 和 <btt:x>的话
在这里下载:
http://pastebin.com/J6haUy5T

==============================================================================
Credits:
Yami 为 气泡对话框的作者.

==============================================================================
使用条款:
随意使用(没错,包括商业游戏),只要你不声明这个脚本是你自己写的。
同时我也希望你能在使用此脚本时,属名我为脚本的作者。
请记住本脚本必须和Yami的气泡对话框同时使用,其也有自己的使用条款.

==============================================================================
Bugs:
不懂

==============================================================================
History:
11/10/2016 - Fixed some problems added some minor feature.
19/01/2016 - Fixed some bugs, changes to choices when a pop message is used.
14/01/2016 - Chatter messages now last forever if you set the duration to a
             negative number. Also added method for clearing all chatter
             to use in script calls. Also squashed some bugs.
13/01/2016 - Pretty big update. Added more functionality.
10/01/2016 - Proper release since Absurdiness found the original script so I
             could separate the addon from the original.
08/01/2016 - Initial release

=end

$imported = {} if $imported.nil?
$imported["Chatter_Messages"] = true

#==============================================================================
# * 设定
#==============================================================================

module YSE
  module POP_MESSAGE
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    # - 视觉设定 -
    #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
   
    EFFECT2 = { # 开始.
      :bubble_tag_name => "BubbleTag_Speech",
      :thought_bubble_tag_name => "BubbleTag_Thought",
    } # 结束.
  end
end

module QUACK
  module MSG
   
    # 闲谈窗口同时显示的最大数量。
    # 太少会限制了你的选择,太多会使画面杂乱。
    MAX_MSGS = 7
   
    # 在这里设定窗口颜色。
    # 格式:
    # '名称' => Tone.new(红,绿,蓝,灰度)
    # 名称为字符,红绿蓝为数字,范围是 -255~255
    # 灰度的范围是 0 到 255. 灰度为可选值,不一定非要写。
    WINDOW_TONES = {
      #在下面手动添加设定
      '偏红' => Tone.new(85,44,51),
      '杰克' => Tone.new(-34,85,102),
      '狂人' => Tone.new(68,68,68,10),
      '普尔' => Tone.new(102,34,-34),
      '爱丽丝' => Tone.new(102,34,51),
      # 自己设定更多的
    }
   
    # 在这里设定文本打字音效
    # 格式:
    # '名称' => ["文件名",音量, 最低音调, 最高音调],
    # 名称为字符,文件名为音效文件名where Key is a string. Sound is the name of your sound,
    # 音量音调为数字,范围是 0-100.
    TEXT_SOUNDS = {
      #在下面手动添加设定
      '0' => nil, # 无任何打字音效的默认值!
      '1' => ["Cursor1", 80, 70, 100],
      '2' => ["Cursor1", 80, 90, 120],
      '3' => ["Knock", 80, 50, 75],
      '杰克' => ["Cursor1", 80, 90, 120],
      '狂人' => ["Cursor1", 80, 45, 70],
      '普尔' => ["Cursor1", 80, 70, 100],
      '爱丽丝' => ["Cursor1", 70, 110, 140],
      # And above this line
    }
   
    NAMES = {
      # 设定名称
      '1' => "冒险家杰克",
      '2' => "疯狂实验员"
    }
   
    # 每X个字符播放一次打字音效.
    SOUND_PLAY_FREQUENCY = 3
   
    # 气泡对话框是否在使用选项时随着文本显示而逐渐增大,还是立刻显示为最大尺寸
    POP_CHOICE_GROW = true
   
  end
end

#==============================================================================
# * SCRIPT START
#==============================================================================

#==============================================================================
# ?! DataManager
#==============================================================================
module DataManager
  class << self
    alias quack_msg_create_game_objects create_game_objects
    def create_game_objects
      quack_msg_create_game_objects
      if !$imported["YSE-PopMessage"]
        msgbox(sprintf("This script(Chatter Messages) requires Yami's Pop Messages to function", "ChatterMessages", 1))
        exit
      end
      $game_message.quack_msg_make
    end
  end
end

#==============================================================================
# ?! Game_Message
#==============================================================================
class Game_Message
  attr_accessor :quack_msgs
  attr_accessor :ev_id
  
  # new
  def quack_msg_make
    @quack_msgs = []
    QUACK::MSG::MAX_MSGS.times {@quack_msgs.push(Game_Message.new)}
    @quack_msg_ttl = 0
    @c_msg = 0
  end
  # new
  def set_ttl(ttl)
    @quack_msg_ttl = ttl
  end
  # new
  def ttl_sub
    @quack_msg_ttl -= 1 if @quack_msg_ttl > 0
  end
  # new
  def expire?
    return false if @quack_msg_ttl < 0
    @quack_msg_ttl == 0
  end
  # new
  def prepare_msg(duration)
    @quack_msg_ttl = (duration * 60).to_i
  end
  # new
  def fin_msg
    @quack_msg_ttl = 0
    @c_msg = (@c_msg + 1) % QUACK::MSG::MAX_MSGS
  end
  # new
  def add_chatter(text)
    m = @quack_msgs[@c_msg]
    m.add(text)
    m.face_name = face_name
    m.face_index = face_index
    m.set_ttl(@quack_msg_ttl)
  end
  # new
  def clear_chatter
    @quack_msgs.each {|m| m.set_ttl(0) }
  end
  
  # new
  def clear_chatter_event(e)
    # Find any chatter attached to certain event id and close the chatter
    @quack_msgs.each {|m| m.set_ttl(0) if m.ev_id == e }
  end
end

#==============================================================================
# ?! Window_Message
#==============================================================================

class Window_Message < Window_Base
  
  # new
  def chatter?
    false
  end
  # new
  def source
    $game_message
  end
  # overwrite
  def standard_padding
    return 8
  end
  # alias
  alias quack_chatter_init initialize
  def initialize
    @msg_tone = $game_system.window_tone
    @snd_f = 0
    #@name_text = ""
    quack_chatter_init
  end
  # new
  def speech_bubble_tag=(sprite)
    @speech_bubble_tag = sprite
  end
  # new
  def thought_bubble_tag=(sprite)
    @thought_bubble_tag = sprite
  end
  # new
  def set_offset_x(x)
    @ox = x
    return ""
  end
  # new
  def set_offset_y(y)
    @oy = y
    return ""
  end
  # overwrite
  def cal_width_line(text)
    result = 0
    text.each_line { |line|
      result = text_size(line).width if result < text_size(line).width
    }
    return result
  end
  # alias
  alias quack_chatter_process_character process_character
  def process_character(c, text, pos)
    if @snd_f == 0 && !@show_fast && !@text_sound.nil?
      Audio.se_play("Audio/SE/"+@text_sound[0],@text_sound[1],@text_sound[2]+rand(@text_sound[3]-@text_sound[2]))
    end
    @snd_f += 1
    @snd_f = 0 if @snd_f == QUACK::MSG::SOUND_PLAY_FREQUENCY
    quack_chatter_process_character(c,text,pos)
  end
  # overwrite
  def update_tone
    self.tone.set(@msg_tone)
  end
  # overwrite
  def message_escape_characters_pop_message(result)
    @msg_tone = $game_system.window_tone
    @event_pop_id = nil
    set_offset_x(0)
    set_offset_y(0)
    @text_sound = QUACK::MSG::TEXT_SOUNDS['0']
    @msg_size_x = 0
    @msg_size_y = 0
    reset_font_settings
   
    result.gsub!(/<BT:([^<>]*)>/i) { event_pop_message_setup2($1, false) }
    result.gsub!(/<BTT:([^<>]*)>/i) { event_pop_message_setup2($1, true) }
    result.gsub!(/\eOX\[([-+]?\d+)\]/i) { set_offset_x($1.to_i) }
    result.gsub!(/\eOY\[([-+]?\d+)\]/i) { set_offset_y($1.to_i) }
    result.gsub!(/\eBM\[([-+]?\d+)\]/i) { event_pop_message_setup($1.to_i, false) }
    result.gsub!(/\eBMT\[([-+]?\d+)\]/i) { event_pop_message_setup($1.to_i, true) }
    result.gsub!(/\eBMF\[(\d+)\]/i) { event_pop_message_setup($1.to_i, false, true) }
    result.gsub!(/\eCBM/i) { event_pop_message_setup(nil, false) }
    result.gsub!(/<BC:([^<>]*)>/i) { @msg_tone = QUACK::MSG::WINDOW_TONES[$1] ;""}
    result.gsub!(/<TS:([^<>]*)>/i) { @text_sound = QUACK::MSG::TEXT_SOUNDS[$1]; ""}
    result.gsub!(/<PMS:([-+]?\d+),([-+]?\d+)>/i) { @msg_size_x = $1.to_i ;@msg_size_y = $2.to_i; ""}
    result
  end
  # new
  def event_pop_message_setup2(tag, thought = false)
    if SceneManager.scene_is?(Scene_Battle)
      if tag.include?('act')
        ev_id = tag[3].to_i
        ev_id = (1+$game_party.members.index($game_actors[ev_id])) * -1
        @msg_tone = QUACK::MSG::WINDOW_TONES[tag] if QUACK::MSG::WINDOW_TONES.has_key?(tag)
        @text_sound = QUACK::MSG::TEXT_SOUNDS[tag] if !thought && QUACK::MSG::TEXT_SOUNDS.has_key?(tag)
      else
        msgbox(sprintf("无任何事件使用标志: '" + tag + "'.","Chatter Messages",1))
      end
      return event_pop_message_setup(ev_id, thought)
    end
    msgbox(sprintf("使用此标志需要你安装Qonvenience.","Chatter Messages",1)) if !$imported["Qonvenience"]
    if tag == 'pl'
      ev_id = 0
    else
      ev_id = $game_map.first_event_tag(tag).id
      msgbox(sprintf("无任何事件使用标志: '" + tag + "'.","Chatter Messages",1)) if ev_id.nil?
    end
    @msg_tone = QUACK::MSG::WINDOW_TONES[tag] if QUACK::MSG::WINDOW_TONES.has_key?(tag)
    @text_sound = QUACK::MSG::TEXT_SOUNDS[tag] if !thought && QUACK::MSG::TEXT_SOUNDS.has_key?(tag)
    namewindow(QUACK::MSG::NAMES[tag], 1) if $imported["YEA-MessageSystem"] && QUACK::MSG::NAMES.has_key?(tag) && @name_text == ""
    return event_pop_message_setup(ev_id, thought)
  end
  # overwrite
  def event_pop_message_setup(event_id, thought = false, follower = false)
    start_name_window if $imported["YEA-MessageSystem"]
    if follower && $game_player.followers[event_id].nil?
      @event_pop_id = nil
      @event_pop_follower = false
      return ""
    end
    if thought # THOUGHT
      @speech_bubble_tag.visible = false
      @bubble_tag = @thought_bubble_tag
    else # SPEECH
      @thought_bubble_tag.visible = false
      @bubble_tag = @speech_bubble_tag
    end
    @event_pop_follower = follower
    @event_pop_id = event_id
    # close any chatter message currently attached to this event
    $game_message.clear_chatter_event(event_id)
    source.ev_id = event_id
    return ""
  end
  # overwrite
  def set_face_position
    #return unless SceneManager.scene_is?(Scene_Map)
    return unless @event_pop_id
    return unless @face_window
    contents.clear
    @face_window.set_face
    return unless $imported["YEA-MessageSystem"]
    return if @face_window.close?
    #@name_window.x = self.x + YSE::POP_MESSAGE::POSITION[:face_x_buffer] + YSE::POP_MESSAGE::POSITION[:name_x_buffer] if (@name_position == 1 || @name_position == 2)
  end
  # overwrite
  def close
    pop_message_close
    #return unless SceneManager.scene_is?(Scene_Map)
    return unless @event_pop_id
    @event_pop_follower = false
    @face_window.hide_face
    return unless YSE::POP_MESSAGE::EFFECT[:use_bubble_tag]
    @speech_bubble_tag.visible = false if @speech_bubble_tag
    @thought_bubble_tag.visible = false if @thought_bubble_tag
    source.ev_id = nil
  end
  # overwrite
  def process_all_text
    @event_pop_id = nil
    @name_text = ""
    txt = convert_escape_characters($game_message.all_text)
    update_placement
    adjust_pop_message(txt)#$game_message.all_text)
    pop_message_process_all_text
  end
  # overwrite
  def update_placement
    if SceneManager.scene_is?(Scene_Map)
      if @event_pop_id.nil?
        fix_default_message
        event_pop_message_update_placement
      elsif @event_pop_id == 0
        character = $game_player
        self.y = character.screen_y + @oy - self.height + YSE::POP_MESSAGE::POSITION[:y_buffer]
        self.x = character.screen_x + @ox - self.width / 2 + YSE::POP_MESSAGE::POSITION[:x_buffer]
        fix_position_bubble(character)
        set_bubble_tag(character)
        @name_window.update_pos if $imported["YEA-MessageSystem"] && @name_window.open?
        @face_window.set_position if !chatter? && @face_window.open?
      elsif @event_pop_id > 0
        hash = @event_pop_follower ? $game_player.followers : $game_map.events
        character = hash[@event_pop_id]
        self.y = character.screen_y + @oy - self.height + YSE::POP_MESSAGE::POSITION[:y_buffer]
        self.x = character.screen_x + @ox - self.width / 2 + YSE::POP_MESSAGE::POSITION[:x_buffer]
        fix_position_bubble(character)
        set_bubble_tag(character)
        @name_window.update_pos if $imported["YEA-MessageSystem"] && @name_window.open?
        @face_window.set_position if !chatter? && @face_window.open?
      end
    else
      # IF IN BATTLE
      #event_pop_message_update_placement
      if @event_pop_id.nil?
        fix_default_message
        event_pop_message_update_placement
      elsif @event_pop_id < 0
        battler = $game_party.members[(@event_pop_id * -1)-1]
        self.y = battler.screen_y + @oy - self.height + YSE::POP_MESSAGE::POSITION[:y_buffer]
        self.x = battler.screen_x + @ox - self.width / 2 + YSE::POP_MESSAGE::POSITION[:x_buffer]
        fix_position_bubble(battler)
        set_bubble_tag(battler)
        @name_window.update_pos if $imported["YEA-MessageSystem"] && @name_window.open?
        @face_window.set_position if !chatter? && @face_window.open?
      elsif @event_pop_id > 0
        battler = $game_troop.members[@event_pop_id-1]
        self.y = battler.screen_y + @oy - self.height + YSE::POP_MESSAGE::POSITION[:y_buffer]
        self.x = battler.screen_x + @ox - self.width / 2 + YSE::POP_MESSAGE::POSITION[:x_buffer]
        fix_position_bubble(battler)
        set_bubble_tag(battler)
        @name_window.update_pos if $imported["YEA-MessageSystem"] && @name_window.open?
        @face_window.set_position if !chatter? && @face_window.open?
      end
    end
  end
  # overwrite
  def fix_default_message
    self.width = window_width
    self.height = window_height
    self.x = 0
    @face_window.hide_face if @face_window
    #create_contents
    return unless YSE::POP_MESSAGE::EFFECT[:use_bubble_tag]
    @speech_bubble_tag.visible = false if @speech_bubble_tag
    @thought_bubble_tag.visible = false if @thought_bubble_tag
  end
  # overwrite
  def fix_position_bubble(character)
    end_x = self.x + self.width
    end_y = self.y + self.height
    self.x = 0 if self.x < 0
    self.y = character.screen_y + @oy if self.y < 0
    self.y = -99 if self.y < 0
    self.x = Graphics.width - self.width if end_x > Graphics.width
    self.y = Graphics.height - self.height if end_y > Graphics.height
  end
  # overwrite
  def set_bubble_tag(character)
    return unless YSE::POP_MESSAGE::EFFECT[:use_bubble_tag]
    return unless @bubble_tag
    up = self.y == character.screen_y + @oy
    if self.y == -99
      self.y = 0
      up = true
    end
    self.y += up ? @bubble_tag.height / 2 : -@bubble_tag.height / 2
    @bubble_tag.x = character.screen_x + @ox - @bubble_tag.width / 2
    if up
      @bubble_tag.src_rect.set(0, @bubble_tag.height, @bubble_tag.width, @bubble_tag.height)
      @bubble_tag.y = self.y - @bubble_tag.height - YSE::POP_MESSAGE::POSITION[:tag_y_buffer]
    else
      @bubble_tag.src_rect.set(0, 0, @bubble_tag.width, @bubble_tag.height)
      @bubble_tag.y = self.y + self.height + YSE::POP_MESSAGE::POSITION[:tag_y_buffer]
    end
    @bubble_tag.z = self.z + 1000
  end
  # overwrite
  def adjust_pop_message(text = " ")
    #return unless SceneManager.scene_is?(Scene_Map)
    unless @event_pop_id
      if $imported["YEA-MessageSystem"]
        #adjust_message_window_size
      end
      return
    end
    n_line = cal_number_line(text)
    n_line = YSE::POP_MESSAGE::LIMIT[:limit_line] if YSE::POP_MESSAGE::LIMIT[:limit_line] > 0 && cal_number_line(text) > YSE::POP_MESSAGE::LIMIT[:limit_line]
    @real_lines = n_line
    self.height = fitting_height(n_line)
    self.height += @msg_size_y
    self.width = cal_width_line(text) + 10
    self.width += @msg_size_x
    self.width += new_line_x
    if self.width > YSE::POP_MESSAGE::LIMIT[:limit_width] && YSE::POP_MESSAGE::LIMIT[:limit_width] > 0
      self.width = YSE::POP_MESSAGE::LIMIT[:limit_width]
    end
    if $game_message.choice? && !QUACK::MSG::POP_CHOICE_GROW
      dy = fitting_height($game_message.choices.size) - 16
      self.y -= dy - 16
      self.height += dy - 16
      @face_window.y -= dy - 16
      @name_window.y -= dy - 16 if $imported["YEA-MessageSystem"]
    end
    # If a chatter message with face graphic, force height to be at least big enough to show the face.
    if chatter? && !source.face_name.empty?
      self.height = [self.height, 86].max
    end
   
    create_contents
    update_placement
  end
  # alias
  alias yse_pop_dispose dispose
  def dispose
    @speech_bubble_tag.visible = false if @speech_bubble_tag
    @thought_bubble_tag.visible = false if @thought_bubble_tag
    yse_pop_dispose
  end
  # alias
  alias chatter_msg_input_choice input_choice
  def input_choice
    if !close? && pop_message? && QUACK::MSG::POP_CHOICE_GROW
      f = Fiber.new { add_room_for_choices }
      @choice_window.visible = false
      @choice_window.set_fiber(f)
      f.resume
    end
    chatter_msg_input_choice
  end
  # new
  def add_room_for_choices
    q = fitting_height($game_message.choices.size) - 16
    i = 0
    while true
      i += 4
      self.y -= 4
      self.height += 4
      @face_window.y -= 4
      @name_window.y -= 4 if $imported["YEA-MessageSystem"]
      break if i >= q
      Fiber.yield
    end
    @choice_window.visible = true
    @choice_window.set_fiber(nil)
  end
  # new
  def pop_message?
    @event_pop_id
  end
end

#==============================================================================
# ?! Window_ChoiceList
#==============================================================================
class Window_ChoiceList < Window_Command
  # alias
  alias chatter_msg_init initialize
  def initialize(message_window)
    chatter_msg_init(message_window)
    self.opacity = 0
    self.z = 20070
  end
  # new
  def set_fiber(fiber)
    @fiber = fiber
  end
  # alias
  alias chatter_msg_update update
  def update
    chatter_msg_update
    @fiber.resume if @fiber
  end
  # alias
  alias chatter_msg_update_placement update_placement
  def update_placement
    if @message_window.pop_message?
      self.opacity = 0
      self.width = @message_window.width-26 + padding * 2
      self.width = [width, Graphics.width].min
      self.height = fitting_height($game_message.choices.size)
      self.x = @message_window.x
      self.y = @message_window.y+@message_window.height-self.height+6
    else
      self.opacity = 255
      chatter_msg_update_placement
    end
  end
end

class Window_NameMessage < Window_Base
  #def hide_me
  #  self.x = 99999
  #  self.y = 99999
  #end
end

#==============================================================================
# ■ Window_NameMessage
#==============================================================================
class Window_NameMessage < Window_Base
  # alias
  alias quack_msg_name_init initialize
  def initialize(message_window)
    quack_msg_name_init(message_window)
    self.z += 2
  end
  # new
  def update_pos
    set_x_position(1)
    #set_y_position
    self.y = @message_window.y - self.height / 1.25
    self.y = 0 if self.y < 0
  end
  # overwrite
      #  self.y = @message_window.height
      #  self.y -= YEA::MESSAGE::NAME_WINDOW_Y_BUFFER
      #else
      #  self.y = @message_window.y - self.height / 1.25
      #  self.y += YEA::MESSAGE::NAME_WINDOW_Y_BUFFER
      #end
end
  
#==============================================================================
# ¡ Window_Message_Face
#==============================================================================

class Window_Message_Face < Window_Base
  alias quack_msg_face_pos set_position
  def set_position
    quack_msg_face_pos
    self.y -= 4
  end
end

#==============================================================================
# ?! Window_Quack_Message
#==============================================================================
class Window_Quack_Message < Window_Message
  attr_accessor :active
  
  # overwrite
  def initialize(msg_source, zz)
    super()
    self.z = zz
    @quack_msg_source = msg_source
    @active = false
    @background = 0
    self.opacity = 255
    self.visible = false
    clear_name_window if $imported["YEA-MessageSystem"]
  end
  # overwrite
  def chatter?
    true
  end
  # overwrite
  def source
    @quack_msg_source
  end
  # overwrite
  def update
    if @quack_msg_source.busy?
      if @quack_msg_source.expire?
        close
      else
        self.visible = true if !self.visible
        @quack_msg_source.ttl_sub
      end
    end
    self.visible = false if self.visible && close?
    super
  end
  # overwrite
  def update_placement
    return if @closing
    super
  end
  # overwrite
  def update_show_fast
    return false
  end
  # overwrite
  def process_all_text
    @event_pop_id = nil
    text = convert_escape_characters(@quack_msg_source.all_text)
    update_placement
    adjust_pop_message(text)
    open_and_wait
    #text = convert_escape_characters(@quack_msg_source.all_text)
    pos = {}
    new_page(text, pos)
    process_character(text.slice!(0, 1), text, pos) until text.empty? || close?
  end
  # overwrite
  def close
    pop_message_close #super
    return unless @event_pop_id
    return unless YSE::POP_MESSAGE::EFFECT[:use_bubble_tag]
    @speech_bubble_tag.visible = false if @speech_bubble_tag
    @thought_bubble_tag.visible = false if @thought_bubble_tag
    source.ev_id = nil
    @name_text = ""
  end
  # overwrite
  def input_pause
    self.pause = true
    wait(10)
    Fiber.yield until close?
    self.pause = false
  end
  # overwrite
  def update_fiber
    if @fiber
      @fiber.resume
    elsif @quack_msg_source.busy?
      @fiber = Fiber.new { fiber_main }
      @fiber.resume
    else
      @quack_msg_source.visible = false
    end
  end
  def fiber_main
    @quack_msg_source.visible = true
    #update_background
    update_placement
    loop do
      process_all_text if @quack_msg_source.has_text?
      process_input
      @quack_msg_source.clear
      @name_window.start_close if $imported["YEA-MessageSystem"]
      Fiber.yield
      break unless text_continue?
    end
    close_and_wait
    @quack_msg_source.visible = false
    @fiber = nil
  end
  #def update_background
  #  @background = @quack_msg_source.background
  #  self.opacity = @background == 0 ? 255 : 0
  #end
  def process_input
    input_pause unless @pause_skip
  end
  def text_continue?
    @quack_msg_source.has_text?# && !settings_changed?
  end
  def settings_changed?
    #@background != $game_message.background ||
    #@position != @quack_msg_source.position
    false
  end
  def new_page(text, pos)
    contents.clear
    draw_face(@quack_msg_source.face_name, @quack_msg_source.face_index, 0, 0)
    reset_font_settings
    pos[:x] = new_line_x
    pos[:y] = 0
    pos[:new_x] = new_line_x
    pos[:height] = calc_line_height(text)
    clear_flags
  end
  def new_line_x
    @quack_msg_source.face_name.empty? ? 0 : 112
  end
  # overwrite
  def input_pause
    #self.pause = true
    wait(10)
    Fiber.yield until @quack_msg_source.expire? #Input.trigger?(:B) || Input.trigger?(:C)
    #Input.update
    #self.pause = false
  end
  
  # overwrite
  def create_all_windows
    @name_window = Window_NameMessage.new(self) if $imported["YEA-MessageSystem"]
  end
  # overwrite
  def dispose_all_windows
    @name_window.dispose if $imported["YEA-MessageSystem"]
  end
  # overwrite
  def update_all_windows
    if $imported["YEA-MessageSystem"]
      @name_window.update
      @name_window.back_opacity = self.back_opacity
      @name_window.opacity = self.opacity
    end
  end
  # overwrite
  def event_pop_message_update_placement
  end
  # overwrite
  def all_close?
    close? && (!$imported["YEA-MessageSystem"] || @name_window.close?)
  end
  
  if $imported["YEA-MessageSystem"]
    def close_and_wait
      @name_window.force_close
      window_message_close_and_wait_ams
    end
  end
end

#==============================================================================
# ?! Scene_Map
#==============================================================================

class Scene_Map < Scene_Base
  # alias
  alias quack_msg_update update
  def update
    @quack_msgs.each {|m|
      m.update
      if m.open?
        m.update_placement
      end
    }
    @message_window.update_placement if @message_window.open?
    quack_msg_update
  end
  # overwrite
  def create_message_window
    yse_pm_create_message_window
    @face_window = Window_Message_Face.new
    @face_window.message_window = @message_window
    if @bubble_tag_sprite || @thought_bubble_tag_sprite
    @bubble_tag_sprite.dispose
    @thought_bubble_tag_sprite.dispose
    end
    if YSE::POP_MESSAGE::EFFECT[:use_bubble_tag]
      @bubble_tag_sprite = Sprite.new
      @bubble_tag_sprite.visible = false
      @bubble_tag_sprite.bitmap = Cache.system(YSE::POP_MESSAGE::EFFECT2[:bubble_tag_name])
      @bubble_tag_sprite.src_rect.set(0, 0, @bubble_tag_sprite.width, @bubble_tag_sprite.height / 2)
      @message_window.speech_bubble_tag = @bubble_tag_sprite
      
      @thought_bubble_tag_sprite = Sprite.new
      @thought_bubble_tag_sprite.visible = false
      @thought_bubble_tag_sprite.bitmap = Cache.system(YSE::POP_MESSAGE::EFFECT2[:thought_bubble_tag_name])
      @thought_bubble_tag_sprite.src_rect.set(0, 0, @thought_bubble_tag_sprite.width, @thought_bubble_tag_sprite.height / 2)
      @message_window.thought_bubble_tag = @thought_bubble_tag_sprite
    end
    @message_window.face_window = @face_window
   
    quack_msg_create_msg
  end
  # new
  def quack_msg_create_msg
    unless @quack_msgs.nil?
      @quack_msgs.each {|m| m.dispose}
      @quack_msg_speech_bubble_sprites.each {|s| s.dispose}
      @quack_msg_thought_bubble_sprites.each {|s| s.dispose}
    end
    @quack_msgs = []
    @quack_faces = []
    @quack_msg_speech_bubble_sprites = []
    @quack_msg_thought_bubble_sprites = []
    QUACK::MSG::MAX_MSGS.times do |i|
      qm = Window_Quack_Message.new($game_message.quack_msgs, 200-QUACK::MSG::MAX_MSGS+i)
      @quack_msgs.push(qm)
      ss = Sprite.new
      ss.visible = false
      ss.bitmap = Cache.system(YSE::POP_MESSAGE::EFFECT2[:bubble_tag_name])
      ss.src_rect.set(0, 0, ss.width, ss.height / 2)
      qm.speech_bubble_tag = ss
      ts = Sprite.new
      ts.visible = false
      ts.bitmap = Cache.system(YSE::POP_MESSAGE::EFFECT2[:thought_bubble_tag_name])
      ts.src_rect.set(0, 0, ts.width, ts.height / 2)
      qm.thought_bubble_tag = ts
    end
  end
  # overwrite
  def dispose_spriteset
    pop_message_dispose_spriteset
    #@quack_msg_speech_bubble_sprites.each {|s| s.dispose}
    #@quack_msg_thought_bubble_sprites.each {|s| s.dispose}
    #return unless @bubble_tag_sprite || @thought_bubble_tag_sprite
    #@bubble_tag_sprite.dispose
    #@thought_bubble_tag_sprite.dispose
  end
  # alias
  #alias quack_msg_dispose_all_windows dispose_all_windows
  #def dispose_all_windows
  #  @quack_msgs.each {|m| m.dispose}
  #  quack_msg_dispose_all_windows
  #end
end

#==============================================================================
# ?! Scene_Battle
#==============================================================================
class Scene_Battle
  alias quack_update_basic update_basic
  def update_basic
    quack_update_basic
    @quack_msgs.each {|m|
      m.update
      if m.open?
        m.update_placement
      end
    }
  end
  
  alias yse_pop_create_message_window create_message_window
  def create_message_window
    yse_pop_create_message_window
    @face_window = Window_Message_Face.new
    @face_window.message_window = @message_window
    if YSE::POP_MESSAGE::EFFECT[:use_bubble_tag]
      @bubble_tag_sprite = Sprite.new
      @bubble_tag_sprite.visible = false
      @bubble_tag_sprite.bitmap = Cache.system(YSE::POP_MESSAGE::EFFECT2[:bubble_tag_name])
      @bubble_tag_sprite.src_rect.set(0, 0, @bubble_tag_sprite.width, @bubble_tag_sprite.height / 2)
      @message_window.speech_bubble_tag = @bubble_tag_sprite
      
      @thought_bubble_tag_sprite = Sprite.new
      @thought_bubble_tag_sprite.visible = false
      @thought_bubble_tag_sprite.bitmap = Cache.system(YSE::POP_MESSAGE::EFFECT2[:thought_bubble_tag_name])
      @thought_bubble_tag_sprite.src_rect.set(0, 0, @thought_bubble_tag_sprite.width, @thought_bubble_tag_sprite.height / 2)
      @message_window.thought_bubble_tag = @thought_bubble_tag_sprite

    end
    @message_window.face_window = @face_window
   
    quack_create_message_window
  end
  
  def quack_create_message_window
    @quack_msgs = []
    @quack_msg_speech_bubble_sprites = []
    @quack_msg_thought_bubble_sprites = []
    QUACK::MSG::MAX_MSGS.times do |i|
      qm = Window_Quack_Message.new($game_message.quack_msgs, 200-QUACK::MSG::MAX_MSGS+i)
      @quack_msgs.push(qm)
      ss = Sprite.new
      ss.visible = false
      ss.bitmap = Cache.system(YSE::POP_MESSAGE::EFFECT2[:bubble_tag_name])
      ss.src_rect.set(0, 0, ss.width, ss.height / 2)
      qm.speech_bubble_tag = ss
      ts = Sprite.new
      ts.visible = false
      ts.bitmap = Cache.system(YSE::POP_MESSAGE::EFFECT2[:thought_bubble_tag_name])
      ts.src_rect.set(0, 0, ts.width, ts.height / 2)
      qm.thought_bubble_tag = ts
    end
  end
  
  alias yse_pop_dispose_spriteset dispose_spriteset
  def dispose_spriteset
    yse_pop_dispose_spriteset
    @quack_msg_speech_bubble_sprites.each {|s| s.dispose}
    @quack_msg_thought_bubble_sprites.each {|s| s.dispose}
    return unless @bubble_tag_sprite || @thought_bubble_tag_sprite
    @bubble_tag_sprite.dispose
    @thought_bubble_tag_sprite.dispose
  end
  
  alias quack_msg_dispose_all_windows dispose_all_windows
  def dispose_all_windows
    @quack_msgs.each {|m| m.dispose}
    quack_msg_dispose_all_windows
  end
end

#==============================================================================
# ?! Game_Interpreter
#==============================================================================
class Game_Interpreter
  def command_101
    item = $data_items[20]
    if $imported["YEA-MessageSystem"]
      wait_for_message
      $game_message.face_name = @params[0]
      $game_message.face_index = @params[1]
      $game_message.background = @params[2]
      $game_message.position = @params[3]
      
      startindex = @index+1
      textline = @list[startindex].parameters[0].dup
      chatdur = 0
      textline.gsub!(/<cm:([^<>]*)>/i) { chatdur = $1.to_i;"" }
      $game_message.prepare_msg(chatdur) if chatdur != 0
      while continue_message_string?
        @index += 1
        if @list[@index].code == 401
          textline = @list[@index].parameters[0] unless @index == startindex
          if chatdur != 0; $game_message.add_chatter(textline)
          else; $game_message.add(textline)
          end
        end
        break if $game_message.texts.size >= Variable.message_rows
      end
      case next_event_code
      when 102
        @index += 1
        setup_choices(@list[@index].parameters)
      when 103
        @index += 1
        setup_num_input(@list[@index].parameters)
      when 104
        @index += 1
        setup_item_choice(@list[@index].parameters)
      end
      $game_message.fin_msg if chatdur != 0
      wait_for_message
    else
      wait_for_message
      $game_message.face_name = @params[0]
      $game_message.face_index = @params[1]
      $game_message.background = @params[2]
      $game_message.position = @params[3]
      
      startindex = @index+1
      textline = @list[startindex].parameters[0].dup
      chatdur = 0
      textline.gsub!(/<cm:([^<>]*)>/i) { chatdur = $1.to_i;"" }
      $game_message.prepare_msg(chatdur) if chatdur != 0
      
      while next_event_code == 401       # Text data
        @index += 1
        textline = @list[@index].parameters[0] unless @index == startindex
        if chatdur != 0; $game_message.add_chatter(textline)
        else; $game_message.add(textline)
        end
      end
      case next_event_code
      when 102  # Show Choices
        @index += 1
        setup_choices(@list[@index].parameters)
      when 103  # Input Number
        @index += 1
        setup_num_input(@list[@index].parameters)
      when 104  # Select Item
        @index += 1
        setup_item_choice(@list[@index].parameters)
      end
      $game_message.fin_msg if chatdur != 0
      wait_for_message
    end
  end
  # new
  def clear_chatter
    $game_message.clear_chatter
  end
end

#==============================================================================
#
# ?\ End of File
#
#==============================================================================








[pre lang="ruby"]=begin
#==============================================================================
* Qonvenience - v1.0e
  Author: Quack
#==============================================================================

What it is and what does it do?
-------------------------------------------------------------------------------
-Code that I have made for my own conveniece and use for some of my scripts.
Other than needing it if you plan to use certain scripts I've written it
adds some functionality others might be interested in listed below:

-Adds event self variables.
Usage: (event_id should be a number and key can be what you want. Usually a
          number or a string)
  -Set var: L[event_id,key] = "a_value"  OR   event.tset(key,"a_value")
  -Get var: somevar = L[event_id,key]    OR   somevar = event.tget(key)

-Can access event self switches similar to self vars.
Usage:
  -Set switch: SS[event_id,"A"] = true   OR   event.sset("B",false)
  -Get switch: somevar = SS[event_id,"A"] OR  event.sget("C")

-Game variables and game switches can also be accessed with shorter commands
using V[23] = 200, somevar = V[2] for game variables and S[4] = true,
somevar = S[5] for game switches.

-Adds map local variables. That is variables that are unique to that map.
Usage:
  -Set var: M[key] = 123
  -Get var: somevar = M[key]

-Adds Temporary variables that reset on map chage. There exists both map wide
and event self temporary variables.
Usage:
-To set or get a normal temp var you do this:
    TMP["a_key"] = 9999   OR  TMP[7] = "some_value"
    somevar = TMP["another_key"]  OR  somevar = TMP[13]
-To set or get an event self tmp var:
    event.tset("a_key","a_value")
    event.tget("a_key")
    TMP[event.id,"a_key"] = "a_value"  # works too
   
-Adds a functionality for enemy respawning. It doesn't do anything unless you
actually use it. I would have taken it out and put it a separate script but I
didn't feel like it. A bunch of extra methods aliases and waste of time.
If you have no interest in this just skip to the next point instead.
I use visible enemies that chase you in my game. When an enemy dies I set it's
self A switch to ON to make it stay dead. I did this because I didn't want
them to respawn everytime I went into the room. But I didn't want them stay
dead forever either. What I did was add a counter to each map that is set to
a certain value (depends on a game variable, which variable you decide in the
config area below). Whenever you change map that value is reduced by 1 for all
maps. When the value gets to 0 all events with the tag <en> in their name on
that map gets their 'A' self switch set to OFF so they will respawn. So if you
set the variable to 2 you have to walk at least 2 maps away from a certain map
for that maps enemies to respawn. It is also possible you might want all
enemies to stay dead in a dungeon until you leave that dungeon. To do this
you would set the game variable to a really high value so the enemies will
never respawn from you walking to other maps upon entering the dungeon. And
when you leave you set it back and also do this script call:
   $game_respawnVars.clear
So to use this all your respawnable enemies would have to use the self switch
'A' as ON to make it dead and they also need to have the tag <en> in their
event name.
   
-Some things for Move routes.
-Designate event to move via code evaluation by setting the first command in
  a move route to script call starting with '[v]' followed by code that can
  be evaluated to a number like: '[v]20-5' OR '[v]V[12]'

-Like with move routes you can now using jump to label designate a label to
jump to via code evaluation by setting the label name in the jump to label
command to '[v]' followed by code that can be evaluated to a string.
  Like so: '[v]"my label"' OR '[v]V[34]' OR '[v]"my label" + M[2]'

-Call an event page like you would call a common event using this method in
a script call: call_event(event_id, page_number)

-Support for editor suffixes.
  Have you ever had multiple versions of the same skill, all with same name?
  Or wanted to add a comment to an enemy's name to help you remember exactly
  what that enemy is and/or does just by seeing it in the list rather than
  having to click it and check it's details?
  Then this is it. With this script active any text following and including
  the first '(' in a database object's name will get removed in-game.
  For example let's say I have a couple of key items which are all for a
  certain sidequest, lets call it the "Pink Elephant" quest. Therefore I add
  '(Pink Elephant)' to the name of each of those key items so they are easy to
  spot in the list. So lets say one of these key items is the "Golden Peanut".
  That item now has the name "Golden Peanut(Pink Elephant)" in the editor.
  But in-game it still has the name "Golden Peanut" because the pink elephant
  part gets removed.

Requirements:
None

Instructions/Install notes:
Paste it below Materials like you would any other script.

Terms of Use:
Use it however you wish (yes, that does include commercial projects), as long
as you do not claim it as your own code. I would also prefer you mention me in
your credits if you do decide to use it.

Bugs:
dunno

History:
13/01/2016 - Added comments, cleaned code and uploaded it since my Chatter
             Messages script requires it.
  
=end

$imported = {} if $imported.nil?
$imported["Qonvenience"] = true

#==============================================================================
# CONFIG
#==============================================================================
module QUACK
  
  # 在切换地图时自动改变BGM的开关
  TURN_OFF_AUTO_BGM_PLAY_SWITCH = 20
  
  # 变量,设定从当前地图离开后,再经过多少地图,敌人会重生。
  RESPAWN_ROOM_COUNT = 12
  
end
#==============================================================================
# SCRIPT START
#==============================================================================

#==============================================================================
# DataManager - Local variables & item names
# -----------------------------------------------------------------------------
# Adds hashes for new variables and removes text from all database item names
# from the first encountered '('. Useful in for example when you have several
# versions of the same skill (a levelable skill perhaps) and want them all to
# have the same name but still be able to easily tell them apart in the editor.
#==============================================================================
module DataManager
  class << self
   
    #--------------------------------------------------------------------------
    # alias: Create Game Objects
    #--------------------------------------------------------------------------
    alias local_create_game_objects create_game_objects
    def create_game_objects
      local_create_game_objects
      $game_selfVars = {}#Simple_Matrix.new
      $game_mapVars = {}
      $game_respawnVars = {}
      $game_tempVars = {}
      #$game_database = Database.finalize
    end
   
    #--------------------------------------------------------------------------
    # alias: Make Save Contents
    #--------------------------------------------------------------------------
    alias local_make_save_contents make_save_contents
    def make_save_contents
      contents = local_make_save_contents
      contents[:self_vars] = $game_selfVars
      contents[:map_vars] = $game_mapVars
      contents[:respawn_vars] = $game_respawnVars
      contents[:tmp_vars] = $game_tempVars
      contents
    end
      
    #--------------------------------------------------------------------------
    # alias: Extract Save Contents
    #--------------------------------------------------------------------------
    alias local_extract_save_contents extract_save_contents
    def extract_save_contents(contents)
      local_extract_save_contents(contents)
      $game_selfVars = contents[:self_vars]
      $game_mapVars = contents[:map_vars]
      $game_tempVars = contents[:tmp_vars]
      $game_respawnVars = contents[:respawn_vars]
      #$game_database = Database.finalize
     end
      
    #--------------------------------------------------------------------------
    # alias: Load database
    #--------------------------------------------------------------------------
    alias load_database_item_names load_database
    def load_database
      load_database_item_names
      load_item_names
      load_notetags_type_tags
    end
   
    #--------------------------------------------------------------------------
    # new: Load Type Tags
    #--------------------------------------------------------------------------
    def load_notetags_type_tags
      for obj in $data_states
        next if obj.nil?
        obj.load_notetags_type_tags
      end
      for obj in $data_skills
        next if obj.nil?
        obj.load_notetags_type_tags
      end
      for obj in $data_items
        next if obj.nil?
        obj.load_notetags_type_tags
      end
      for obj in $data_weapons
        next if obj.nil?
        obj.load_notetags_type_tags
      end
      for obj in $data_armors
        next if obj.nil?
        obj.load_notetags_type_tags
      end
      for obj in $data_actors
        next if obj.nil?
        obj.load_notetags_type_tags
      end
      for obj in $data_enemies
        next if obj.nil?
        obj.load_notetags_type_tags
      end
    end
         
    #--------------------------------------------------------------------------
    # new: Remove Editor suffixes from items
    #--------------------------------------------------------------------------
    def load_item_names
      for actor in $data_actors
        next if actor.nil?
        actor.name = actor.name.partition("(")[0]
      end
      for clas in $data_classes
        next if clas.nil?
        clas.name = clas.name.partition("(")[0]
      end
      for item in $data_items
        next if item.nil?
        item.name = item.name.partition("(")[0]
      end
      for weapon in $data_weapons
        next if weapon.nil?
        weapon.name = weapon.name.partition("(")[0]
      end
      for armor in $data_armors
        next if armor.nil?
        armor.name = armor.name.partition("(")[0]
      end
      for skill in $data_skills
        next if skill.nil?
        skill.name = skill.name.partition("(")[0]
      end
      for state in $data_states
        next if state.nil?
        state.name = state.name.partition("(")[0]
      end
      for enemy in $data_enemies
        next if enemy.nil?
        enemy.name = enemy.name.partition("(")[0]
      end
    end
  end
end

class RPG::BaseItem
  attr_accessor :type_tags

  def has_tag?(tag)
    return @type_tags.include?(tag)
  end
  
  def load_notetags_type_tags
    @type_tags = self.note =~ /<TAGS:([^<>]*)>/i ? $1 : ""
  end
end # RPG::BaseItem

#==============================================================================
# TEMPORARY VARIABLES (reset on map change)
#==============================================================================
class TMP
  class << self
    def [](*arg)#id)
      case arg.length
        when 1
          return 0 if $game_tempVars[[arg[0]]].nil?
          return $game_tempVars[[arg[0]]]
        when 2
          return 0 if $game_tempVars[[arg[0], arg[1]]].nil?
          return $game_tempVars[[arg[0], arg[1]]]
      end
    end
   
    def []=(*arg)#id, val)
      case arg.length
        when 2; $game_tempVars[[arg[0]]] = arg[1]
        when 3; $game_tempVars[[arg[0],arg[1]]] = arg[2]
      end
      $game_map.need_refresh = true
    end  
   
    def clear
      $game_tempVars.clear
    end
  end
end
class T
  class << self
    def [](*arg)
      case arg.length
        when 1
          return 0 if $game_tempVars[[arg[0]]].nil?
          return $game_tempVars[[arg[0]]]
        when 2
          return 0 if $game_tempVars[[arg[0], arg[1]]].nil?
          return $game_tempVars[[arg[0], arg[1]]]
      end
    end
   
    def []=(*arg)
      case arg.length
        when 2; $game_tempVars[[arg[0]]] = arg[1]
        when 3; $game_tempVars[[arg[0],arg[1]]] = arg[2]
      end
      $game_map.need_refresh = true
    end
   
    def clear
      $game_tempVars.clear
    end
  end
end

#==============================================================================
# MAP LOCAL VARIABLES
#==============================================================================
class M
  class << self
    def [](var_id)
      return 0 if $game_mapVars[[$game_map.map_id,var_id]].nil?
      return $game_mapVars[[$game_map.map_id,var_id]]
    end
   
    def []=(var_id, value)
      $game_mapVars[[$game_map.map_id,var_id]] = value
      $game_map.need_refresh = true
    end
  end
end

#==============================================================================
# EVENT LOCAL VARIABLES
#==============================================================================
class L
  class << self
    def [](eid, vid)
      return 0 if $game_selfVars[[$game_map.map_id,eid,vid]].nil?
      return $game_selfVars[[$game_map.map_id,eid,vid]]
    end
   
    def []=(eid, vid, value)
      $game_selfVars[[$game_map.map_id,eid,vid]] = value
      $game_map.need_refresh = true
    end
  end
end

#==============================================================================
# SELF SWITCHES
#==============================================================================
class SS
  class << self
    def [](eid, vid)
      return false if $game_self_switches[[$game_map.map_id, eif, vid]].nil?
      return $game_self_switches[[$game_map.map_id, eif, vid]]
    end
   
    def []=(eid, vid, value)
      $game_self_switches[[$game_map.map_id,eid,vid]] = value
      $game_map.need_refresh = true
    end
  end
end

#==============================================================================
# GLOBAL VARIABLES
#==============================================================================
class V
  class << self
    def [](id)
      return 0 if id < 1
      return $game_variables[id]
    end
   
    def []=(id, value)
      $game_variables[id] = value
    end
  end
end

#==============================================================================
# GLOBAL SWITCHES
#==============================================================================
class S
  class << self
    def [](id)
      return false if id < 1
      return $game_switches[id]
    end
   
    def []=(id, value)
      $game_switches[id] = value
    end
  end
end

#==============================================================================
#==============================================================================

class Game_Battler < Game_BattlerBase
  #--------------------------------------------------------------------------
  # new: Check if battler has that tag
  #--------------------------------------------------------------------------
  def has_tag?(tag)
    return $data_enemies[@enemy_id].has_tag?(tag)
  end
  
  #--------------------------------------------------------------------------
  # new: Check if battler has state with that tag
  #--------------------------------------------------------------------------
  def tagged_state?(tag)
    for state in states
      return true if state.type_tags.include?(tag)
    end
    return false
  end
  
  #--------------------------------------------------------------------------
  # new: Remove states with specified tag
  #--------------------------------------------------------------------------
  def remove_tagged_states(tag)
    rstates = []
    s = states
    for state in s
      if state.type_tags.include?(tag)
        remove_state(state.id)
        rstates.push(state)
      end
    end
    return rstates
  end
  
  #--------------------------------------------------------------------------
  # new: Return all states battler has with specified tag
  #--------------------------------------------------------------------------
  def states_with_tags(tag)
    s = []
    for state in states
      s.push(state.id) if state.type_tags.include?(tag)
    end
    return s
  end
end

class Game_Actor < Game_Battler
  #--------------------------------------------------------------------------
  # new: Check if battler has that tag
  #--------------------------------------------------------------------------
  def has_tag?(tag)
    return actor.has_tag?(tag)
  end
end

class RPG::Troop::Page
  attr_reader :note_tags
  attr_reader :custom_condition
  
  def setup_notetags
    @note_tags = ""
    return if !@list || @list.size <= 0
    # build note tags
    @list.each {|i|
      @note_tags += i.parameters[0] if i && (i.code == 108 || i.code == 408)
    }
    # find page custom condition if there is one
    @custom_condition = @note_tags =~ /<CC>(.*)<\/CC>/i ? $1 : nil
  end
end

class Game_Troop
  # METHODS FOR CUSTOM EVENT CONDITIONS
  alias quack_qon_setup setup
  def setup(troop_id)
    quack_qon_setup(troop_id)
    troop.pages.each{|p| p.setup_notetags }
  end
  
  alias quack_qon_conditions_met conditions_met?
  def conditions_met?(page)
    r = quack_qon_conditions_met(page)
    return false if has_custom_cond?(page) && custom_cond_fail(page)
    return r
  end
  
  def has_custom_cond?(page)
    !page.custom_condition.nil?
  end
  
  def custom_cond_fail(page)
    return !eval(page.custom_condition)
  end
end

class Game_Map
  attr_reader   :map_id
  
  #--------------------------------------------------------------------------
  # alias: Autoplay
  # Switch for turning off bgm auto starting new song when entering map
  #--------------------------------------------------------------------------
  alias quack_qon_autoplay autoplay
  def autoplay
    if S[QUACK::TURN_OFF_AUTO_BGM_PLAY_SWITCH]
      @map.bgs.play if @map.autoplay_bgs
    else
      quack_qon_autoplay
    end
  end
  
  #--------------------------------------------------------------------------
  # alias: Setup
  # Clear TMP vars, clear event name tags & update enemy respawn
  #--------------------------------------------------------------------------
  alias qack_qon_setup setup
  def setup(map_id)
    TMP.clear
    @q_name_tags = {}
    qack_qon_setup(map_id)
    if get_respawn(map_id) == 0
      e = all_event_tag('en')
      e.each {|ev| ev.sset("A",false) } unless e.nil?
    end
    for key in $game_respawnVars.keys
      $game_respawnVars[key] -= 1
    end
    $game_respawnVars[map_id] = V[QUACK::RESPAWN_ROOM_COUNT]
    $game_respawnVars.delete_if {|k,v| v <= 0 }
  end
  
  #--------------------------------------------------------------------------
  # new: Add Event Tags
  # Used for event name tags
  #--------------------------------------------------------------------------
  def add_event_tags(ev, pt)
    u = []
    # name tags
    t = ev.name.scan(/<([^<>]*)>/i)
    return if t.nil? || t.length < 1
    t.each {|s|
      if @q_name_tags.has_key?(s[0])
        @q_name_tags[s[0]].push(ev)
      else
        @q_name_tags[s[0]] = [ev]
      end
      ev.add_name_tag(s[0])
      u.push(s[0])
    }
    # page tags
    pt.each{|p|
      p.each{|pagtag|
        next if u.include?(pagtag)
        u.push(pagtag)
        if @q_name_tags.has_key?(pagtag)
          @q_name_tags[pagtag].push(ev)
        else
          @q_name_tags[pagtag] = [ev]
        end
      }
    }
  end
  
  #--------------------------------------------------------------------------
  # new: Delete Event Tags
  # Used for event name tags
  #--------------------------------------------------------------------------
  def delete_event_tags(ev)
    ev.name_tags.each{|s|
      @q_name_tags.delete(ev)
    }
  end
  
  #--------------------------------------------------------------------------
  # new: First Event With Tag
  # First event on map with specified tag
  #--------------------------------------------------------------------------
  def first_event_tag(tag)
    return nil unless @q_name_tags.has_key?(tag)
    #return @q_name_tags[tag][0]
    @q_name_tags[tag].each{|e|
      return e if e.has_name_tag?(tag)
    }
    return nil
  end
  #--------------------------------------------------------------------------
  # new: Last Event With Tag
  # Last event on map with specified tag
  #--------------------------------------------------------------------------
  def last_event_tag(tag)
    return nil unless @q_name_tags.has_key?(tag)
    #return @q_name_tags[tag][@q_name_tags[tag].length-1]
    @q_name_tags[tag].reverse_each{|e|
      return e if e.has_name_tag?(tag)
    }
  end
  #--------------------------------------------------------------------------
  # new: All Events With Tag
  # All events on map with specified tag
  #--------------------------------------------------------------------------
  def all_event_tag(tag)
    return nil unless @q_name_tags.has_key?(tag)
    #return @q_name_tags[tag]
    return @q_name_tags[tag].select{|e| e.has_name_tag?(tag) }
  end
  
  #--------------------------------------------------------------------------
  # new: get respawn
  # get respawn var
  #--------------------------------------------------------------------------
  def get_respawn(id)
    return $game_respawnVars[id] if $game_respawnVars.has_key?(id)
    return 0
  end
  
end


class Game_Character < Game_CharacterBase
  #--------------------------------------------------------------------------
  # alias: process_move_command
  #--------------------------------------------------------------------------
  alias process_move_command_movement_cmds_alias process_move_command
  def process_move_command(command)
    case command.code
      when ROUTE_SCRIPT
        return if command.parameters[0].include? '[v]'
    end
    process_move_command_movement_cmds_alias(command)
  end
  
  MOVE_SYMBOL_CODE = {
  :UP    => ROUTE_MOVE_UP,
  :DOWN  => ROUTE_MOVE_DOWN,
  :LEFT  => ROUTE_MOVE_LEFT,
  :RIGHT => ROUTE_MOVE_RIGHT,
  :FORWARD => ROUTE_MOVE_FORWARD,
  :BACKWARD => ROUTE_MOVE_BACKWARD,
  :TOWARD => ROUTE_MOVE_TOWARD,
  :AWAY => ROUTE_MOVE_AWAY,
  }
  
  #--------------------------------------------------------------------------
  # new method: opacity_tween
  #--------------------------------------------------------------------------
  def opacity_tween(opacity, duration)
    crnt_opacity = @opacity
    i = (opacity - crnt_opacity).to_f / duration
    for x in (0..duration)
      @move_route.list.insert(@move_route_index + x + 1, RPG::MoveCommand.new(ROUTE_CHANGE_OPACITY, [crnt_opacity.to_i]))
      crnt_opacity += i
      crnt_opacity = opacity if x == (duration-1)
    end
    @move_route.list.delete_at(@move_route_index)
  end

  #--------------------------------------------------------------------------
  # new method: move
  #--------------------------------------------------------------------------
  def move(dir, steps)
    dir = MOVE_SYMBOL_CODE[dir] if dir.is_a?(Symbol)
    for x in (1..steps)
      @move_route.list.insert(@move_route_index + x, RPG::MoveCommand.new(dir))
    end
    @move_route.list.delete_at(@move_route_index)
  end
  
  def gotoxy(x,y)
    @x = x
    @y = y
  end
  
  def moveto2(x, y)
    @x = x % $game_map.width
    @y = y % $game_map.height
    @real_x = @x
    @real_y = @y
  end
  
  def moveto2_d(l, d)
    @y -= l if d == 8
    @y += l if d == 2
    @x -= l if d == 4
    @x += l if d == 6
    @real_x = @x
    @real_y = @y
  end
  
  def set_move_speed(val)
    @move_speed = val
  end
  
  def clear_move_route
    @move_route = nil
    @move_route_index = 0
    @wait_count = 0
  end
  
  def turn_left
    set_direction(4)
  end
  def turn_right
    set_direction(6)
  end
  def turn_up
    set_direction(8)
  end
  def turn_down
    set_direction(2)
  end
end

class Game_Player < Game_Character
  alias init_alias initialize
  def initialize
    init_alias
    @move_input_enabled = true
  end
  
  def disable_move_input
    @move_input_enabled = false
  end
  
  def enable_move_input
    @move_input_enabled = true
  end
  
  def in_control?
    return @move_input_enabled
  end
  
  alias qon_movable movable?
  def movable?
    return false if !@move_input_enabled
    qon_movable
  end
  
  #alias move_by_input_alias move_by_input
  #def move_by_input
  #  return if !@move_input_enabled
  #  move_by_input_alias
  #end
end

class RPG::Event::Page
  attr_reader :page_tags
  attr_reader :note_tags
  attr_reader :custom_condition
  
  def setup_notetags
    @note_tags = ""
    @page_tags = []
    return if !@list || @list.size <= 0
    # build note tags
    @list.each {|i|
      @note_tags += i.parameters[0] if i && (i.code == 108 || i.code == 408)
    }
    # find page custom condition if there is one
    @custom_condition = note_tags =~ /<CC>(.*)<\/CC>/i ? $1 : nil
   
    # get page tags from note tags
    t = @note_tags.scan(/<t:([^<>]*)>/i)
    return if t.nil? || t.length < 1
    t.each{|pt|
      @page_tags.push(pt[0])
    }
  end
end

class Game_Event < Game_Character
  
  #--------------------------------------------------------------------------
  # alias: initialize
  # For event name tags.
  #--------------------------------------------------------------------------
  alias quack_qon_init initialize
  def initialize(map_id, event)
    quack_qon_init(map_id, event)
    pt = []
    @event.pages.each {|p|
      p.setup_notetags
      pt.push(p.page_tags)
    }
    $game_map.add_event_tags(self, pt)
  end
  #--------------------------------------------------------------------------
  # new: Add name tag
  # For event name tags.
  #--------------------------------------------------------------------------
  def add_name_tag(tag)
    if @name_tags.nil?
      @name_tags = [tag]
    else
      @name_tags.push(tag)
    end
  end
  def name_tags
    return [] if @name_tags.nil?
    return @name_tags
  end
  def has_name_tag?(tag)
    unless @name_tags.nil?
      return true if @name_tags.include?(tag)
    end
    return false if @page.nil? || @page.page_tags.nil?
    return true if @page.page_tags.include?(tag)
    return false
  end
  #--------------------------------------------------------------------------
  # new: Return event's name
  # For event name tags.
  #--------------------------------------------------------------------------
  def name
    return @event.name
  end
  
  def page_tags
    return @page.page_tags
  end
  
  def notetags_page
    return @page.note_tags
  #  return "" if !@page || !@page.list || @page.list.size <= 0
  #  return @notetags_page if @notetags_page
  #  @notetags_page = ""
  #  l = []
  #  @page.list.each {|i|
  #    @notetags_page += i.parameters[0] if i && (i.code == 108 || i.code == 408)
  #  }
  #  return @notetags_page
  end  
  def notetags
    return @notetags unless @notetags.nil?
    @notetags = ""
    @event.pages.each {|p|
      next if !p || !p.list || p.list.size <= 0
      @notetags += p.note_tags
    }
    return @notetags
  end
  
  # METHODS FOR CUSTOM EVENT CONDITIONS
  
  alias quack_qon_conditions_met conditions_met?
  def conditions_met?(page)
    r = quack_qon_conditions_met(page)
    return false if has_custom_cond?(page) && custom_cond_fail(page)
    return r
  end
  
  def has_custom_cond?(page)
    !page.custom_condition.nil?
  end
  
  def custom_cond_fail(page)
    return !eval(page.custom_condition)
  end
  
  # METHODS FOR ACCESSING THE EVENTS LOCAL VARIABLES AND SWITCHES
  
  #--------------------------------------------------------------------------
  # new: Get self var
  #--------------------------------------------------------------------------
  def lget(id)
    L[@id,id]
  end
  #--------------------------------------------------------------------------
  # new: Set self var
  #--------------------------------------------------------------------------
  def lset(id,val)
    $game_selfVars[[@map_id,@id,id]] = val
    $game_map.need_refresh = true
  end

  #--------------------------------------------------------------------------
  # new: Get self switch
  #--------------------------------------------------------------------------
  def sget(id)
    L[@id,id]
  end
  #--------------------------------------------------------------------------
  # new: Set self switch
  #--------------------------------------------------------------------------
  def sset(id,val)
    $game_self_switches[[@map_id,@id,id]] = val
    $game_map.need_refresh = true
  end
  
  #--------------------------------------------------------------------------
  # new: Get self temp var
  #--------------------------------------------------------------------------
  def tget(id)
    return TMP[@id,id]
  end
  #--------------------------------------------------------------------------
  # new: Set self temp var
  #--------------------------------------------------------------------------
  def tset(id,val)
    $game_tempVars[[@id,id]] = val
    $game_map.need_refresh = true
  end
  
  #--------------------------------------------------------------------------
  # new: Get Page
  # Needed for event page call
  #--------------------------------------------------------------------------
  def get_page(index)
    return @event.pages[index]
  end
end

class Game_Interpreter
  #--------------------------------------------------------------------------
  # * Self Vars
  #--------------------------------------------------------------------------
  
  #--------------------------------------------------------------------------
  # new: lget
  # get self var
  #--------------------------------------------------------------------------
  def lget(*arguments)
    result = 0
    case arguments.length
      when 1; result = $game_selfVars[[@map_id, @event_id, arguments[0]]]
      when 2; result = $game_selfVars[[@map_id, arguments[0], arguments[1]]]
      when 3; result = $game_selfVars[[arguments[0], arguments[1], arguments[2]]]
    end
    return result
  end
  #--------------------------------------------------------------------------
  # new: lset
  # set self var
  #--------------------------------------------------------------------------
  def lset(*arguments)
    case arguments.length
      when 2; $game_selfVars[[@map_id, @event_id, arguments[0]]] = arguments[1]
      when 3; $game_selfVars[[@map_id, arguments[0], arguments[1]]] = arguments[2]
      when 4; $game_selfVars[[arguments[0], arguments[1], arguments[2]]] = arguments[3]
    end
    $game_map.need_refresh = true
  end
  #--------------------------------------------------------------------------
  # * Self Switches
  #--------------------------------------------------------------------------
  
  #--------------------------------------------------------------------------
  # new: sget
  # get self switch
  #--------------------------------------------------------------------------
  def sget(*arguments)
    result = false
    case arguments.length
      when 1; result = $game_self_switches[[@map_id, @event_id, arguments[0]]]
      when 2; result = $game_self_switches[[@map_id, arguments[0], arguments[1]]]
      when 3; result = $game_self_switches[[arguments[0], arguments[1], arguments[2]]]
    end
    return result
  end
  #--------------------------------------------------------------------------
  # new: sset
  # set self switch
  #--------------------------------------------------------------------------
  def sset(*arguments)
    case arguments.length
      when 2; $game_self_switches[[@map_id, @event_id, arguments[0]]] = arguments[1]
      when 3; $game_self_switches[[@map_id, arguments[0], arguments[1]]] = arguments[2]
      when 4; $game_self_switches[[arguments[0], arguments[1], arguments[2]]] = arguments[3]
    end
    $game_map.need_refresh = true
  end
  
  #--------------------------------------------------------------------------
  # * Respawn Vars
  #--------------------------------------------------------------------------
  
  #--------------------------------------------------------------------------
  # new: get respawn
  # get respawn var
  #--------------------------------------------------------------------------
  def get_respawn(id)
    return $game_respawnVars[id] if $game_respawnVars.has_key?(id)
    return 0
  end
  #--------------------------------------------------------------------------
  # new: set respawn
  # set respawn var
  #--------------------------------------------------------------------------
  def set_respawn(id, value)
    $game_respawnVars[id] = value
  end
  
  #--------------------------------------------------------------------------
  # * Easier to remember fade commands
  #--------------------------------------------------------------------------
  def fade_in(duration)
    screen.start_fadein(duration)
  end
  def fade_out(duration)
    screen.start_fadeout(duration)
  end
  
  #--------------------------------------------------------------------------
  # alias: Temporarily Erase Event
  # For event name tags
  #--------------------------------------------------------------------------
  alias quack_qon_command_214 command_214
  def command_214
    $game_map.delete_event_tags($game_map.events[@event_id])
    quack_qon_command_214
  end
  
  #--------------------------------------------------------------------------
  # overwrite method: command_205 (Set Move Route)
  # ---------------------------------------------------
  # By making the first command in a move route a script call which starts
  # with '[v]' the rest of the script call be evaluated to an integer which
  # is used as character id to chose which event the move route pertains to.
  #--------------------------------------------------------------------------
  def command_205 # COMMAND SET MOVE ROUTE
    $game_map.refresh if $game_map.need_refresh
    character = get_character(@params[0])
    cmd = @params[1].list[0]
    if cmd.code == 45 # 45 = SCRIPT COMMAND
      if cmd.parameters[0].include? '[v]'
        @params[0] = eval(cmd.parameters[0][3..cmd.parameters[0].length])
        character = get_character(@params[0])
        #@params[1].list.delete_at(0)
      end
    end
    if character
      character.force_move_route(@params[1].dup)
      Fiber.yield while character.move_route_forcing if @params[1].wait
    end
  end
  
  #==========================================================================
  # * Jump to Label (edited to allow to jump to a label using a variable)
  #==========================================================================
  def command_119
    label_name = @params[0]
    if label_name.include? '[v]'
      label_name = eval(label_name[3..label_name.length])
    end
    @list.size.times do |i|
      if @list.code == 118 && @list.parameters[0] == label_name
        @index = i
        return
      end
    end
  end
  
  #==========================================================================
  # * Call event page
  #==========================================================================
  def call_event(event_id, page_id)
    qq = Game_Interpreter.new(@depth + 1)
    page = evs[event_id].get_page(page_id)
    qq.setup(page.list, event_id)
    qq.run
  end
  
  def ev; @event_id; end
  def evs; $game_map.events; end
  def events; $game_map.events; end
  def me; evs[ev]; end
  def pl; $game_player; end
  def player; $game_player; end
  def char(id); get_character(id); end
  def map; return $game_map; end
  def set_move_speed(char_id, val)
    get_character(char_id).set_move_speed(val)
  end
  
  def move_to_point(id,x,y,wait=false)
    c = char(id)
    c.move_to_point(x,y)
    Fiber.yield while c.move_route_forcing if wait
  end
  
  #--------------------------------------------------------------------------
  # new: First event with tag
  #--------------------------------------------------------------------------
  def first_event_tag(tag)
    $game_map.first_event_tag(tag)
  end
  #--------------------------------------------------------------------------
  # new: Last event with tag
  #--------------------------------------------------------------------------
  def last_event_tag(tag)
    $game_map.last_event_tag(tag)
  end
  #--------------------------------------------------------------------------
  # new: All events with tag
  #--------------------------------------------------------------------------
  def all_event_tag(tag)
    $game_map.all_event_tag(tag)
  end
  #--------------------------------------------------------------------------
  # new: Find all events with all the specified tags
  #--------------------------------------------------------------------------
  def find_events(*args)
    result = []
    evs.keys.each {|k|
      unless evs[k].name_tags.nil?
        if (args - evs[k].name_tags).empty?
          result.push(evs[k])
        end
      end
    }
    return result
  end
  
  def diff(val1, val2)
    return (val1 - val2).abs
  end
  
  def pos_diff(c1, c2)
    xd = c1.x - c2.x
    yd = c1.y - c2.y
    xd *= xd
    yd *= yd
    return Math.sqrt(xd+yd)
  end
  
  #returns true if the distance between char1 and char2 is greater than dist
  def distance_gt(ev1,ev2,dist)#id1, id2, dist)
    #xd = char(id1).x - char(id2).x
    #yd = char(id1).y - char(id2).y
    xd = ev1.x - ev2.x
    yd = ev1.y - ev2.y
    xd *= xd
    yd *= yd
    return (xd + yd) > dist * dist
  end
  
  # returns true if the difference between val1 and val2 is greater than i.
  def diff_gt(val1, val2, i)
    if val1 < val2 - i; return true; end
    if val1 > val2 + i; return true; end
    return false
  end
  
  # returns true if the position1 is equal to position2
  def pos_is?(*arg)
    case arg.length
      when 1
        c = arg[0]#get_character(arg[0])
        return c.x == me.x && c.y == me.y
      when 2
        c1 = arg[0]#get_character(arg[0])
        c2 = arg[1]#get_character(arg[1])
        return c1.x == c2.x && c1.y == c2.y
      when 3
        c1 = arg[0]#get_character(arg[0])
        return c1.x == arg[1] && c2.y == arg[2]
      when 4
        return arg[0] == arg[2] && arg[1] == arg[3]
    end
    return false
  end
  
  # Returns in which of the 4 directions char2 is related to char1
  def ev_dir(char1, char2)
    if diff(char1.x, char2.x) > diff(char1.y,char2.y)
      if char1.x < char2.x
        return 6
      else
        return 4
      end
    else
      if char1.y < char2.y
        return 2
      else
        return 8
      end
    end
  end
  
  def wait_rnd(min_dur, max_dur)
    duration = min_dur + rnd(max_dur - min_dur).to_i
    duration.times { Fiber.yield }
  end
  
  def break_loop #becuz who can remember that 113 = break?
    command_113
  end
  
  # Prepare for cutscene
  def prep_scene
    $game_system.menu_disabled = true
    $game_system.save_disabled = true
    pl.disable_move_input
  end
  
  #end cutscene
  def end_scene
    $game_system.menu_disabled = false
    $game_system.save_disabled = false
    pl.enable_move_input
  end
end[/pre]






我使用脚本的范例工程

https://rpg.blue/thread-405406-1-1.html
QQ截图20180210120241.png

这是放在新的工程里的

这是放在新的工程里的
梦石
0
星屑
915
在线时间
107 小时
注册时间
2017-12-2
回帖
51
 楼主| 发表于 2018-2-10 12:16:27 | 显示全部楼层
我又重新排除了一下插件脚本里的脚本是否冲突,发现并不是它们的原因,难道是上面的脚本出问题了???。。。。。。。。
会不会是我以前弄过忘记了
回复

使用道具 举报

梦石
0
星屑
915
在线时间
107 小时
注册时间
2017-12-2
回帖
51
 楼主| 发表于 2018-2-10 12:18:06 | 显示全部楼层
总是会这样子。。。。。。。。。。。。。。。。。。。。
QQ截图20180210121517.png
回复

使用道具 举报

梦石
0
星屑
915
在线时间
107 小时
注册时间
2017-12-2
回帖
51
 楼主| 发表于 2018-2-10 13:20:26 | 显示全部楼层
该怎么办怎么办怎么办。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
回复

使用道具 举报

梦石
1
星屑
14374
在线时间
2109 小时
注册时间
2017-9-28
回帖
607
发表于 2018-2-10 15:25:08 | 显示全部楼层
qonvenience是核心脚本,需要放在气泡框插件插件的上面...........
顺序参考帖子里的范例

点评

建议核心脚本/基础模块等脚本放的越上越好....  发表于 2018-2-10 15:26
VA外站脚本汉化群:226308173   |    部分远古文件备份:https://wwzv.lanzoue.com/b02rac5pc  密码:acgm
回复

使用道具 举报

梦石
0
星屑
915
在线时间
107 小时
注册时间
2017-12-2
回帖
51
 楼主| 发表于 2018-2-10 15:58:30 | 显示全部楼层
Nil2018 发表于 2018-2-10 15:25
qonvenience是核心脚本,需要放在气泡框插件插件的上面...........
顺序参考帖子里的范例 ...

放了。。没用。。。。。。。。。。。。。。。

点评

你放在下面了,不是"上面"  发表于 2018-2-10 17:27
回复

使用道具 举报

梦石
0
星屑
915
在线时间
107 小时
注册时间
2017-12-2
回帖
51
 楼主| 发表于 2018-2-10 17:41:59 | 显示全部楼层
Nil2018 发表于 2018-2-10 15:25
qonvenience是核心脚本,需要放在气泡框插件插件的上面...........
顺序参考帖子里的范例 ...

我重新放在下面过了,不是一楼的那个顺序【那是之前的】
可还是没有用。。。。
回复

使用道具 举报

梦石
0
星屑
915
在线时间
107 小时
注册时间
2017-12-2
回帖
51
 楼主| 发表于 2018-2-10 21:38:56 | 显示全部楼层
没有人吗。。。。。。。。。。。。。。。。。。
回复

使用道具 举报

梦石
0
星屑
915
在线时间
107 小时
注册时间
2017-12-2
回帖
51
 楼主| 发表于 2018-2-11 12:14:26 | 显示全部楼层
大家新年快乐。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
回复

使用道具 举报

梦石
0
星屑
915
在线时间
107 小时
注册时间
2017-12-2
回帖
51
 楼主| 发表于 2018-2-13 17:18:01 | 显示全部楼层
没人能回答了吗。。。。。。。。。。。。。。。。。。。。。。。
回复

使用道具 举报

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

本版积分规则

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

在本版发帖返回顶部