普通攻防技能的扩展
# @taroxd metadata 1.0
# @require taroxd_core
# @display 普通攻防技能的扩展
# @id attack_skill
# @help 
#
#    使用方法:
#      在装备/技能/角色/职业/敌人上备注 <attackskill x> / <guardskill x>
#      建议与“战斗指令优化”配合使用。

Taroxd::AttackSkill = true

class RPG::BaseItem
  note_i :attack_skill, false
  note_i :guard_skill,  false
end

class Game_BattlerBase

  def_chain :attack_skill_id do |old|
    note_objects { |item| return item.attack_skill if item.attack_skill }
    old.call
  end

  def_chain :guard_skill_id do |old|
    note_objects { |item| return item.guard_skill if item.guard_skill }
    old.call
  end
end
Astar 寻路
# @taroxd metadata 1.0
# @id astar
# @display Astar 寻路
# @help AStar Core v1.01 by 禾西 on 2012.01.02
module Taroxd end

class Taroxd::AStar

  def self.path(character, tx, ty)
    new(character, tx, ty).do_search
  end

  def self.path_to_player(character)
    path(character, $game_player.x, $game_player.y)
  end

  def initialize(character, tx, ty)
    @map_width  = $game_map.width
    @map_height = $game_map.height
    @g_data = Table.new(@map_width, @map_height)
    @f_data = Table.new(@map_width, @map_height)
    @p_data = Table.new(@map_width, @map_height)
    @character = character
    @ox = character.x
    @oy = character.y
    @tx = tx
    @ty = ty
    @open_list = []
    @g = 0
    @search_done = false
  end

  def do_search
    x = @ox
    y = @oy
    @g_data[x, y] = 2
    @f_data[x, y] = 1
    @open_list << [x, y]
    t = 0
    begin
      t += 1
      point = @open_list.shift
      return [] if point.nil?
      check_4dir(point[0], point[1])
    end until @search_done
    if @g_data[@tx, @ty] == 1
      @tx = point[0]
      @ty = point[1]
    end
    make_path
    @path
  end

  private

  # 检查四方向
  def check_4dir(x, y)
    @g = @g_data[x, y] + 1
    mark_point(x, y - 1, 8)
    mark_point(x, y + 1, 2)
    mark_point(x - 1, y, 4)
    mark_point(x + 1, y, 6)
  end

  # 检查单点
  def mark_point(x, y, dir)
    return if over_map?(x, y)
    return if @g_data[x, y] > 1
    if check_passage(x, y, dir)
      @g_data[x, y] = @g
      @f_data[x, y] = f = _f(x, y)
      point = @open_list[0]
      if point.nil? || f > @f_data[point[0], point[1]]
        @open_list.push [x, y]
      else
        @open_list.unshift [x, y]
      end
    else
      @g_data[x, y] = 1
      @f_data[x, y] = _f(x, y)
    end
    @search_done = true if x == @tx && y == @ty
  end

  def make_path
    x = @tx
    y = @ty
    @path = []
    while x != @ox || y != @oy
      @g = @g_data[x, y]
      @best_f = 0
      dir = 0
      dir = make_step(x, y - 1, 2) || dir
      dir = make_step(x, y + 1, 8) || dir
      dir = make_step(x - 1, y, 6) || dir
      dir = make_step(x + 1, y, 4) || dir
      @path.unshift(dir)
      case dir
      when 2 then y -= 1
      when 8 then y += 1
      when 6 then x -= 1
      when 4 then x += 1
      end
      @p_data[x, y] = 1
    end
  end

  # 生成单步
  def make_step(x, y, dir)
    return if @g_data[x, y].nil? || @p_data[x, y] == 1
    if @g - @g_data[x, y] == 1 || @g == 1
      f = @f_data[x, y]
      if f > 0 && (@best_f == 0 || f < @best_f)
        @best_f = f
        dir
      end
    end
  end
  # 检查地图通行度
  def check_passage(x, y, dir)
    case dir
    when 2 then y -= 1
    when 8 then y += 1
    when 4 then x += 1
    when 6 then x -= 1
    end
    @character.passable?(x, y, dir)
  end

  # 检查地图是否越界
  def over_map?(x, y)
    x | y | (@map_width - x - 1) | (@map_height - y - 1) < 0
  end

  # f 值算法
  def _f(x, y)
    (x - @tx).abs + (y - @ty).abs + @g
  end
end
I18n
//=============================================================================
// i18n.js
//=============================================================================

/*:
 * @target MZ
 * @plugindesc Module for i18n.
 * @author taroxd
 *
 * @param Default Locale
 * @desc The language used when the language detected is not supported.
 * @default en-US
 *
 * @param Resource Folder
 * @desc The folder where resource files are put in.
 * @default data/i18n
 *
 * @help
 *
 * Prefix any string in the MV/MZ editor with "__ " to enable i18n for it.
 *
 * Plugin Command:
 *   i18n en-US      # set language to en-US
 *
 * @command i18n
 * @text Set language
 * @desc Set the gameplay language
 *
 * @arg language
 * @type string
 * @text language
 * @desc The language code (e.g. en-US)
 */

window.i18n = function() {

    var parameters = PluginManager.parameters('i18n');
    var defaultLocale = parameters['Default Locale'];
    var supportedLocale = parameters['Supported Locale'];
    var resourceFolder = parameters['Resource Folder'];

    function i18n(string) {
        return (i18n[i18n.language] || {})[string] || string;
    }

    Object.defineProperty(i18n, 'language', {
        get: function() { return i18n._language; },
        set: function(lang) {
            if (lang == null) lang = navigator.language;
            lang = lang.substr(0, 3).toLowerCase() + lang.substr(3).toUpperCase();
            loadI18nResources(lang,
                function() { i18n._language = lang; },
                function() { i18n._language = defaultLocale; }
            );
        }
    });

    function loadI18nResources(language, onload, onerror) {
        if (i18n[language]) return onload();
        var xhr = new XMLHttpRequest();
        var url = resourceFolder + '/' + language + '.json';
        xhr.open('GET', url);
        xhr.overrideMimeType('application/json');
        xhr.onload = function() {
            if (xhr.status < 400) {
                i18n[language] = JSON.parse(xhr.responseText);
                onload();
            }
        };
        xhr.onerror = onerror;
        xhr.send();
    };

    function overrideObj(obj) {
        if (obj == null) return obj;
        Object.keys(obj).forEach(function(key) {
            var value = obj[key];
            switch(typeof value) {
            case 'string':
                if (value.startsWith('__ ')) {
                    value = value.substr(3);
                    Object.defineProperty(obj, key, {
                        get: function() { return i18n(value); },
                        set: function(v) { value = v; },
                        enumerable: true,
                        configurable: true
                    });
                }
                break;
            case 'object':
                overrideObj(value);
                break;
            }
        });
        return obj;
    }

    // override method
    DataManager.loadDataFile = function(name, src) {
        var xhr = new XMLHttpRequest();
        var url = 'data/' + src;
        xhr.open('GET', url);
        xhr.overrideMimeType('application/json');
        xhr.onload = function() {
            if (xhr.status < 400) {
                window[name] = overrideObj(JSON.parse(xhr.responseText));
                DataManager.onLoad(window[name]);
            }
        };
        xhr.onerror = function() {
            DataManager._errorUrl = DataManager._errorUrl || url;
        };
        window[name] = null;
        xhr.send();
    };

    Object.defineProperty(ConfigManager, 'language', {
        get: function() { return this._language; },
        set: function(lang) {
            this._language = lang;
            i18n.language = lang;
        },
        configurable: true
    });

    var makeData = ConfigManager.makeData;
    ConfigManager.makeData = function() {
        var config = makeData.call(this);
        config.language = this.language;
        return config;
    };

    var applyData = ConfigManager.applyData;
    ConfigManager.applyData = function(config) {
        applyData.call(this, config);
        this.language = config.language;
    };

    var pluginCommand = Game_Interpreter.prototype.pluginCommand;
    Game_Interpreter.prototype.pluginCommand = function(command, args) {
        pluginCommand.call(this, command, args);
        if (command === 'i18n') {
            ConfigManager.language = args[0];
            ConfigManager.save();
        }
    };

    return i18n;
}();