Skip to content

Instantly share code, notes, and snippets.

@rutan
Created July 11, 2015 06:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rutan/600bdc0a474221d9eee2 to your computer and use it in GitHub Desktop.
Save rutan/600bdc0a474221d9eee2 to your computer and use it in GitHub Desktop.
メモ欄スクリプト
# encoding: utf-8
#===============================================================================
# ■ メモ欄取得スクリプト for RGSS3
#-------------------------------------------------------------------------------
# Ru/むっくRu
#-------------------------------------------------------------------------------
# メモ欄の指定フォーマット行を取得します
#-------------------------------------------------------------------------------
# 【更新履歴】
#===============================================================================
module Torigoya
module Utils
module CSVLine
# CSVっぽい1行の文字列を分解する
# @param [String] line CSVっぽい文字列
# @return [Array]
def self.parse(line)
columns = []
line = line.split(//)
while line.size > 0
case c = line.shift
when /\s/
next
when '"', "'"
area = line.slice!(0, search_char(line, c))
columns << area.join('')
line.slice!(0, search_char(line, ',') || line.size)
line.delete_at(0)
else
area = line.slice!(0, (search_char(line, ',') || line.size))
columns << "#{c}#{area.join('')}"
line.delete_at(0)
end
end
columns.each { |column| column.strip!; column.gsub!(/\\(?=.)/, '') }
end
# 文字配列の指定文字のindexを取得する(エスケープ文字を考慮する)
# @param [String] chars 文字配列
# @param [String] target_char 検索する文字
# @return [Integer] インデックス値。指定文字がない場合はnil
def self.search_char(chars, target_char)
chars.find_index.with_index do |c, i|
return i if c == target_char && !(i > 0 && chars[i - 1] == '\\')
end
nil
end
end
end
module Note
# メモ欄の命令行の先頭に付ける文字列
# この文字列が先頭にない行は処理対象にしない
PREFIX = '[t]'
# メモ欄取得メソッドを実装するmodule
module Readable
# メモ欄から必要な情報を抽出したBookインスタンスを取得
# @return [Book]
def torigoya_note
@torigoya_note ||= ::Torigoya::Note::Book.parse(self.note)
end
end
# メモ欄解析結果を内包するクラス
class Book
include Enumerable
# メモ欄の内容を解析しBookインスタンスを返す
# @param [String] note メモ欄の中身
# @return [Book] 解析結果
def self.parse(note)
tips = note.split(/\r?\n/).select { |n| n.index(PREFIX) == 0 }.map do |line|
Tip.parse(line.sub(PREFIX, ''))
end
self.new(tips)
end
# 初期化
# @param [Hash] collection
def initialize(tips)
@tips = tips
@collection = {}
tips.each do |tip|
@collection[tip.name] ||= []
@collection[tip.name] << tip
end
end
attr_reader :tips
# 指定名のTip配列の取得
# @param [String] name 取得するTipの名前
# @return [Array]
def [](name)
@collection[name.to_s] || []
end
def each
@collection.each { |k, v| yield(k, v) }
end
end
# メモ欄の項目名に表記ゆれを許容するための辞書
class AliasDictionary
include Enumerable
def initialize
@data = {}
end
# 指定キーのエイリアス先を取得
# @return [String] エイリアス先の名前、未定義の場合はnilを返す
def [](key)
@data[key.to_s]
end
# 指定キーのエイリアスを登録
# @param [String] key エイリアス元の名前
# @param [String] alias_name エイリアス先の名前
# @return [void]
def []=(key, alias_name)
@data[key.to_s] = alias_name.to_s
end
def each
@data.each { |k, v| yield(k, v) }
end
end
# メモ欄の各行ごとの解析済みデータ
class Tip
# エイリアス辞書の取得
# @return [AliasDictionary]
def self.alias_dictionary
@alias_dictionary ||= AliasDictionary.new
end
# note欄の行を元にTipを作成
# @param [String] str noteの行(PREFIXは含まない)
# @return [Tip]
def self.parse(str)
case str
when /\A\s*([^:]+):\s*(.+)\s*\z/
key = $1.to_s
text = $2.to_s
values = Torigoya::Utils::CSVLine.parse(text).map do |n|
case n
when /\A\d+\.\d+\z/; n.to_f
when /\A\d+\z/; n.to_i
else; n
end
end
else
key = str
text = ''
values = []
end
self.new(self.alias_dictionary[key] || key, text, values)
end
# 初期化
# @param [String] name 名前
# @param [String] text データ(文字列)
# @param [Array] values データ(配列)
def initialize(name, text, values = [])
@name = name
@text = text
@values = values
end
attr_reader :name
attr_reader :text
attr_reader :values
end
end
end
# メモ欄を持つクラスにinclude
class RPG::BaseItem
include Torigoya::Note::Readable
end
class RPG::Tileset
include Torigoya::Note::Readable
end
# coding: utf-8
#===============================================================================
#-------------------------------------------------------------------------------
raise 'メモ欄取得スクリプトが見つかりません' unless defined?(Torigoya) && defined?(Torigoya::Note)
begin
# メモ欄のエイリアス設定
Torigoya::Note::Tip.alias_dictionary['ターン消費なし'] = 'quick_skill'
end
module Torigoya
class QuickSkill
# 初期化
def initialize(battler)
@battler = battler
end
# 現在設定中のアクションを保存する
# @note 強制行動イベントを実行した場合に不整合が起きるのを防止するもの
def store_action
@actions = @battler.actions.dup
end
# アクションを強制行動前のものに戻す
def revert_action
@actions.tap { @actions = nil }
end
# ターン消費なしのスキルを発動中か?
def self.playing?
@playing
end
# ターン消費なしのスキルの発動フラグの取得
def self.playing=(n)
@playing = n
end
# アクションを元に戻す
def self.revert_action_all_members
[$game_party, $game_troop].each do |party|
party.members.each {|member| member.torigoya_quick_skill.revert_action }
end
end
end
end
module BattleManager
#-----------------------------------------------------------------------------
# ● 行動が未選択のアクターを先頭から探す
#-----------------------------------------------------------------------------
def self.hzm_vxa_quick_skill_can_action_actor_before(daemon)
return false unless $game_party.members.index(daemon)
for @actor_index in 0..$game_party.members.index(daemon)
actor = $game_party.members[@actor_index]
return true if actor.next_command
end
false
end
end
class Game_Battler < Game_BattlerBase
#-----------------------------------------------------------------------------
# ● ターン消費なし行動管理の取得
#-----------------------------------------------------------------------------
def torigoya_quick_skill
@torigoya_quick_skill ||= ::Torigoya::QuickSkill.new(self)
end
#-----------------------------------------------------------------------------
# ● [エイリアス] 行動速度の決定
#-----------------------------------------------------------------------------
alias torigoya_quick_skill_make_speed make_speed
def make_speed
# 空行動は削除する
@actions.reject! { |a| a == nil }
# 元の処理
torigoya_quick_skill_make_speed
# アクションを速度順にソート
@actions.sort! { |a, b| b.speed - a.speed }
end
#-----------------------------------------------------------------------------
# ● 戦闘行動の強制(エイリアス)
#-----------------------------------------------------------------------------
alias hzm_vxa_quick_skill_force_action force_action
def force_action(skill_id, target_index)
self.torigoya_quick_skill.store_action if Torigoya::QuickSkill.playing?
hzm_vxa_quick_skill_force_action(skill_id, target_index)
end
#-----------------------------------------------------------------------------
# ● 戦闘行動の復元
#-----------------------------------------------------------------------------
def torigoya_quick_skill_revert_action
if actions = self.torigoya_quick_skill.revert_action
@actions = actions
end
end
end
class Game_Actor < Game_Battler
#-----------------------------------------------------------------------------
# ● アクションを先頭に入れ替え(独自)
#-----------------------------------------------------------------------------
def hzm_vxa_quick_skill_swap_action
@actions[0], @actions[@action_input_index] = @actions[@action_input_index], @actions[0]
end
end
class Game_Action
#-----------------------------------------------------------------------------
# ● 行動速度の計算(エイリアス)
#-----------------------------------------------------------------------------
alias hzm_vxa_quick_skill_speed speed
def speed
# ターン消費無し行動の行動速度を最速化
item.speed = 999999 if item and item.torigoya_note['quick_skill'].first
# 元の処理
hzm_vxa_quick_skill_speed
end
end
class Scene_Battle < Scene_Base
#-----------------------------------------------------------------------------
# ● [エイリアス] 情報表示ビューポートの更新
#-----------------------------------------------------------------------------
alias torigoya_quick_skill_update_info_viewport update_info_viewport
def update_info_viewport
torigoya_quick_skill_update_info_viewport
# ターン消費なしスキル発動中はステータスの表示位置を行動中と同じに
move_info_viewport(64) if Torigoya::QuickSkill.playing?
end
#-----------------------------------------------------------------------------
# ● [エイリアス] アクターコマンド選択の開始
#-----------------------------------------------------------------------------
alias torigoya_quick_skill_start_actor_command_selection start_actor_command_selection
def start_actor_command_selection
torigoya_quick_skill_start_actor_command_selection
# パーティメンバーが増減したときにaction未生成のアクターが混ざりこむので対応
BattleManager.actor.make_actions unless BattleManager.actor.input
end
#-----------------------------------------------------------------------------
# ● [エイリアス] 次のコマンド入力へ
#-----------------------------------------------------------------------------
alias torigoya_quick_skill_next_command next_command
def next_command
if @torigoya_quick_skill_selected_item && @torigoya_quick_skill_selected_item.torigoya_note['quick_skill'].size > 0
torigoya_quick_skill_run
# 行動を再選択
if BattleManager.hzm_vxa_quick_skill_can_action_actor_before(@subject) || @subject.inputable?
@subject.prior_command
return start_actor_command_selection
end
end
torigoya_quick_skill_next_command
end
#-----------------------------------------------------------------------------
# ● [エイリアス] スキル[決定]
#-----------------------------------------------------------------------------
alias torigoya_quick_skill_on_skill_ok on_skill_ok
def on_skill_ok
@torigoya_quick_skill_selected_item = @skill_window.item
torigoya_quick_skill_on_skill_ok
end
#-----------------------------------------------------------------------------
# ● [エイリアス] スキル[キャンセル]
#-----------------------------------------------------------------------------
alias torigoya_quick_skill_on_skill_cancel on_skill_cancel
def on_skill_cancel
@torigoya_quick_skill_selected_item = nil
torigoya_quick_skill_on_skill_cancel
end
#-----------------------------------------------------------------------------
# ● [エイリアス] アイテム[決定]
#-----------------------------------------------------------------------------
alias torigoya_quick_skill_on_item_ok on_item_ok
def on_item_ok
@torigoya_quick_skill_selected_item = @item_window.item
torigoya_quick_skill_on_item_ok
end
#-----------------------------------------------------------------------------
# ● [エイリアス] アイテム[キャンセル]
#-----------------------------------------------------------------------------
alias torigoya_quick_skill_on_item_cancel on_item_cancel
def on_item_cancel
@torigoya_quick_skill_selected_item = nil
torigoya_quick_skill_on_item_cancel
end
#-----------------------------------------------------------------------------
# ● ターン消費無し行動の実行
#-----------------------------------------------------------------------------
def torigoya_quick_skill_run
@torigoya_quick_skill_selected_item = nil
Torigoya::QuickSkill.playing = true
@actor_command_window.close if @actor_command_window
@subject = BattleManager.actor
@subject.hzm_vxa_quick_skill_swap_action # 選んだ行動を先頭に引きずり出す
execute_action
process_event
@subject.hzm_vxa_quick_skill_swap_action # 行動を元の位置に
Torigoya::QuickSkill.playing = false
refresh_status
@actor_command_window.open if @actor_command_window
@status_window.open if @status_window
end
end
# encoding: utf-8
#===============================================================================
# ■ calc for RGSS3
#-------------------------------------------------------------------------------
# Ru/むっくRu
#-------------------------------------------------------------------------------
#
#-------------------------------------------------------------------------------
# 【更新履歴】
#===============================================================================
raise 'メモ欄取得スクリプトが見つかりません' unless defined?(Torigoya) && defined?(Torigoya::Note)
begin
# メモ欄のエイリアス設定
Torigoya::Note::Tip.alias_dictionary['変数代入'] = 'set_var'
Torigoya::Note::Tip.alias_dictionary['変数加算'] = 'add_var'
Torigoya::Note::Tip.alias_dictionary['変数減算'] = 'sub_var'
Torigoya::Note::Tip.alias_dictionary['変数乗算'] = 'mul_var'
Torigoya::Note::Tip.alias_dictionary['変数除算'] = 'div_var'
end
module Torigoya
module UsableItemCalc
CALC_LIST = {
'set_var' => :'=',
'add_var' => :'+',
'sub_var' => :'-',
'mul_var' => :'*',
'div_var' => :'/',
}
# メモ欄計算の実行
# @param [Game_Battler] battler 行動者
# @param [RPG::ItemBase] item 対象のスキル/アイテム
def self.apply(battler, item)
item.torigoya_note.tips.each do |tip|
next unless CALC_LIST.keys.include?(tip.name)
self.apply_variable(battler, item, CALC_LIST[tip.name], tip.values[0], tip.values[1])
end
end
# メモ欄計算の実行(変数)
# @param [Game_Battler] battler 行動者
# @param [RPG::ItemBase] item 計算する対象のスキル/アイテム
# @param [symbol] method_name 計算に使用するメソッド名
# @param [String] id 変数の番号(計算式可)
# @param [String] value 変数の番号(計算式可)
def self.apply_variable(battler, item, method_name, id, value)
calc_id = self.eval(battler, item, id).to_i
calc_value = self.eval(battler, item, value).to_i
case method_name
when :'='
$game_variables[calc_id] = calc_value
else
$game_variables[calc_id] = $game_variables[calc_id].method(method_name).call(calc_value)
end
end
# 計算の実行
# @param [Game_Battler] a 行動者
# @param [RPG::ItemBase] item 計算する対象のスキル/アイテム
# @param [RPG::ItemBase] command 計算する対象のスキル/アイテム
def self.eval(a, item, command)
Kernel.eval(command.to_s)
end
end
end
class Game_Battler < Game_BattlerBase
#-----------------------------------------------------------------------------
# ● [エイリアス] スキル/アイテムの使用
#-----------------------------------------------------------------------------
alias torigoya_note_usable_item_calc_use_item use_item
def use_item(item)
Torigoya::UsableItemCalc.apply(self, item)
torigoya_note_usable_item_calc_use_item(item)
end
end
# encoding: utf-8
#===============================================================================
# ■ スキル条件 for RGSS3
#-------------------------------------------------------------------------------
# Ru/むっくRu
#-------------------------------------------------------------------------------
#
#-------------------------------------------------------------------------------
# 【更新履歴】
#===============================================================================
raise 'メモ欄取得スクリプトが見つかりません' unless defined?(Torigoya) && defined?(Torigoya::Note)
begin
# メモ欄のエイリアス設定
Torigoya::Note::Tip.alias_dictionary['条件'] = 'condition'
end
module Torigoya
module SkillConditions
# 指定スキルの使用可能確認を実行
# @param [Game_Battler] battler 行動者
# @param [RPG::ItemBase] item 対象のスキル/アイテム
# @return [Boolean]
def self.usable?(battler, item)
item.torigoya_note['condition'].all? do |tip|
usable_item_by_tip?(battler, item, tip)
end
end
# 指定スキルの項目別使用可能確認を実行
# @param [Game_Battler] battler 行動者
# @param [RPG::ItemBase] item 対象のスキル/アイテム
# @param [RPG::ItemBase] tip 確認項目
# @return [Boolean]
def self.usable_item_by_tip?(battler, item, tip)
case tip.values.first
when 'スイッチON', 'switch_on'
switch_id = self.eval(battler, item, tip.values[1])
$game_switches[switch_id.to_i]
when 'スイッチOFF', 'switch_off'
switch_id = self.eval(battler, item, tip.values[1])
!$game_switches[switch_id.to_i]
when '変数', 'variable'
variable_id = self.eval(battler, item, tip.values[1])
self.eval(battler, item, tip.values[2], $game_variables[variable_id.to_i])
when 'パーティ人数', 'party_size'
self.eval(battler, item, tip.values[1], $game_party.members.size)
when 'パーティ存在', 'party_in'
$game_party.members.map(&:actor_id).include?(self.eval(battler, item, tip.values[1]))
when 'パーティ不在', 'party_out'
!$game_party.members.map(&:actor_id).include?(self.eval(battler, item, tip.values[1]))
when '戦闘内上限', 'limit_in_battle'
return true unless $game_party.in_battle
using_count_for(:battle, battler, item)[item.id].to_i < self.eval(battler, item, tip.values[1]).to_i
when 'ターン内上限', 'limit_in_turn'
return true unless $game_party.in_battle
using_count_for(:turn, battler, item)[item.id].to_i < self.eval(battler, item, tip.values[1]).to_i
when 'スクリプト', 'script'
self.eval(battler, item, tip.values[1])
else
true
end
end
# 計算の実行
def self.eval(a, item, command, n = nil)
Kernel.eval(command.to_s)
end
# 戦闘の初期化
def self.reset_battle
@using_count_in_battle ||= {}
@using_count_in_battle.clear
end
# ターンの初期化
def self.reset_turn
@using_count_in_turn ||= {}
@using_count_in_turn.clear
end
# 戦闘/ターン内の使用スキル一覧を取得する
# @param [Symbol] type 戦闘 or ターン(battle or turn)
# @param [Game_Battler] battler 行動者
# @param [RPG::ItemBase] item 対象のスキル/アイテム
# @return [Hash] スキル/アイテムIDをキーとした利用回数を持つハッシュ
def self.using_count_for(type, battler, item)
using_count =
case type
when :battle; @using_count_in_battle
when :turn; @using_count_in_turn
end
case item
when RPG::Item
using_count['party'] ||= {}
when RPG::Skill
using_count[battler.actor? ? "actor_#{battler.actor_id}" : "enemy_#{battler.index}"] ||= {}
end
end
# 指定スキルの使用回数を1増やす
# @param [Game_Battler] battler 行動者
# @param [RPG::ItemBase] item 対象のスキル/アイテム
def self.count_up(battler, item)
return unless $game_party.in_battle
[
using_count_for(:battle, battler, item),
using_count_for(:turn, battler, item),
].each do |using_count|
using_count[item.id] ||= 0
using_count[item.id] += 1
end
end
end
end
class Game_BattlerBase
#-----------------------------------------------------------------------------
# ● [エイリアス] スキル/アイテムの共通使用可能条件チェック
#-----------------------------------------------------------------------------
alias torigoya_skill_condition_usable_item_conditions_met? usable_item_conditions_met?
def usable_item_conditions_met?(item)
torigoya_skill_condition_usable_item_conditions_met?(item) && Torigoya::SkillConditions.usable?(self, item)
end
end
class Game_Battler < Game_BattlerBase
#--------------------------------------------------------------------------
# ● [エイリアス] スキル/アイテムの使用
#--------------------------------------------------------------------------
alias torigoya_skill_condition_use_item use_item
def use_item(item)
Torigoya::SkillConditions.count_up(self, item)
torigoya_skill_condition_use_item(item)
end
end
class Scene_Battle < Scene_Base
#--------------------------------------------------------------------------
# ● [エイリアス] 戦闘開始
#--------------------------------------------------------------------------
alias torigoya_skill_conditions_battle_start battle_start
def battle_start
Torigoya::SkillConditions.reset_battle
Torigoya::SkillConditions.reset_turn
torigoya_skill_conditions_battle_start
end
#--------------------------------------------------------------------------
# ● ターン終了
#--------------------------------------------------------------------------
alias torigoya_skill_conditions_turn_end turn_end
def turn_end
Torigoya::SkillConditions.reset_turn
torigoya_skill_conditions_turn_end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment