# functions:
# auto load event list from the txt file with same name.

class Game_Event < Game_Character
  
  alias _auto_load_setup_page_settings setup_page_settings
  def setup_page_settings
    _auto_load_setup_page_settings    
    if @list[0].code == 355 && @list[0].parameters[0] =~ /AUTO:(.+)/
      auto_load(@event.name, $1.strip)
    elsif @auto_load_keys
      auto_load *@auto_load_keys
    end
  end

  def auto_load(name, key)
    @auto_load_keys = [name, key]
    @list.replace Auto_Event.load(name).list(key)
  end

  def name
    @event.name
  end
  
  def auto_reload
    @page = nil
    refresh
  end
end

module Auto_Event
  module_function

  Event_List = {}  

  def reload # only after .md file changes
    Event_List.keys.each do |name|
      Event_List[name] = load_list_txt(name)
    end
  end

  def load(name)
    Event_List[name] ||= load_list_txt(name)
    @data = Event_List[name]
    @list = []
    @keys = []
    self
  end

  def load_list_txt(name)
    data, key, value = {}, '', []
    File.open('Events/' + name + '.md', 'r') do |f|
      f.readlines.each do |line|
        # start with # key
        if line =~ /^#+\s*(.+)/
          data[key] = value.join("\n") if key != ''
          key, value = $1, []
          next
        else
          value << line.strip
          next
        end
      end
      # last key
      data[key] = value.join("\n") if key != ''
    end
    data
  end

  def list(key)
    @keys << key
    event_keys = []
    while @keys.size != event_keys.size
      @keys.uniq!
      @keys.each do |key|
        next if event_keys.include?(key)
        event_keys << key
        next if !@data[key]
        add(118, 0, [key])
        set_text(@data[key])
        add(115, 0, [])
      end
    end
    add(0, 0, [])
  end

  def set_text(text)
    msg_tag, script_tag, choice_tag, table_tag = *[false] * 4
    choices = []
    choice_ignore = []
    table_rows = []
    text.split("\n").each do |line|
      # ------------------------------------------------------------
      # 优先判定是否为脚本
      # ------------------------------------------------------------
      if script_tag
        if line =~ /^```/
          script_tag = false
        else
          add(655, 0, [line])
          msg_tag = false
        end
        next
      end
      # ------------------------------------------------------------
      # 判定注释
      # ------------------------------------------------------------
      if line =~ /^>/
        next
      end
      # ------------------------------------------------------------
      # 继续剩下的判定
      # ------------------------------------------------------------
      case line
      # ------------------------------------------------------------
      # ```识别为 脚本
      # ------------------------------------------------------------
      when /^```/
        add(355, 0, '#~ event scripts')
        script_tag = true
      # ------------------------------------------------------------
      # 空行
      # ------------------------------------------------------------
      when /^\s*$/
        if msg_tag
          msg_tag = false
        end
        if choice_tag
          choice_tag = false
          add_choices(choices, choice_ignore)
        end
        if table_tag
          table_tag = false
          add_table(table_rows)
          table_rows.clear
        end
      # ------------------------------------------------------------
      # 数字列表:选择项
      # ------------------------------------------------------------
      when /^\s*\d+\.\s*(.+)/
        text = $1        
        if choice_tag
          choices << text
        else
          choice_tag = true
          choice_ignore = []
          choices = [text]
        end
      when /^-\s+`(.+)`/
        if choice_tag
          if !eval($1)
            choice_ignore << choices.size - 1
          end
        end
      # ------------------------------------------------------------
      # 图片:对话开始,自动名称和头像
      # ------------------------------------------------------------
      when /^!\[(.+)\]\((.+)\)/
        name, fig = $1, $2
        if fig =~ /"(\d+)"/
          num = $1.to_i
          fig = fig.sub(/"\d+"/, '').strip
        else
          num = 0
        end
        msg_tag = true
        add(101, 0, [fig, num, 0, 2])
        add(401, 0, [name])
      # ------------------------------------------------------------
      # 邮件<>:可见指令
      # ------------------------------------------------------------
      when /^<(.+)@(.+)>/ #
        cmd, para = $1, $2
        case cmd
        when 'CommonEvent'
          if para =~ /\d+/
            add(117, 0, [para.to_i])
          else
            id = $data_common_events.find{|e| e && e.name == para}.id
            add(117, 0, [id])
          end
        when 'GetItem'
          add(104, 0, [para.to_i])
        when 'JumpTo'
          add(119, 0, [para])
          @keys << para
        when 'AutoEvent'
          if para == 'reload'
            add(355, 0, ['$game_map.events[@event_id].auto_reload'])
          end
        end
      # ------------------------------------------------------------
      # [sth]: site "description" 不可见指令
      # ------------------------------------------------------------
      when /^\[(.+)\]\s*:\s*(.+)\s+"(.+)"/
        cmd, para1, para2 = $1, $2, $3
        case cmd
        when 'SelfSwitch' # 独立开关
          _v = (para2 == 'ON')? 0 : 1
          add(123, 0, [para1, _v])
        when 'Move', 'Moves' # 移动事件,等待移动结束
          if para1 =~ /\-*\d+/
            id = para1.to_i
          else
            add(355, 0,
              ["s = $game_map.events.select{|id, e| e.name == '#{para1}'}"]
            )
            add(655, 0, ["@list[@index + 1].parameters[0] = s.keys[0]"])
          end
          route = add_moveroute(para2, cmd == 'Move')
          add(205, 0, [id, route])
        when 'PlaySE'
          add(250, 0, [RPG::SE.new(para1, para2.to_i, 100)])
        when 'Dialog'          
          case para1
          when 'change-skin'
            id = Window_Message::Skin[:var]
            add(122, 0, [id, id, 0, 4, para2])
          end
        end
      # ------------------------------------------------------------
      # [label](script) 条件跳转
      # ------------------------------------------------------------
      when /^\[(.+)\]\((.+)\)/
        label, script = $1, $2
        add(111, 0, [12, script])
        add(119, 1, [label])
        add(0, 1, [])
        add(412, 0, [])
        add(118, 0, ['#' + label])
        @keys << label
      # ------------------------------------------------------------
      # [code][paras] 直接执行命令:
      # [201] [0, map, x, y, 0, 0] 切换地图
      # [214] [] 暂时消除事件
      # [213] [-1, 1, true] Balloon
      # ...
      # ------------------------------------------------------------
      when /^\[(\d+)\] (\[.+\])/
        add($1.to_i, 0, eval($2))
      # ------------------------------------------------------------
      # 表格的情况
      # ------------------------------------------------------------
      when /^.+\|/
        ary = line.split('|')
        if table_tag
          table_rows << ary
        else
          if table_rows.empty?
            table_rows << ary
          elsif ['-'] * table_rows[0].size == ary
            table_tag = true
          else
            table_rows.clear
          end
        end
      # ------------------------------------------------------------
      # 其他的情况
      # ------------------------------------------------------------
      else
        # 移除行尾的 
或者
line.sub!(/$/, '') # 转义 `` 中的内容 while line =~ /`(.*?)`/ line.sub! /`.*?`/, eval($1).to_s end # 视为普通的对话 if msg_tag add(401, 0, [line]) else msg_tag = true add(101, 0, ['', 0, 1, 2]) add(401, 0, [line]) end end end # 如果以选择项结尾 add_choices(choices, choice_ignore) if choice_tag add_table(table_rows) if table_tag end def add(*parameters) @list << RPG::EventCommand.new(*parameters) end def add_choices(choices, choice_ignore) @keys.concat(choices) choice_ignore.each do |i| choices[i] = nil end choices.compact! add(102, 0, [choices, 5]) choices.each_index do |i| add(402, 0, [i, choices[i]]) add(119, 1, [choices[i]]) add(0, 1, []) end add(403, 0, []) add(0, 1, []) add(404, 0, []) end def add_table(rows) case rows[0][0] when 'Shop' add(302, 0, [-1, 0, 0, 0, rows[0][1] =~ /^P/]) rows.each do |paras| paras[2] = (paras[3] == '-') ? 0 : 1 add(605, 0, paras.map{|x| x.to_i}) end end end def add_moveroute(string, wait = false) route = RPG::MoveRoute.new route.repeat = false route.skippable = true route.wait = wait route.list.clear list = [] string.split(' ').each do |c| case c # move when /w(\d+)/ then list.concat([4, []] * $1.to_i) # move up when /a(\d+)/ then list.concat([2, []] * $1.to_i) # move left when /s(\d+)/ then list.concat([1, []] * $1.to_i) # move down when /d(\d+)/ then list.concat([3, []] * $1.to_i) # move right when /f(\d+)/ then list.concat([12, []] * $1.to_i) # move forward when /b(\d+)/ then list.concat([13, []] * $1.to_i) # move backward when /j(.+)/ then list << [14, $1.split('.').map{|i| i.to_i}] # jump when /J(.+)/ then list << [45, ["moveto #{$1.sub('.', ',')}"]] # move to # turn when 'W' then list << [19, []] # turn up when 'A' then list << [17, []] # turn left when 'S' then list << [16, []] # turn down when 'D' then list << [18, []] # turn right when 'L' then list << [21, []] # turn left 90 when 'R' then list << [20, []] # turn right 90 when 'B' then list << [22, []] # turn 180 when 'FIX' then list << [35, []] # fix direction on when 'fix' then list << [36, []] # fix direction off # move setting when 'PASS' then list << [37, []] # pass through on when 'pass' then list << [38, []] # pass through off when /v(\d+)/ then list << [29, [$1.to_i]] # change speed when /V(\d+)/ then list << [30, [$1.to_i]] # change frequency when 'STEP' then list << [33, []] # step animation on when 'step' then list << [33, []] # step animation off # opacity when 'T' then list << [39, []] # transparent on when 't' then list << [40, []] # transparent off when /o(\d+)/ then list << [42, [$1.to_i]] # opacity # other when /W(\d+)/ then list << [15, [$1.to_i]] # wait when /X(\d+)/ then list << [27, [$1.to_i]] # switch on when /x(\d+)/ then list << [28, [$1.to_i]] # switch off end end list << [0, []] list.each do |code, paras| route.list << RPG::MoveCommand.new(code, paras) end route end end