选择地图上的点
# @taroxd metadata 1.0
# @display 选择地图上的点
# @require taroxd_core
# @require point
# @require rgss_bugfix
# @id map_select
# @help 
#    开始选择,并将光标指定在 x, y 处。注意 x, y 不可以在地图之外。
#    若不指定参数,默认 x, y 为玩家所在的位置。
#    一直等待,直到玩家选择或取消。
#    返回 Taroxd::Point 的实例或 nil(取消)
#
#    可以选择的区域默认为可以通行的区域。该设置可在下方修改。

module Taroxd::MapSelect

  # 颜色设置
  OPACITY = 150
  NG_COLOR = Color.new(255, 0, 0, OPACITY)
  OK_COLOR = Color.new(0, 0, 255, OPACITY)

  class << self

    attr_reader :point
    attr_reader :selecting

    def x
      @point.x
    end

    def y
      @point.y
    end

    # 是否允许选择点 (x, y)(该方法可以自定义)
    def can_select?(x, y)
      $game_player.passable?(x, y, 10 - $game_player.direction)
    end

    def start(x, y)
      @point = Taroxd::Point[x, y]
      @selecting = true
    end

    def select
      if can_select?(*@point)
        Sound.play_ok
        @selecting = false
      else
        Sound.play_buzzer
      end
    end

    def cancel
      @point = nil
      @selecting = false
    end

    def update
      move_right if Input.repeat?(:RIGHT)
      move_left  if Input.repeat?(:LEFT)
      move_down  if Input.repeat?(:DOWN)
      move_up    if Input.repeat?(:UP)
      select     if Input.trigger?(:C)
      cancel     if Input.trigger?(:B)
    end

    def move_right
      return if screen_x > Graphics.width - 48
      @point.x += 1
      Sound.play_cursor
    end

    def move_left
      return if screen_x < 16
      @point.x -= 1
      Sound.play_cursor
    end

    def move_up
      return if screen_y < 16
      @point.y -= 1
      Sound.play_cursor
    end

    def move_down
      return if screen_y > Graphics.height - 48
      @point.y += 1
      Sound.play_cursor
    end

    def screen_x
      @point.screen_x - 16
    end

    def screen_y
      @point.screen_y - 32
    end
  end

  class Cursor < Sprite
    include Taroxd::DisposeBitmap

    # 光标的位图缓存。该方法可以自定义。
    def self.bitmap
      return @bitmap if @bitmap && !@bitmap.disposed?
      @bitmap = Bitmap.new(32, 32)
      skin = Cache.system('Window')
      @bitmap.stretch_blt(@bitmap.rect, skin, Rect.new(64, 0, 64, 64))
      @bitmap
    end

    def initialize(_)
      super
      self.bitmap = self.class.bitmap
      self.z = 205
    end

    def update
      self.visible = Taroxd::MapSelect.selecting
      return unless visible
      self.x = Taroxd::MapSelect.screen_x
      self.y = Taroxd::MapSelect.screen_y
    end
  end

  class Status < Plane
    include Taroxd::DisposeBitmap
    include Taroxd::BugFix::PlaneVisible

    def initialize(_)
      super
      self.z = 200
    end

    def update
      was_visible = visible
      self.visible = Taroxd::MapSelect.selecting
      return unless visible
      refresh unless was_visible
      self.ox = $game_map.display_x * 32
      self.oy = $game_map.display_y * 32
    end

    def refresh
      bitmap.dispose if bitmap
      self.bitmap = Bitmap.new($game_map.width * 32, $game_map.height * 32)
      $game_map.width.times do |x|
        $game_map.height.times do |y|
          draw_point(x, y)
        end
      end
    end

    def draw_point(x, y)
      color = Taroxd::MapSelect.can_select?(x, y) ? OK_COLOR : NG_COLOR
      bitmap.fill_rect(x * 32, y * 32, 32, 32, color)
    end
  end

  # F12 guard
  DataManager.singleton_def_before(:init, method(:cancel))
end

class Game_Interpreter

  MapSelect = Taroxd::MapSelect

  def select_point(x = $game_player.x, y = $game_player.y)
    MapSelect.start(x, y)
    while MapSelect.selecting
      MapSelect.update
      Fiber.yield
    end
    MapSelect.point
  end
end

class Spriteset_Map
  use_sprite(Taroxd::MapSelect::Cursor) { @viewport2 }
  use_sprite(Taroxd::MapSelect::Status) { @viewport2 }
end
地图显血
# @taroxd metadata 1.0
# @id map_hp
# @display 地图显血
# @require taroxd_core
# @require roll_gauge
# @help 在地图上显示一个简易的血条。
class Sprite_MapHP < Sprite

  Taroxd::MapHP = self

  include Taroxd::DisposeBitmap
  include Taroxd::RollGauge

  # 颜色
  HP_COLOR1 = Color.new(223, 127, 63)
  HP_COLOR2 = Color.new(239, 191, 63)
  BACK_COLOR = Color.new(31, 31, 63)

  # 大小
  WIDTH = 124
  HEIGHT = 100

  def initialize(_)
    super
    self.z = 170
    self.bitmap = Bitmap.new(WIDTH, HEIGHT)
    roll_all_gauge
  end

  def roll_all_gauge
    bitmap.clear
    $game_party.each_with_index do |actor, i|
      rate = gauge_transitions[actor][:hp].value.fdiv(actor.mhp)
      fill_w = (width * rate).to_i
      gauge_y = i * 16 + 12
      bitmap.fill_rect(fill_w, gauge_y, WIDTH - fill_w, 6, BACK_COLOR)
      bitmap.gradient_fill_rect(0, gauge_y, fill_w, 6, HP_COLOR1, HP_COLOR2)
    end
  end
end

Spriteset_Map.use_sprite(Sprite_MapHP) { @viewport2 }
迭代所有事件指令
# @taroxd metadata 1.0
# @id load_and_save_event_command
# @display 迭代所有事件指令
# @help 迭代整个游戏的每个事件指令,并保存所做的修改。
module Taroxd
  module LoadAndSaveEventCommand

    module_function

    # 迭代所有地图事件的事件指令
    def of_map(&block)
      return to_enum(__method__) unless block
      load_data('Data/MapInfos.rvdata2').each_key do |map_id|
        load_and_save(sprintf('Data/Map%03d.rvdata2', map_id)) do |map|
          map.events.each_value do |event|
            event.pages.flat_map(&:list).each(&block)
          end
        end
      end
    end

    # 迭代所有公共事件的事件指令
    def of_common_event(&block)
      return to_enum(__method__) unless block
      load_and_save('Data/CommonEvents.rvdata2') do |events|
        events.each { |event| event.list.each(&block) if event }
      end
    end

    # 迭代所有敌群事件的事件指令
    def of_troop(&block)
      return to_enum(__method__) unless block
      load_and_save('Data/Troops.rvdata2') do |troops|
        troops.each do |troop|
          troop.pages.flat_map(&:list).each(&block) if troop
        end
      end
    end

    # 迭代上述所有事件指令
    def all(&block)
      return to_enum(__method__) unless block
      of_map(&block)
      of_common_event(&block)
      of_troop(&block)
    end

    # 读取文件,执行 block 并保存到原来的文件
    def load_and_save(filename, &block)
      save_data(load_data(filename).tap(&block), filename)
    end
  end
end