=begin
▼ 选项拓展 ver. 3.4
仅用于 RPG Maker VXAce
制作 : 木星ペンギン
URL : [url]http://woodpenguin.blog.fc2.com/[/url]
------------------------------------------------------------------------------
概要
添加功能:
□ 合并两个连续选项为一个大选项。
□ 选项显示条件功能,不符合显示条件的选项会被隐藏。
□ 设定选项和指针的初始位置
当前指针的位置可以赋值于变量。
□ 临时更改选项窗口的位置。
□ 设定选项条件,不符合条件时,选项变成半透明且不可被选择。
□ 各个选项都可以有相应的帮助信息。
------------------------------------------------------------------------------
使用方法
□ 当两个选项连续排列时,它们会被合并为一个选项。
? 合并后选项的「取消的时候」为最后一个选项的设定。
□ 如果在选项中填入 if(条件) 、且不满足条件时,该选项会被隐藏。
?条件用 eval 进行判断。(详细参考【内建功能】)
?s 代表开关、v 代表变量。
例子:
if(s[1]&&s[2])
if(v[1]==1)
?如果「取消的时候」的选项因为不符合显示条件而被隐藏,则用“无效”作为代替。
□ 在注释中填入以下字符串,指定某变量的值为指针的初始位置。
记忆指针(n)
n : 指针初始位置的变量
?每当选项的指针位置改变时,选项位置的数字会被存储于变量中。
□ 在注释中填入以下字符串,暂时改变选项的显示位置。
选项位置(x, y[, row])
x : 选项窗口的x坐标。
y : 选项窗口的y坐标。
row : 选项最大行数。
未设定时,会显示全部的选项。
□ 在注释中填入以下字符串,使选项显示在对话框的背后。
请在[显示文字]后面使用。
选项位置(对话框后)
□ 在注释中填入以下字符串,则隐藏选项窗口的背景。
背景OFF
□ 在选项中填入 en(条件) 、当不符合条件时,选项会变半透明。
?条件用 eval 进行判断。(详细参考【内建功能】)
?s[n] 代表条件是开启n号开关、v[n] 代表n号变量。
例子:
en(s[1]&&s[2])
en(v[1]==1)
?如果「取消的时候」的选项因为不符合显示条件而变半透明,则会播放蜂鸣声。
□ 各选项之下的注释中填入以下字符串,当移动到各选项中时,会显示选项的帮助文字。
选项帮助
(内容)
例如:
选项帮助
可以住宿。
□ 请在以下网址中查看详细介绍。
[url]http://woodpenguin.web.fc2.com/rgss3/choice_ex.html[/url]
=end
module WdTk
module ChoiceEX
#//////////////////////////////////////////////////////////////////////////////
#
# 设定部分
#
#//////////////////////////////////////////////////////////////////////////////
#--------------------------------------------------------------------------
# ● 选项最大行数
# 如果选项数小于这个数字。
# 则选项最大数与选项数相同。
#--------------------------------------------------------------------------
RowMax = 4
#--------------------------------------------------------------------------
# ● 读取选项帮助的开头文字
#--------------------------------------------------------------------------
Help = "选项帮助"
end
#//////////////////////////////////////////////////////////////////////////////
#
# 以下部分、没有修改的必要
#
#//////////////////////////////////////////////////////////////////////////////
@material ||= []
@material << :ChoiceEX
def self.include?(sym)
@material.include?(sym)
end
end
#==============================================================================
# ■ Game_Message
#==============================================================================
class Game_Message
#--------------------------------------------------------------------------
# ● 公開インスタンス変数
#--------------------------------------------------------------------------
attr_accessor :choice_x # 選択肢ウィンドウの表示 X 座標
attr_accessor :choice_y # 選択肢ウィンドウの表示 Y 座標
attr_accessor :choice_row_max # 選択肢ウィンドウの表示行数
attr_accessor :choice_help # 選択肢のヘルプ
attr_accessor :choice_var_id # 選択肢のカーソル位置を入れる変数ID
attr_accessor :choice_background # 選択肢ウィンドウ背景の表示状態
attr_accessor :under_choice # 選択肢をメッセージの下に表示
#--------------------------------------------------------------------------
# ○ クリア
#--------------------------------------------------------------------------
alias _wdtk_choice_clear clear
def clear
_wdtk_choice_clear
@choice_x = @choice_y = nil
@choice_row_max = WdTk::ChoiceEX::RowMax
@choice_help = {}
@choice_var_id = 0
@choice_background = 0
@under_choice = false
end
end
#==============================================================================
# ■ Game_Interpreter
#==============================================================================
class Game_Interpreter
#--------------------------------------------------------------------------
# ☆ 選択肢のセットアップ
#--------------------------------------------------------------------------
def setup_choices(params)
add_choices(params, @index)
$game_message.choice_proc = Proc.new {|n| @branch[@indent] = n }
end
#--------------------------------------------------------------------------
# ● 選択肢の追加
#--------------------------------------------------------------------------
def add_choices(params, i, d = 0)
params[0].each_with_index {|s, n| $game_message.choices[n + d] = s }
$game_message.choice_cancel_type = params[1] + d if params[1] > 0
indent = @list[i].indent
loop do
i += 1
if @list[i].indent == indent
case @list[i].code
when 402 # [**] の場合
get_help_texts(@list[i].parameters[0] + d, i + 1)
when 404 # 分岐終了
break
end
end
end
i += 1
add_choices(@list[i].parameters, i, d + 5) if @list[i].code == 102
end
#--------------------------------------------------------------------------
# ● ヘルプ用テキストの取得
#--------------------------------------------------------------------------
def get_help_texts(b, i)
if @list[i].code == 108 && @list[i].parameters[0] == WdTk::ChoiceEX::Help
$game_message.choice_help[b] = []
while @list[i + 1].code == 408
i += 1
$game_message.choice_help[b] << @list[i].parameters[0]
end
end
end
#--------------------------------------------------------------------------
# ? 注釈
#--------------------------------------------------------------------------
alias _wdtk_choice_command_108 command_108
def command_108
_wdtk_choice_command_108
@comments.each do |comment|
case comment
when /选项位置\((\d+),\s*(\d+),?\s*(\d*)\)/
$game_message.choice_x = $1.to_i
$game_message.choice_y = $2.to_i
$game_message.choice_row_max = ($3.empty? ? 99 : $3.to_i)
when "选项位置(对话框后)"
$game_message.under_choice = true
$game_message.choice_background = 1
when /记忆指针\((\d+)\)/
$game_message.choice_var_id = $1.to_i
when /背景(ON|OFF)/
$game_message.choice_background = ($1 == "ON" ? 0 : 1)
end
end
end
#--------------------------------------------------------------------------
# ☆ 分岐終了の場合
#--------------------------------------------------------------------------
def command_404
if next_event_code == 102
@branch[@indent] -= 5 if @branch.include?(@indent)
@index += 1
command_skip
end
end
end
#==============================================================================
# ■ Window_ChoiceList
#==============================================================================
class Window_ChoiceList
#--------------------------------------------------------------------------
# ☆ 入力処理の開始
#--------------------------------------------------------------------------
def start
return unless close?
clear_command_list
make_command_list
if @list.empty?
$game_message.choice_proc.call(-1)
return
end
update_placement
refresh
select(0)
if $game_message.choice_var_id > 0
select_ext($game_variables[$game_message.choice_var_id])
end
open
activate
end
#--------------------------------------------------------------------------
# ☆ ウィンドウ位置の更新
#--------------------------------------------------------------------------
def update_placement
self.width = [max_choice_width + 12, 96].max + padding * 2
self.width = [width, Graphics.width].min
n = [@list.size, $game_message.choice_row_max].min
self.height = fitting_height(n)
self.x = Graphics.width - width
if @message_window.y >= Graphics.height / 2
self.y = @message_window.y - height
else
self.y = @message_window.y + @message_window.height
end
self.x = $game_message.choice_x if $game_message.choice_x
self.y = $game_message.choice_y if $game_message.choice_y
self.z = $game_message.under_choice ? 210 : 100
end
#--------------------------------------------------------------------------
# ☆ 選択肢の最大幅を取得
#--------------------------------------------------------------------------
def max_choice_width
@list.collect {|com| text_size(com[:name]).width }.max || 0
end
#--------------------------------------------------------------------------
# ☆ コマンドリストの作成
#--------------------------------------------------------------------------
def make_command_list
$game_message.choices.each_with_index do |choice, i|
next unless choice
str = choice.dup
next if str.slice!(/\s*if\(([^\)]+)\)/i) && !choice_eval($1)
enable = !str.slice!(/\s*en\(([^\)]+)\)/i) || choice_eval($1)
add_command(str, :choice, enable, i)
end
end
#--------------------------------------------------------------------------
# ○ 項目の描画
#--------------------------------------------------------------------------
alias _wdtk_choice_draw_item draw_item
def draw_item(index)
@choice_enabled = command_enabled?(index)
_wdtk_choice_draw_item(index)
end
#--------------------------------------------------------------------------
# ● テキスト描画色の変更
#--------------------------------------------------------------------------
def change_color(color, enabled = true)
super(color, enabled && @choice_enabled)
end
#--------------------------------------------------------------------------
# ☆ 決定ハンドラの呼び出し
#--------------------------------------------------------------------------
def call_ok_handler
$game_message.choice_proc.call(current_ext)
close
end
#--------------------------------------------------------------------------
# ● キャンセルボタンが押されたときの処理
#--------------------------------------------------------------------------
def process_cancel
return super if $game_message.choice_cancel_type % 5 == 0
index = @list.index {|c| c[:ext] == $game_message.choice_cancel_type - 1 }
return unless index
return super if command_enabled?(index)
Sound.play_buzzer
end
#--------------------------------------------------------------------------
# ● ウィンドウを閉じる
#--------------------------------------------------------------------------
def close
@message_window.on_show_fast unless $game_message.choice_help.empty?
super
end
#--------------------------------------------------------------------------
# ● ヘルプウィンドウ更新メソッドの呼び出し
#--------------------------------------------------------------------------
def call_update_help
update_help if active && !$game_message.choice_help.empty?
end
#--------------------------------------------------------------------------
# ● ヘルプウィンドウの更新
#--------------------------------------------------------------------------
def update_help
@message_window.force_clear
if $game_message.choice_help.include?(current_ext)
$game_message.texts.replace($game_message.choice_help[current_ext])
else
$game_message.texts.clear
end
end
#--------------------------------------------------------------------------
# ● 分岐用
#--------------------------------------------------------------------------
def choice_eval(formula)
s, v = $game_switches, $game_variables
begin
Kernel.eval(formula)
rescue
msgbox "以下条件判断发生错误。\n\n", formula
true
end
end
#--------------------------------------------------------------------------
# ● フレーム更新
#--------------------------------------------------------------------------
def update
last_index = @index
super
if last_index != @index && $game_message.choice_var_id > 0
$game_variables[$game_message.choice_var_id] = current_ext
end
end
end
#==============================================================================
# ■ Window_Message
#==============================================================================
class Window_Message
#--------------------------------------------------------------------------
# ○ ウィンドウ背景の更新
#--------------------------------------------------------------------------
alias _wdtk_choice_update_background update_background
def update_background
_wdtk_choice_update_background
@choice_window.opacity = $game_message.choice_background == 0 ? 255 : 0
end
#--------------------------------------------------------------------------
# ○ ウィンドウ位置の更新
#--------------------------------------------------------------------------
alias _wdtk_choice_update_placement update_placement
def update_placement
_wdtk_choice_update_placement
reset_under_choice
end
#--------------------------------------------------------------------------
# ○ 改行文字の処理
#--------------------------------------------------------------------------
alias _wdtk_choice_process_new_line process_new_line
def process_new_line(text, pos)
if $game_message.under_choice
$game_message.choice_y += pos[:height]
ch = self.contents_height + self.y - $game_message.choice_y
$game_message.choice_row_max = ch / line_height
end
_wdtk_choice_process_new_line(text, pos)
end
#--------------------------------------------------------------------------
# ○ 改ページ処理
#--------------------------------------------------------------------------
alias _wdtk_choice_new_page new_page
def new_page(text, pos)
_wdtk_choice_new_page(text, pos)
reset_under_choice
end
#--------------------------------------------------------------------------
# ● 選択肢をメッセージ下に表示する際のリセット
#--------------------------------------------------------------------------
def reset_under_choice
if $game_message.under_choice
$game_message.choice_x = self.x + 16 + new_line_x
$game_message.choice_y = self.y
$game_message.choice_row_max = visible_line_number
end
end
#--------------------------------------------------------------------------
# ● 文章の標示を強制クリア
#--------------------------------------------------------------------------
def force_clear
@gold_window.close
@fiber = nil
close
if WdTk.include?(:MesEff)
@character_sprites.each do |sprite, params|
next if params.empty?
sprite.bitmap.clear
sprite.visible = false
params.clear
end
end
end
#--------------------------------------------------------------------------
# ● 文章を最後まで表示する
#--------------------------------------------------------------------------
def on_show_fast
@show_fast = true
end
end