1536 lines
62 KiB
Ruby
1536 lines
62 KiB
Ruby
#******************************************************************************
|
||
#
|
||
# * Custom Menu Base
|
||
#
|
||
# --------------------------------------------------------------------------
|
||
# バージョン : 1.0.0
|
||
# 対 応 : RPGツクールVX Ace : RGSS3
|
||
# 制 作 者 : CACAO
|
||
# 配 布 元 : http://cacaosoft.web.fc2.com/
|
||
# --------------------------------------------------------------------------
|
||
# == 概 要 ==
|
||
#
|
||
# : カスタムメニューのベーススクリプトです。
|
||
#
|
||
# --------------------------------------------------------------------------
|
||
# == 注意事項 ==
|
||
#
|
||
# ※ このスクリプトは、なるべく下のほうのに導入してください。
|
||
# ※ カスタムメニュー関連のスクリプトより上に導入してください。
|
||
#
|
||
#
|
||
#******************************************************************************
|
||
|
||
|
||
#==============================================================================
|
||
# ◆ ユーザー設定
|
||
#==============================================================================
|
||
module CAO
|
||
module CM
|
||
#--------------------------------------------------------------------------
|
||
# ◇ メニュー項目の設定
|
||
#--------------------------------------------------------------------------
|
||
COMMAND_ITEMS = {}
|
||
COMMAND_ITEMS[:item] = {
|
||
:name => "アイテム",
|
||
:command => Scene_Item,
|
||
:help => 'アイテムを使用します。'
|
||
}
|
||
COMMAND_ITEMS[:skill] = {
|
||
:name => "スキル",
|
||
:personal => Scene_Skill,
|
||
:help => 'スキルを使用します。'
|
||
}
|
||
COMMAND_ITEMS[:equip] = {
|
||
:name => "装備",
|
||
:personal => Scene_Equip,
|
||
:help => '装備を変更します。'
|
||
}
|
||
COMMAND_ITEMS[:status] = {
|
||
:name => "ステータス",
|
||
:personal => Scene_Status,
|
||
:help => 'ステータスを確認します。'
|
||
}
|
||
COMMAND_ITEMS[:formation] = {
|
||
:name => "並び替え",
|
||
:command => :command_formation,
|
||
:enable => :formation_enabled,
|
||
:help => 'パーティを入れ替えます。'
|
||
}
|
||
COMMAND_ITEMS[:game_end] = {
|
||
:name => "ゲーム終了",
|
||
:command => Scene_End,
|
||
:help => 'ゲームを終了します。'
|
||
}
|
||
|
||
COMMAND_ITEMS[:file] = {
|
||
:name => "ファイル",
|
||
:sub => :sub_file,
|
||
:help => 'ゲームのセーブ・ロードを行います。'
|
||
}
|
||
COMMAND_ITEMS[:save] = {
|
||
:name => "セーブ",
|
||
:command => Scene_Save,
|
||
:enable => "!$game_system.save_disabled",
|
||
:help => 'ゲームをセーブします。'
|
||
}
|
||
COMMAND_ITEMS[:load] = {
|
||
:name => "ロード",
|
||
:command => Scene_Load,
|
||
:enable => "DataManager.save_file_exists?",
|
||
:help => 'ゲームをロードします。'
|
||
}
|
||
COMMAND_ITEMS[:sample] = {
|
||
:name => "オプション",
|
||
:sub => :sub_sample,
|
||
:help => '音量設定・ゲーム終了。'
|
||
}
|
||
COMMAND_ITEMS[:common] = {
|
||
:name => "コモンイベント",
|
||
:command => 'start_common_event(2)',
|
||
:enable => "!$game_switches[3]",
|
||
:help => 'コモンイベントを実行します。'
|
||
}
|
||
COMMAND_ITEMS[:levelup] = {
|
||
:name => "レベルアップ",
|
||
:personal => 'start_common_event(1)',
|
||
:enable => "$game_variables[1] != 2",
|
||
:refresh => [:status],
|
||
:help => 'アクター選択後のコモンイベントサンプル'
|
||
}
|
||
COMMAND_ITEMS[:switch] = {
|
||
:name => [3, "スイッチ ON", "スイッチ OFF"],
|
||
:command => "$game_switches[3] ^= true",
|
||
:refresh => [:command, :text],
|
||
:help => 'スイッチを操作します。'
|
||
}
|
||
COMMAND_ITEMS[:variable] = {
|
||
:name => ['"EV変数 #{$game_variables[1]}"'],
|
||
:command => "$game_variables[1] = ($game_variables[1] + 1) % 3",
|
||
:refresh => [:command, :text],
|
||
:help => 'EV変数を操作します。'
|
||
}
|
||
COMMAND_ITEMS[:medal] = {
|
||
:name => TMMEDAL::COMMAND_MEDAL,
|
||
:command => :command_medal,
|
||
:enable => :medal_enabled,
|
||
:hide => 'TMMEDAL::HIDE_COMMAND && !medal_enabled'
|
||
}
|
||
COMMAND_ITEMS[:audio] = {
|
||
:name => "音量設定",
|
||
:command => HZM_VXA::AudioVol::Scene_VolConfig,
|
||
}
|
||
|
||
#--------------------------------------------------------------------------
|
||
# ◇ 表示項目の設定
|
||
#--------------------------------------------------------------------------
|
||
COMMANDS = {}
|
||
COMMANDS[:main] = # 必須
|
||
[:item, :skill, :equip, :status, :formation, :medal, :file, :sample]
|
||
COMMANDS[:sub_file] = [:save, :load]
|
||
COMMANDS[:sub_sample] = [:audio, :language, :game_end]
|
||
#--------------------------------------------------------------------------
|
||
# ◇ 残りHPで顔グラを変化させる
|
||
#--------------------------------------------------------------------------
|
||
EXPRESSIVE_RATE = []
|
||
#--------------------------------------------------------------------------
|
||
# ◇ 立ち絵のファイル名
|
||
#--------------------------------------------------------------------------
|
||
PORTRAIT_NAME = "MActor%d"
|
||
|
||
#--------------------------------------------------------------------------
|
||
# ◇ 背景画像
|
||
#--------------------------------------------------------------------------
|
||
# 前景画像(最前面に表示されます。)
|
||
FILE_FOREGROUND = nil
|
||
# 背景画像(デフォルトのマップ画像と入れ替えます。)
|
||
FILE_BACKGROUND = nil
|
||
# アニメ画像 ["ファイル名", vx, vy, 最背面?]
|
||
BACKIMAGE = nil
|
||
|
||
#--------------------------------------------------------------------------
|
||
# ◇ システム文字の有無
|
||
#--------------------------------------------------------------------------
|
||
VISIBLE_SYSTEM = true
|
||
#--------------------------------------------------------------------------
|
||
# ◇ 用語設定
|
||
#--------------------------------------------------------------------------
|
||
VOCABS = {}
|
||
VOCABS[:gold] = "所持金"
|
||
VOCABS[:exp] = "経験値"
|
||
VOCABS[:exp_a] = "EXP"
|
||
|
||
end # module CM
|
||
end # module CAO
|
||
|
||
|
||
#/////////////////////////////////////////////////////////////////////////////#
|
||
# #
|
||
# 下記のスクリプトを変更する必要はありません。 #
|
||
# #
|
||
#/////////////////////////////////////////////////////////////////////////////#
|
||
|
||
|
||
class CustomizeError < Exception; end
|
||
|
||
class Game_MenuItem
|
||
#--------------------------------------------------------------------------
|
||
# ●
|
||
#--------------------------------------------------------------------------
|
||
attr_reader :symbol
|
||
attr_reader :sub
|
||
attr_reader :enable
|
||
attr_reader :refresh
|
||
#--------------------------------------------------------------------------
|
||
# ●
|
||
#--------------------------------------------------------------------------
|
||
def initialize(symbol, params = {})
|
||
@symbol = symbol # 項目の識別子
|
||
@name = params[:name] || "" # 項目名
|
||
@help = params[:help] || "" # ヘルプ
|
||
@icon = params[:icon] # アイコン番号
|
||
@scene = params[:scene] # 項目処理 シーン遷移
|
||
@command = params[:command] # 項目処理 コマンド実行
|
||
@personal = params[:personal] # 項目処理 アクター選択
|
||
@sub = params[:sub] # 項目処理 サブコマンド
|
||
case [@scene, @command, @personal, @sub].count {|o| o }
|
||
when 0; raise CustomizeError, "項目処理が設定されていません。"
|
||
when 1 # Do Nothing
|
||
else; raise CustomizeError, "複数の項目処理が設定されています。"
|
||
end
|
||
@enable = params[:enable] || true # 選択の可否
|
||
@hide = params[:hide] || false # 非表示の有無
|
||
@refresh = params[:refresh] || [] # 項目処理後に再描画
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ●
|
||
#--------------------------------------------------------------------------
|
||
def _convert_value(obj)
|
||
if obj.is_a?(Array)
|
||
case obj[0]
|
||
when String
|
||
result = eval(obj[0], ::TOPLEVEL_BINDING)
|
||
return result if obj.size == 1
|
||
return obj[result ? 1 : 2] if result == !!result
|
||
return obj[result + 1]
|
||
when Integer
|
||
if obj.size == 3
|
||
return obj[$game_switches[obj[0]] ? 1 : 2]
|
||
else
|
||
return obj[$game_variables[obj[0]]]
|
||
end
|
||
else
|
||
raise "must not happen"
|
||
end
|
||
else
|
||
return obj
|
||
end
|
||
end
|
||
private :_convert_value
|
||
#--------------------------------------------------------------------------
|
||
# ●
|
||
#--------------------------------------------------------------------------
|
||
def name
|
||
return _convert_value(@name)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ●
|
||
#--------------------------------------------------------------------------
|
||
def help
|
||
return _convert_value(@help)
|
||
end
|
||
alias description help
|
||
#--------------------------------------------------------------------------
|
||
# ●
|
||
#--------------------------------------------------------------------------
|
||
def icon_index
|
||
return _convert_value(@icon)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ●
|
||
#--------------------------------------------------------------------------
|
||
def handler
|
||
return :command_ok if @scene
|
||
return @command if @command && @command.is_a?(Symbol)
|
||
return :command_ok if @command
|
||
return @personal if @personal && @personal.is_a?(Symbol)
|
||
return :command_personal if @personal
|
||
return :command_sub if @sub
|
||
raise "must not happen"
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ●
|
||
#--------------------------------------------------------------------------
|
||
def exec
|
||
#
|
||
# ここでエラーが発生した場合、項目の設定が間違っている可能性があります。
|
||
# 項目処理の設定を確認してください。
|
||
#
|
||
# エラーメッセージを確認の上、設定を修正してください。
|
||
# つづり間違いや文法が間違っている可能性があります。
|
||
#
|
||
if @scene
|
||
case @scene
|
||
when Class
|
||
return SceneManager.call(@scene.untaint)
|
||
when Symbol
|
||
return SceneManager.call(Kernel.const_get(@scene).untaint)
|
||
when String
|
||
return SceneManager.call(eval(@scene, ::TOPLEVEL_BINDING).untaint)
|
||
end
|
||
else
|
||
command = @command || @personal
|
||
case command
|
||
when Class
|
||
return SceneManager.call(command.untaint)
|
||
when String
|
||
return SceneManager.scene.instance_eval(command)
|
||
end
|
||
end
|
||
raise "must not happen"
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ●
|
||
#--------------------------------------------------------------------------
|
||
def hide?
|
||
#
|
||
# ここでエラーが発生した場合、項目の設定が間違っている可能性があります。
|
||
# オプションの :hide の設定を確認してください。
|
||
#
|
||
case @hide
|
||
when true, false
|
||
return @hide
|
||
when String
|
||
return eval(@hide, ::TOPLEVEL_BINDING)
|
||
else
|
||
raise "must not happen"
|
||
end
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ●
|
||
#--------------------------------------------------------------------------
|
||
def personal?
|
||
return @personal && true
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ●
|
||
#--------------------------------------------------------------------------
|
||
def refresh?
|
||
return !@refresh.empty?
|
||
end
|
||
end
|
||
|
||
class Scene_Menu
|
||
#--------------------------------------------------------------------------
|
||
# ○ 開始処理
|
||
#--------------------------------------------------------------------------
|
||
def start
|
||
super
|
||
create_command_window
|
||
create_status_window
|
||
create_option_window
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ○ フレーム更新
|
||
#--------------------------------------------------------------------------
|
||
def update
|
||
super
|
||
update_backimage
|
||
update_command_window
|
||
update_status_window
|
||
update_option_window
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ○ 終了処理
|
||
#--------------------------------------------------------------------------
|
||
def terminate
|
||
super
|
||
dispose_command_window
|
||
dispose_status_window
|
||
dispose_option_window
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ○ 背景の作成
|
||
#--------------------------------------------------------------------------
|
||
def create_background
|
||
create_backimage if CAO::CM::BACKIMAGE && CAO::CM::BACKIMAGE[3]
|
||
if CAO::CM::FILE_BACKGROUND
|
||
@background_sprite = Sprite.new
|
||
@background_sprite.bitmap = Cache.system(CAO::CM::FILE_BACKGROUND)
|
||
else
|
||
super
|
||
end
|
||
create_backimage if CAO::CM::BACKIMAGE && !CAO::CM::BACKIMAGE[3]
|
||
if CAO::CM::FILE_FOREGROUND
|
||
@foreground_sprite = Sprite.new
|
||
@foreground_sprite.z = 1000
|
||
@foreground_sprite.bitmap = Cache.system(CAO::CM::FILE_FOREGROUND)
|
||
end
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ○ 背景の解放
|
||
#--------------------------------------------------------------------------
|
||
def dispose_background
|
||
super
|
||
@backimage_sprite.dispose if @backimage_sprite
|
||
@foreground_sprite.dispose if @foreground_sprite
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ●
|
||
#--------------------------------------------------------------------------
|
||
def create_backimage
|
||
return unless CAO::CM::BACKIMAGE
|
||
@backimage_sprite = Plane.new
|
||
@backimage_sprite.bitmap = Cache.system(CAO::CM::BACKIMAGE[0])
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ●
|
||
#--------------------------------------------------------------------------
|
||
def update_backimage
|
||
return unless @backimage_sprite
|
||
return unless CAO::CM::BACKIMAGE[1] && CAO::CM::BACKIMAGE[2]
|
||
@backimage_sprite.ox -= CAO::CM::BACKIMAGE[1]
|
||
@backimage_sprite.oy -= CAO::CM::BACKIMAGE[2]
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● コマンドウィンドウの作成
|
||
#--------------------------------------------------------------------------
|
||
def create_command_window
|
||
# Do Nothing
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● ステータスウィンドウの作成
|
||
#--------------------------------------------------------------------------
|
||
def create_status_window
|
||
# Do Nothing
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● オプションウィンドウの作成
|
||
#--------------------------------------------------------------------------
|
||
def create_option_window
|
||
# Do Nothing
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● コマンドウィンドウの更新
|
||
#--------------------------------------------------------------------------
|
||
def update_command_window
|
||
# Do Nothing
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● ステータスウィンドウの更新
|
||
#--------------------------------------------------------------------------
|
||
def update_status_window
|
||
# Do Nothing
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● オプションウィンドウの更新
|
||
#--------------------------------------------------------------------------
|
||
def update_option_window
|
||
# Do Nothing
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● コマンドウィンドウの解放
|
||
#--------------------------------------------------------------------------
|
||
def dispose_command_window
|
||
# Do Nothing
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● ステータスウィンドウの解放
|
||
#--------------------------------------------------------------------------
|
||
def dispose_status_window
|
||
# Do Nothing
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● オプションウィンドウの解放
|
||
#--------------------------------------------------------------------------
|
||
def dispose_option_window
|
||
# Do Nothing
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● コマンド [決定]
|
||
#--------------------------------------------------------------------------
|
||
def command_ok
|
||
@command_window.current_exec
|
||
@command_window.activate
|
||
check_common_event
|
||
check_refresh_window(@command_window.current_data)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ○ 個人コマンド [決定]
|
||
#--------------------------------------------------------------------------
|
||
def on_personal_ok
|
||
command_ok
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● コモンイベント予約判定
|
||
# イベントの呼び出しが予約されているならマップ画面へ遷移する。
|
||
#--------------------------------------------------------------------------
|
||
def check_common_event
|
||
SceneManager.goto(Scene_Map) if $game_temp.common_event_reserved?
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 項目処理後のリフレッシュ
|
||
#--------------------------------------------------------------------------
|
||
def check_refresh_window(command)
|
||
# Do Nothing
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● コモンベントの実行
|
||
#--------------------------------------------------------------------------
|
||
def start_common_event(common_event_id)
|
||
if @status_window && @status_window.index >= 0
|
||
$game_party.menu_actor = $game_party.members[@status_window.index]
|
||
end
|
||
interpreter = Scene_Menu::Game_Interpreter.new
|
||
interpreter.setup($data_common_events[common_event_id].list)
|
||
interpreter.update while interpreter.running?
|
||
end
|
||
end
|
||
|
||
class Scene_Menu::Game_Interpreter < ::Game_Interpreter
|
||
#--------------------------------------------------------------------------
|
||
# ●
|
||
#--------------------------------------------------------------------------
|
||
undef command_101 # 文章の表示
|
||
undef command_102 # 選択肢の表示
|
||
undef command_103 # 数値入力の処理
|
||
undef command_104 # アイテム選択の処理
|
||
undef command_105 # スクロール文章の表示
|
||
undef command_201 # 場所移動
|
||
undef command_204 # マップのスクロール
|
||
undef command_205 # 移動ルートの設定
|
||
undef command_217 # 隊列メンバーの集合
|
||
undef command_261 # ムービーの再生
|
||
undef command_301 # バトルの処理
|
||
undef command_351 # メニュー画面を開く
|
||
end
|
||
|
||
class Window_CustomMenuCommand < Window_MenuCommand
|
||
#--------------------------------------------------------------------------
|
||
# ● オブジェクト初期化
|
||
#--------------------------------------------------------------------------
|
||
def initialize(ident)
|
||
@ident = ident
|
||
super()
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● ウィンドウ内容の幅を計算
|
||
#--------------------------------------------------------------------------
|
||
def contents_width
|
||
(item_width + spacing) * col_max - spacing
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 横に項目が並ぶときの空白の幅を取得
|
||
#--------------------------------------------------------------------------
|
||
def spacing
|
||
return 8
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● コマンドリストの作成
|
||
#--------------------------------------------------------------------------
|
||
def make_command_list
|
||
return unless @ident
|
||
unless CAO::CM::COMMANDS[@ident]
|
||
raise CustomizeError,
|
||
"識別子 :#{@ident} のメニューコマンドの設定がありません。(COMMANDS)"
|
||
end
|
||
CAO::CM::COMMANDS[@ident].each do |symbol|
|
||
unless CAO::CM::COMMAND_ITEMS[symbol]
|
||
puts "識別子 :#{symbol} の項目の設定がありません。(COMMAND_ITEMS)"
|
||
next
|
||
end
|
||
item = Game_MenuItem.new(symbol, CAO::CM::COMMAND_ITEMS[symbol])
|
||
@list << item unless item.hide?
|
||
end
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● コマンド名の取得
|
||
#--------------------------------------------------------------------------
|
||
def command_name(index)
|
||
@list[index].name
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● コマンドの有効状態を取得
|
||
#--------------------------------------------------------------------------
|
||
def command_enabled?(index)
|
||
param = @list[index].enable
|
||
return false if @list[index].personal? && !$game_party.exists
|
||
return true if param == true
|
||
return false if param == false
|
||
return eval(param.to_s) if param.is_a?(Symbol) || param.is_a?(String)
|
||
raise "must not happen"
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● コマンドアイコン番号の取得
|
||
#--------------------------------------------------------------------------
|
||
def command_icon_index(index)
|
||
return @list[index].icon_index
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 選択項目のコマンドデータを取得
|
||
#--------------------------------------------------------------------------
|
||
def current_data
|
||
index >= 0 ? @list[index] : nil
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 選択項目の有効状態を取得
|
||
#--------------------------------------------------------------------------
|
||
def current_item_enabled?
|
||
index >= 0 ? command_enabled?(index) : false
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 選択項目のシンボルを取得
|
||
#--------------------------------------------------------------------------
|
||
def current_symbol
|
||
current_data ? current_data.symbol : nil
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 選択項目の実行
|
||
#--------------------------------------------------------------------------
|
||
def current_exec
|
||
current_data.exec
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 指定されたシンボルを持つコマンドにカーソルを移動
|
||
#--------------------------------------------------------------------------
|
||
def select_symbol(symbol)
|
||
@list.each_index {|i| select(i) if @list[i].symbol == symbol }
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ●
|
||
#--------------------------------------------------------------------------
|
||
def clear_handler
|
||
@handler = {}
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 動作に対応するハンドラの設定
|
||
#--------------------------------------------------------------------------
|
||
def set_handlers(obj)
|
||
#
|
||
# ここでエラーが発生した場合、項目の設定が間違っている可能性があります。
|
||
# 項目処理の設定を確認してください。
|
||
#
|
||
# NameError : undefined method `○○' for class `Scene_Menu'
|
||
# つづりが間違っていないか確認してください。
|
||
#
|
||
# NameError : undefined method `command_sub' for class `Scene_Menu'
|
||
# 『サブコマンド』スクリプトが未導入の可能性があります。
|
||
#
|
||
@list.each {|cmd| @handler[cmd.symbol] = obj.method(cmd.handler) }
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● カーソルを下に移動
|
||
#--------------------------------------------------------------------------
|
||
def cursor_down(wrap = false)
|
||
if index < item_max - col_max || (wrap && col_max == 1)
|
||
select((index + col_max) % item_max)
|
||
elsif col_max != 1 && index < (item_max.to_f/col_max).ceil*col_max-col_max
|
||
select(item_max - 1)
|
||
end
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 項目の描画
|
||
#--------------------------------------------------------------------------
|
||
def draw_item(index)
|
||
rect = item_rect(index)
|
||
enabled = command_enabled?(index)
|
||
if command_icon_index(index)
|
||
draw_icon(command_icon_index(index), rect.x, rect.y, enabled)
|
||
rect.x += 26
|
||
rect.width -= 28
|
||
else
|
||
rect.x += 4
|
||
rect.width -= 8
|
||
end
|
||
change_color(normal_color, enabled)
|
||
draw_text(rect, command_name(index), alignment)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● リフレッシュ
|
||
#--------------------------------------------------------------------------
|
||
def refresh
|
||
self.contents.clear
|
||
draw_all_items
|
||
end
|
||
end
|
||
|
||
class Game_Actor
|
||
#--------------------------------------------------------------------------
|
||
# ● 公開インスタンス変数
|
||
#--------------------------------------------------------------------------
|
||
attr_accessor :portrait_name # 立ち絵 ファイル名
|
||
#--------------------------------------------------------------------------
|
||
# ● 立ち絵のファイル名を取得
|
||
#--------------------------------------------------------------------------
|
||
def portrait_name
|
||
return @portrait_name if @portrait_name
|
||
return sprintf(CAO::CM::PORTRAIT_NAME, self.id, self.expression_index)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 表情のインデックス
|
||
#--------------------------------------------------------------------------
|
||
def expression_index
|
||
rate = (self.hp_rate * 100).ceil
|
||
index = CAO::CM::EXPRESSIVE_RATE.index {|r| r < rate }
|
||
return index || CAO::CM::EXPRESSIVE_RATE.size
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 経験値の割合を取得
|
||
#--------------------------------------------------------------------------
|
||
def cm_exp_rate
|
||
return 1.0 if max_level?
|
||
return self.cm_accumulated_exp / self.cm_requisite_exp.to_f
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● レベルアップに必要な経験値を取得
|
||
#--------------------------------------------------------------------------
|
||
def cm_requisite_exp
|
||
return self.next_level_exp - self.current_level_exp
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 現在のレベルでの経験値を取得
|
||
#--------------------------------------------------------------------------
|
||
def cm_accumulated_exp
|
||
return self.exp - self.current_level_exp
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● レベルアップに必要な残りの経験値を取得
|
||
#--------------------------------------------------------------------------
|
||
def cm_remaining_exp
|
||
return self.next_level_exp - self.exp
|
||
end
|
||
end
|
||
|
||
class CAO::CM::Canvas
|
||
include CAO::CM
|
||
#--------------------------------------------------------------------------
|
||
# ● 公開インスタンス変数
|
||
#--------------------------------------------------------------------------
|
||
attr_reader :window
|
||
attr_reader :bitmap
|
||
#--------------------------------------------------------------------------
|
||
# ● オブジェクト初期化
|
||
#--------------------------------------------------------------------------
|
||
def initialize(obj)
|
||
case obj
|
||
when Window
|
||
@window = obj
|
||
@bitmap = obj.contents
|
||
when Bitmap
|
||
@window = nil
|
||
@bitmap = obj
|
||
else
|
||
raise TypeError,
|
||
"wrong argument type #{obj.class} (expected Bitmap or Window)"
|
||
end
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ●
|
||
#--------------------------------------------------------------------------
|
||
def contents
|
||
return @window ? @window.contents : @bitmap
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ●
|
||
#--------------------------------------------------------------------------
|
||
def draw_actor_items(actor, x, y, list)
|
||
#
|
||
# メニューステータスの設定が間違っている可能性があります。
|
||
# 表示項目の設定を確認してください。
|
||
#
|
||
# TypeError
|
||
# 引数の型(数値や文字列など)が間違っています。
|
||
# 設定がずれているかもしれません。
|
||
# 設定は必ず [シンボル, 数値, 数値, ... ] の形で始まります。
|
||
# 識別子とx座標とy座標の設定は省略できません。
|
||
#
|
||
# ArgumentError : wrong number of arguments
|
||
# 引数の数が間違っています。
|
||
# オプション部分の設定に間違いがないか確認してください。
|
||
#
|
||
list.each do |params|
|
||
symbol = params[0]
|
||
argv = params[1, params.size]
|
||
xx, yy = argv[0], argv[1]
|
||
unless METHODS_NAME[symbol]
|
||
puts "識別子 :#{symbol} の処理は定義されていません。"
|
||
next
|
||
end
|
||
unless xx && yy
|
||
raise CustomizeError, "描画する座標が設定されていません。"
|
||
end
|
||
begin
|
||
opt = (argv.size <= 2) ? [] : argv[2, argv.size - 2]
|
||
eval("#{METHODS_NAME[symbol]}(actor, x + xx, y + yy, *opt)")
|
||
rescue
|
||
msg = "{ Actor(#{actor.respond_to?(:id)&&actor.id}) "
|
||
msg << "Symbol(:#{symbol}) Method(#{METHODS_NAME[symbol]}) }\n"
|
||
msg << $!.message
|
||
raise $!, msg, $!.backtrace
|
||
end
|
||
end
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ●
|
||
#--------------------------------------------------------------------------
|
||
METHODS_NAME = {}
|
||
METHODS_NAME[:w_chara] = '@window.draw_actor_graphics'
|
||
METHODS_NAME[:w_face] = '@window.draw_actor_face'
|
||
METHODS_NAME[:w_name] = '@window.draw_actor_name'
|
||
METHODS_NAME[:w_class] = '@window.draw_actor_class'
|
||
METHODS_NAME[:w_nick] = '@window.draw_actor_nickname'
|
||
METHODS_NAME[:w_level] = '@window.draw_actor_level'
|
||
METHODS_NAME[:w_state] = '@window.draw_actor_icons'
|
||
METHODS_NAME[:w_hp] = '@window.draw_actor_hp'
|
||
METHODS_NAME[:w_mp] = '@window.draw_actor_mp'
|
||
METHODS_NAME[:w_tp] = '@window.draw_actor_tp'
|
||
|
||
if CAO::CM::EXPRESSIVE_RATE.empty?
|
||
METHODS_NAME[:face] = :draw_actor_face
|
||
else
|
||
METHODS_NAME[:face] = :draw_actor_expression
|
||
end
|
||
METHODS_NAME[:chara] = :draw_actor_graphic
|
||
METHODS_NAME[:name] = :draw_actor_name
|
||
METHODS_NAME[:class] = :draw_actor_class
|
||
METHODS_NAME[:nick] = :draw_actor_nickname
|
||
METHODS_NAME[:level] = :draw_actor_level
|
||
METHODS_NAME[:lv_g] = :draw_actor_level_g
|
||
METHODS_NAME[:state] = :draw_actor_icons
|
||
METHODS_NAME[:hp] = :draw_actor_hp
|
||
METHODS_NAME[:mp] = :draw_actor_mp
|
||
METHODS_NAME[:tp] = :draw_actor_tp
|
||
METHODS_NAME[:exp] = :draw_actor_exp
|
||
METHODS_NAME[:param] = :draw_actor_param
|
||
METHODS_NAME[:icon] = :draw_actor_icon
|
||
METHODS_NAME[:bust] = :draw_actor_portrait
|
||
METHODS_NAME[:fill] = :draw_actor_rect
|
||
METHODS_NAME[:pict] = :draw_actor_picture
|
||
METHODS_NAME[:text] = :draw_actor_text
|
||
METHODS_NAME[:num] = :draw_actor_number
|
||
#--------------------------------------------------------------------------
|
||
# ● 定数
|
||
#--------------------------------------------------------------------------
|
||
COLOR_AIB_1 = Color.new(0, 0, 0) # アクターアイコンの縁の色
|
||
COLOR_AIB_2 = Color.new(255, 255, 255) # アクターアイコンの背景色
|
||
#--------------------------------------------------------------------------
|
||
# ● 行の高さを取得
|
||
#--------------------------------------------------------------------------
|
||
def line_height
|
||
return 24
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 半透明描画用のアルファ値を取得
|
||
#--------------------------------------------------------------------------
|
||
def translucent_alpha
|
||
return 160
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ●
|
||
#--------------------------------------------------------------------------
|
||
def str2color(value)
|
||
case value
|
||
when Color
|
||
return value
|
||
when Array
|
||
return Color.new(*value)
|
||
when Integer
|
||
num = value
|
||
when Symbol, String
|
||
text = value.to_s.sub(/^(0x|x)/, "")
|
||
case text.size
|
||
when 1; text = text * 6 << 'FF'
|
||
when 2; text = text[0] * 6 << text[1] * 2
|
||
when 3; text = text[0] * 2 << text[1] * 2 << text[2] * 2 << 'FF'
|
||
when 4; text = text[0] * 2 << text[1] * 2 << text[2] * 2 << text[3] * 2
|
||
when 6; text = text[0, 6] << 'FF'
|
||
end
|
||
num = eval("0x#{text}")
|
||
end
|
||
return Color.new(num >> 24, num >> 16 & 255, num >> 8 & 255, num & 255)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 文字色取得
|
||
# n : 文字色番号(0..31)
|
||
#--------------------------------------------------------------------------
|
||
def text_color(n, enabled = true)
|
||
color = Cache.system("Window").get_pixel(64+(n%8)*8, 96+(n/8)*8)
|
||
color.alpha = translucent_alpha unless enabled
|
||
return color
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 各種文字色の取得
|
||
#--------------------------------------------------------------------------
|
||
def normal_color; text_color(0); end; # 通常
|
||
def system_color; text_color(16); end; # システム
|
||
def crisis_color; text_color(17); end; # ピンチ
|
||
def knockout_color; text_color(18); end; # 戦闘不能
|
||
def gauge_back_color; text_color(19); end; # ゲージ背景
|
||
def hp_gauge_color1; text_color(20); end; # HP ゲージ 1
|
||
def hp_gauge_color2; text_color(21); end; # HP ゲージ 2
|
||
def mp_gauge_color1; text_color(22); end; # MP ゲージ 1
|
||
def mp_gauge_color2; text_color(23); end; # MP ゲージ 2
|
||
def mp_cost_color; text_color(23); end; # 消費 MP
|
||
def power_up_color; text_color(24); end; # 装備 パワーアップ
|
||
def power_down_color; text_color(25); end; # 装備 パワーダウン
|
||
def tp_gauge_color1; text_color(28); end; # TP ゲージ 1
|
||
def tp_gauge_color2; text_color(29); end; # TP ゲージ 2
|
||
def tp_cost_color; text_color(29); end; # 消費 TP
|
||
def exp_gauge_color1; text_color(30); end; # EXP ゲージ 1
|
||
def exp_gauge_color2; text_color(31); end; # EXP ゲージ 2
|
||
#--------------------------------------------------------------------------
|
||
# ● 保留項目の背景色を取得
|
||
#--------------------------------------------------------------------------
|
||
def pending_color
|
||
Cache.system("Window").get_pixel(80, 80)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● テキスト描画色の変更
|
||
#--------------------------------------------------------------------------
|
||
def change_color(color, enabled = true)
|
||
if block_given?
|
||
last_color = self.contents.font.color.dup
|
||
change_color(color, enabled)
|
||
yield
|
||
self.contents.font.color = last_color
|
||
else
|
||
self.contents.font.color.set(color)
|
||
self.contents.font.color.alpha = translucent_alpha unless enabled
|
||
end
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● テキストサイズの変更
|
||
#--------------------------------------------------------------------------
|
||
def change_size(size)
|
||
if block_given?
|
||
last_size = self.contents.font.size
|
||
change_size(size)
|
||
yield
|
||
self.contents.font.size = last_size
|
||
else
|
||
self.contents.font.size = size
|
||
end
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● テキストの描画
|
||
#--------------------------------------------------------------------------
|
||
def draw_text(*args)
|
||
contents.draw_text(*args)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● テキストサイズの取得
|
||
#--------------------------------------------------------------------------
|
||
def text_size(str)
|
||
contents.text_size(str)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 制御文字つきテキストの描画
|
||
#--------------------------------------------------------------------------
|
||
def draw_text_ex(x, y, text)
|
||
reset_font_settings
|
||
text = convert_escape_characters(text)
|
||
pos = {:x => x, :y => y, :new_x => x, :height => calc_line_height(text)}
|
||
process_character(text.slice!(0, 1), text, pos) until text.empty?
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● フォント設定のリセット
|
||
#--------------------------------------------------------------------------
|
||
def reset_font_settings
|
||
change_color(normal_color)
|
||
contents.font.size = Font.default_size
|
||
contents.font.bold = Font.default_bold
|
||
contents.font.italic = Font.default_italic
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 制御文字の事前変換
|
||
# 実際の描画を始める前に、原則として文字列に変わるものだけを置き換える。
|
||
# 文字「\」はエスケープ文字(\e)に変換。
|
||
#--------------------------------------------------------------------------
|
||
def convert_escape_characters(text)
|
||
result = text.to_s.clone
|
||
result.gsub!(/\r\n/) { "\n" }
|
||
result.gsub!(/\\/) { "\e" }
|
||
result.gsub!(/\e\e/) { "\\" }
|
||
result.gsub!(/\e({+)/i) { "\e{" * $1.count("{") }
|
||
result.gsub!(/\e(}+)/i) { "\e}" * $1.count("}") }
|
||
result.gsub!(/\eV\[(\d+)\]/i) { $game_variables[$1.to_i] }
|
||
result.gsub!(/\eV\[(\d+)\]/i) { $game_variables[$1.to_i] }
|
||
result.gsub!(/\eS\[(\d+),(.*?),(.*?)\]/i) { $game_switches[$1.to_i]?$2:$3 }
|
||
result.gsub!(/\eN\[(\d+)\]/i) { actor_name($1.to_i) }
|
||
result.gsub!(/\eP\[(\d+)\]/i) { party_member_name($1.to_i) }
|
||
result.gsub!(/\eG/i) { Vocab::currency_unit }
|
||
result.gsub!(/\e\$/) { $game_party.gold }
|
||
result.gsub!(/\eW/) { $game_party.steps }
|
||
result.gsub!(/\eT\[(.+?)\]/i) { play_time($1) }
|
||
result.gsub!(/\eT/i) { play_time }
|
||
result.gsub!(/\en/) { "\n" }
|
||
result.gsub!(/<%(.*?)%>/) { eval($1) }
|
||
result
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● アクター n 番の名前を取得
|
||
#--------------------------------------------------------------------------
|
||
def actor_name(n)
|
||
actor = n >= 1 ? $game_actors[n] : nil
|
||
actor ? actor.name : ""
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● パーティメンバー n 番の名前を取得
|
||
#--------------------------------------------------------------------------
|
||
def party_member_name(n)
|
||
actor = n >= 1 ? $game_party.members[n - 1] : nil
|
||
actor ? actor.name : ""
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● を取得
|
||
#--------------------------------------------------------------------------
|
||
def play_time(format = '%3d:%02d:%02d')
|
||
total = Graphics.frame_count / Graphics.frame_rate
|
||
return sprintf(format,
|
||
(total / 3600), (total / 60 % 60), (total % 60), (total / 60), total)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 文字の処理
|
||
# c : 文字
|
||
# text : 描画処理中の文字列バッファ(必要なら破壊的に変更)
|
||
# pos : 描画位置 {:x, :y, :new_x, :height}
|
||
#--------------------------------------------------------------------------
|
||
def process_character(c, text, pos)
|
||
case c
|
||
when "\n" # 改行
|
||
process_new_line(text, pos)
|
||
when "\e" # 制御文字
|
||
process_escape_character(obtain_escape_code(text), text, pos)
|
||
else # 普通の文字
|
||
process_normal_character(c, pos)
|
||
end
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 通常文字の処理
|
||
#--------------------------------------------------------------------------
|
||
def process_normal_character(c, pos)
|
||
text_width = text_size(c).width
|
||
draw_text(pos[:x], pos[:y], text_width * 2, pos[:height], c)
|
||
pos[:x] += text_width
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 改行文字の処理
|
||
#--------------------------------------------------------------------------
|
||
def process_new_line(text, pos)
|
||
pos[:x] = pos[:new_x]
|
||
pos[:y] += pos[:height]
|
||
pos[:height] = calc_line_height(text)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 制御文字の本体を破壊的に取得
|
||
#--------------------------------------------------------------------------
|
||
def obtain_escape_code(text)
|
||
text.slice!(/^[\$\.\|\^!><\{\}\\]|^[A-Z]+/i)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 制御文字の引数を破壊的に取得
|
||
#--------------------------------------------------------------------------
|
||
def obtain_escape_param(text)
|
||
text.slice!(/^\[-?\d+\]/)[/-?\d+/].to_i rescue 0
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ●
|
||
#--------------------------------------------------------------------------
|
||
def obtain_escape_value(text, value)
|
||
text.slice!(/^\[([+-]?)(\d+)\]/i)
|
||
return value + $2.to_i if $1 == '+'
|
||
return value - $2.to_i if $1 == '-'
|
||
return $2.to_i
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 制御文字の処理
|
||
# code : 制御文字の本体部分(「\C[1]」なら「C」)
|
||
#--------------------------------------------------------------------------
|
||
def process_escape_character(code, text, pos)
|
||
case code.upcase
|
||
when 'C'
|
||
change_color(text_color(obtain_escape_param(text)))
|
||
when 'I'
|
||
process_draw_icon(obtain_escape_param(text), pos)
|
||
when '{'
|
||
make_font_bigger
|
||
when '}'
|
||
make_font_smaller
|
||
when 'X'
|
||
pos[:x] = obtain_escape_value(text, pos[:x])
|
||
when 'Y'
|
||
pos[:y] = obtain_escape_value(text, pos[:y])
|
||
when 'L'
|
||
process_draw_line(text, pos)
|
||
end
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 制御文字によるライン描画の処理
|
||
#--------------------------------------------------------------------------
|
||
def process_draw_line(text, pos)
|
||
if text.slice!(/^\[(\d+)\s*,\s*(\d+)(?:\s*,\s*([AFHTMBXS]+))?\]/i)
|
||
x, y, w, h, params = pos[:x], pos[:y], $1.to_i, $2.to_i, ($3 || "")
|
||
# 描画幅を文字サイズから (A:自動,F:全角,H:半角)
|
||
case params
|
||
when /A/i; w = text_size(text[0, w]).width
|
||
when /F/i; w = text_size(" " * w).width
|
||
when /H/i; w = text_size(" " * w).width
|
||
end
|
||
# 線の描画位置 (t:上,m:中,b:下, デフォルトは下)
|
||
unless params[/T/i]
|
||
if params[/M/i]
|
||
y += (pos[:height] + h) / 2
|
||
else
|
||
y += pos[:height] - h
|
||
end
|
||
end
|
||
# 影の描画
|
||
if params[/S/i]
|
||
w -= 1
|
||
color = gauge_back_color
|
||
color.alpha = translucent_alpha
|
||
self.contents.fill_rect(x + 1, y + 1, w, h, color)
|
||
end
|
||
# 線の描画
|
||
self.contents.fill_rect(x, y, w, h, self.contents.font.color)
|
||
# x座標を進める
|
||
x += w if params[/X/i]
|
||
elsif text.slice!(/^\[([0-9, ]+?)(0x[0-9A-F]+)?\]/i)
|
||
color = $2
|
||
param = $1.sub(/, *$/, '').split(',').map {|s| s.to_i }
|
||
if param.is_a?(Array) && param.size == 4
|
||
if color
|
||
draw_fill_rect(*param, str2color(color))
|
||
else
|
||
self.contents.fill_rect(*param, self.contents.font.color)
|
||
end
|
||
end
|
||
end
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 制御文字によるアイコン描画の処理
|
||
#--------------------------------------------------------------------------
|
||
def process_draw_icon(icon_index, pos)
|
||
draw_icon(icon_index, pos[:x], pos[:y] + (pos[:height] - 24) / 2)
|
||
pos[:x] += 24
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● フォントを大きくする
|
||
#--------------------------------------------------------------------------
|
||
def make_font_bigger
|
||
contents.font.size += 4 if contents.font.size <= 92
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● フォントを小さくする
|
||
#--------------------------------------------------------------------------
|
||
def make_font_smaller
|
||
contents.font.size -= 4 if contents.font.size >= 10
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 行の高さを計算
|
||
# restore_font_size : 計算後にフォントサイズを元に戻す
|
||
#--------------------------------------------------------------------------
|
||
def calc_line_height(text, restore_font_size = true)
|
||
result = [line_height, contents.font.size].max
|
||
last_font_size = contents.font.size
|
||
text.slice(/^.*$/).scan(/\e[\{\}]/).each do |esc|
|
||
make_font_bigger if esc == "\e{"
|
||
make_font_smaller if esc == "\e}"
|
||
result = [result, contents.font.size].max
|
||
end
|
||
contents.font.size = last_font_size if restore_font_size
|
||
result
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ●
|
||
#--------------------------------------------------------------------------
|
||
def draw_fill_rect(x, y, width, height, color)
|
||
bitmap = Bitmap.new(width, height)
|
||
bitmap.fill_rect(bitmap.rect, color)
|
||
self.contents.blt(x, y, bitmap, bitmap.rect)
|
||
bitmap.dispose
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● ゲージの描画
|
||
# rate : 割合(1.0 で満タン)
|
||
# color1 : グラデーション 左端
|
||
# color2 : グラデーション 右端
|
||
#--------------------------------------------------------------------------
|
||
def draw_gauge(x, y, width, rate, color1, color2)
|
||
fill_w = (width * rate).to_i
|
||
gauge_y = y + line_height - 8
|
||
contents.fill_rect(x, gauge_y, width, 6, gauge_back_color)
|
||
contents.gradient_fill_rect(x, gauge_y, fill_w, 6, color1, color2)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● アイコンの描画
|
||
#--------------------------------------------------------------------------
|
||
def draw_icon(icon_index, x, y, enabled = true)
|
||
bitmap = Cache.system("Iconset")
|
||
rect = Rect.new(icon_index % 16 * 24, icon_index / 16 * 24, 24, 24)
|
||
contents.blt(x, y, bitmap, rect, enabled ? 255 : translucent_alpha)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 顔グラフィックの描画
|
||
#--------------------------------------------------------------------------
|
||
def draw_face(face_name, face_index, x, y, size = 96, enabled = true)
|
||
bitmap = Cache.face(face_name)
|
||
dest_rect = Rect.new(x, y, 96, 96)
|
||
src_rect = Rect.new(face_index % 4 * 96, face_index / 4 * 96, 96, 96)
|
||
opacity = enabled ? 255 : translucent_alpha
|
||
|
||
case size
|
||
when Integer
|
||
src_rect.x += (96 - size) / 2
|
||
src_rect.y += (96 - size) / 2
|
||
src_rect.width = size
|
||
src_rect.height = size
|
||
contents.blt(x, y, bitmap, src_rect, opacity)
|
||
when Array
|
||
case size.size
|
||
when 1
|
||
dest_rect.width, dest_rect.height = size[0], size[0]
|
||
when 2
|
||
dest_rect.width, dest_rect.height = size[0], size[1]
|
||
when 4
|
||
dest_rect.width, dest_rect.height = size[2], size[3]
|
||
src_rect.width, src_rect.height = size[2], size[3]
|
||
src_rect.x, src_rect.y = src_rect.x + size[0], src_rect.y + size[1]
|
||
else
|
||
raise "wrong number of elements (#{size.size} of 2)"
|
||
end
|
||
contents.stretch_blt(dest_rect, bitmap, src_rect, opacity)
|
||
else
|
||
raise TypeError,
|
||
"wrong argument type #{size.class} (expected Integer or Array)"
|
||
end
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 歩行グラフィックの描画
|
||
#--------------------------------------------------------------------------
|
||
def draw_character(character_name, character_index, x, y)
|
||
return unless character_name
|
||
bitmap = Cache.character(character_name)
|
||
sign = character_name[/^[\!\$]./]
|
||
if sign && sign.include?('$')
|
||
cw = bitmap.width / 3
|
||
ch = bitmap.height / 4
|
||
else
|
||
cw = bitmap.width / 12
|
||
ch = bitmap.height / 8
|
||
end
|
||
n = character_index
|
||
src_rect = Rect.new((n%4*3+1)*cw, (n/4*4)*ch, cw, ch)
|
||
contents.blt(x - cw / 2, y - ch, bitmap, src_rect)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● HP の文字色を取得
|
||
#--------------------------------------------------------------------------
|
||
def hp_color(actor)
|
||
return knockout_color if actor.hp == 0
|
||
return crisis_color if actor.hp < actor.mhp / 4
|
||
return normal_color
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● MP の文字色を取得
|
||
#--------------------------------------------------------------------------
|
||
def mp_color(actor)
|
||
return crisis_color if actor.mp < actor.mmp / 4
|
||
return normal_color
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● TP の文字色を取得
|
||
#--------------------------------------------------------------------------
|
||
def tp_color(actor)
|
||
return normal_color
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● アクターの歩行グラフィック描画
|
||
#--------------------------------------------------------------------------
|
||
def draw_actor_graphic(actor, x, y)
|
||
draw_character(actor.character_name, actor.character_index, x, y)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● アクターの顔グラフィック描画
|
||
#--------------------------------------------------------------------------
|
||
def draw_actor_face(actor, x, y, size = 96)
|
||
draw_face(actor.face_name, actor.face_index, x, y, size)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● アクターの表情グラフィック描画
|
||
#--------------------------------------------------------------------------
|
||
def draw_actor_expression(actor, x, y, size = 96)
|
||
draw_face(actor.face_name, actor.expression_index, x, y, size)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 歩行アイコンの描画
|
||
# enabled : 有効フラグ。false のとき半透明で描画
|
||
#--------------------------------------------------------------------------
|
||
def draw_actor_icon(actor, x, y, enabled = true)
|
||
return unless actor
|
||
self.contents.fill_rect(x, y, 24, 24, COLOR_AIB_1)
|
||
self.contents.fill_rect(x + 1, y + 1, 22, 22, COLOR_AIB_2)
|
||
return unless actor.character_name
|
||
return if actor.character_name.empty?
|
||
bitmap = Cache.character(actor.character_name)
|
||
sign = actor.character_name[/^[\!\$]./]
|
||
if sign != nil and sign.include?('$')
|
||
cw = bitmap.width / 3
|
||
ch = bitmap.height / 4
|
||
else
|
||
cw = bitmap.width / 12
|
||
ch = bitmap.height / 8
|
||
end
|
||
n = actor.character_index
|
||
src_rect = Rect.new((n%4*3+1)*cw, (n/4*4)*ch, 20, 20)
|
||
src_rect.x += (cw - src_rect.width) / 2
|
||
src_rect.y += (ch - src_rect.height) / 4
|
||
opacity = (enabled ? 255 : translucent_alpha)
|
||
self.contents.blt(x + 2, y + 2, bitmap, src_rect, opacity)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 立ち絵の描画
|
||
#--------------------------------------------------------------------------
|
||
def draw_actor_portrait(actor, x, y, enabled = true)
|
||
return unless actor
|
||
bitmap = Cache.picture(actor.portrait_name)
|
||
opacity = (enabled ? 255 : translucent_alpha)
|
||
self.contents.blt(x, y, bitmap, bitmap.rect, opacity)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● の描画
|
||
# [:pict, x, y, "file", "script"]
|
||
# [:pict, x, y, ["file","file"], "script"]
|
||
#--------------------------------------------------------------------------
|
||
def draw_actor_picture(actor, x, y, file, script = nil)
|
||
return unless actor
|
||
battler, alternate = file
|
||
if script
|
||
filename = (eval(script) ? battler : alternate)
|
||
else
|
||
filename = (actor.battle_member? ? battler : alternate) || battler
|
||
end
|
||
if filename && !filename.empty?
|
||
bitmap = Cache.picture(filename % actor.id)
|
||
self.contents.blt(x, y, bitmap, bitmap.rect)
|
||
end
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● の描画
|
||
#--------------------------------------------------------------------------
|
||
def draw_actor_text(actor, x, y, text, script = nil)
|
||
return if script && !eval(script)
|
||
draw_text_ex(x, y, text.gsub(/\\{(\w+?)}/) { actor.__send__($1) })
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● の描画
|
||
#--------------------------------------------------------------------------
|
||
def draw_actor_number(actor, x, y, num, file)
|
||
bitmap = Cache.picture(file)
|
||
r_num = Rect.new(0, 0, bitmap.width / 13, bitmap.height)
|
||
param = String(num.is_a?(String) ? eval(num) : num)
|
||
param.split(//).each_with_index do |c,i|
|
||
case c
|
||
when ' '; next
|
||
when '+'; index = 10
|
||
when '-'; index = 11
|
||
when /\d/; index = Integer(c)
|
||
else; index = 12
|
||
end
|
||
r_num.x = r_num.width * index
|
||
self.contents.blt(x + r_num.width * i, y, bitmap, r_num)
|
||
end
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 名前の描画
|
||
#--------------------------------------------------------------------------
|
||
def draw_actor_name(actor, x, y, width = 124)
|
||
change_color(hp_color(actor))
|
||
draw_text(x, y, width, line_height, actor.name)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 職業の描画
|
||
#--------------------------------------------------------------------------
|
||
def draw_actor_class(actor, x, y, width = 124)
|
||
change_color(normal_color)
|
||
draw_text(x, y, width, line_height, actor.class.name)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 二つ名の描画
|
||
#--------------------------------------------------------------------------
|
||
def draw_actor_nickname(actor, x, y, width = 124)
|
||
change_color(normal_color)
|
||
draw_text(x, y, width, line_height, actor.nickname)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● レベルの描画
|
||
#--------------------------------------------------------------------------
|
||
def draw_actor_level(actor, x, y, width = 64)
|
||
if VISIBLE_SYSTEM
|
||
change_color(system_color)
|
||
draw_text(x, y, 32, line_height, Vocab::level_a)
|
||
end
|
||
change_color(normal_color)
|
||
draw_text(x + width - 32, y, 32, line_height, actor.level, 2)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● レベルの描画 (経験値ゲージ付)
|
||
#--------------------------------------------------------------------------
|
||
def draw_actor_level_g(actor, x, y, width = 64)
|
||
draw_gauge(x,y,width,actor.cm_exp_rate,exp_gauge_color1,exp_gauge_color2)
|
||
if VISIBLE_SYSTEM
|
||
change_color(system_color)
|
||
draw_text(x, y, 32, line_height, Vocab::level_a)
|
||
end
|
||
change_color(tp_color(actor))
|
||
draw_text(x + width - 32, y, 32, line_height, actor.level, 2)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● ステートおよび強化/弱体のアイコンを描画
|
||
#--------------------------------------------------------------------------
|
||
def draw_actor_icons(actor, x, y, width = 96, align = 0)
|
||
icons = (actor.state_icons + actor.buff_icons)[0, width / 24]
|
||
case align
|
||
when 0; left = 0
|
||
when 1; left = (width - icons.size * 24) / 2
|
||
when 2; left = (width - icons.size * 24)
|
||
end
|
||
icons.each_with_index {|n, i| draw_icon(n, x + left + 24 * i, y) }
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 現在値/最大値を分数形式で描画
|
||
#--------------------------------------------------------------------------
|
||
def draw_current_and_max_values(x, y, width, current, max, color1, color2)
|
||
change_color(color1)
|
||
xr = x + width
|
||
if width < 96
|
||
draw_text(xr - 40, y, 42, line_height, current, 2)
|
||
else
|
||
draw_text(xr - 92, y, 42, line_height, current, 2)
|
||
change_color(color2)
|
||
draw_text(xr - 52, y, 12, line_height, "/", 2)
|
||
draw_text(xr - 42, y, 42, line_height, max, 2)
|
||
end
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● HP の描画
|
||
#--------------------------------------------------------------------------
|
||
def draw_actor_hp(actor, x, y, width = 124)
|
||
draw_gauge(x, y, width, actor.hp_rate, hp_gauge_color1, hp_gauge_color2)
|
||
if VISIBLE_SYSTEM
|
||
change_color(system_color)
|
||
draw_text(x, y, 30, line_height, Vocab::hp_a)
|
||
end
|
||
draw_current_and_max_values(x, y, width, actor.hp, actor.mhp,
|
||
hp_color(actor), normal_color)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● MP の描画
|
||
#--------------------------------------------------------------------------
|
||
def draw_actor_mp(actor, x, y, width = 124)
|
||
draw_gauge(x, y, width, actor.mp_rate, mp_gauge_color1, mp_gauge_color2)
|
||
if VISIBLE_SYSTEM
|
||
change_color(system_color)
|
||
draw_text(x, y, 30, line_height, Vocab::mp_a)
|
||
end
|
||
draw_current_and_max_values(x, y, width, actor.mp, actor.mmp,
|
||
mp_color(actor), normal_color)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● TP の描画
|
||
#--------------------------------------------------------------------------
|
||
def draw_actor_tp(actor, x, y, width = 124)
|
||
draw_gauge(x, y, width, actor.tp_rate, tp_gauge_color1, tp_gauge_color2)
|
||
if VISIBLE_SYSTEM
|
||
change_color(system_color)
|
||
draw_text(x, y, 30, line_height, Vocab::tp_a)
|
||
end
|
||
change_color(tp_color(actor))
|
||
draw_text(x + width - 42, y, 42, line_height, actor.tp.to_i, 2)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ●
|
||
#--------------------------------------------------------------------------
|
||
def actor_exp_rate(actor)
|
||
return 1.0 if actor.max_level?
|
||
exp_rate = actor.exp - actor.exp_for_level(actor.level).to_f
|
||
exp_rate /= actor.next_level_exp - actor.exp_for_level(actor.level)
|
||
return exp_rate
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 経験値の描画
|
||
#--------------------------------------------------------------------------
|
||
def draw_actor_exp(actor, x, y, width = 124)
|
||
draw_gauge(x,y,width,actor.cm_exp_rate,exp_gauge_color1,exp_gauge_color2)
|
||
if VISIBLE_SYSTEM
|
||
change_color(system_color)
|
||
draw_text(x, y, 30, line_height, VOCABS[:exp_a])
|
||
end
|
||
change_color(tp_color(actor))
|
||
draw_text(x + width - 42, y, 42, line_height, actor.cm_remaining_exp, 2)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 経験値情報の描画
|
||
#--------------------------------------------------------------------------
|
||
def draw_actor_exp_info(actor, x, y, width = 124)
|
||
s1 = actor.max_level? ? "-------" : actor.exp
|
||
s2 = actor.max_level? ? "-------" : actor.cm_remaining_exp
|
||
s_next = sprintf(Vocab::ExpNext, Vocab::level)
|
||
change_color(system_color)
|
||
draw_text(x, y + line_height * 0, 180, line_height, Vocab::ExpTotal)
|
||
draw_text(x, y + line_height * 2, 180, line_height, s_next)
|
||
change_color(normal_color)
|
||
draw_text(x, y + line_height * 1, 180, line_height, s1, 2)
|
||
draw_text(x, y + line_height * 3, 180, line_height, s2, 2)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 能力値の描画
|
||
#--------------------------------------------------------------------------
|
||
def draw_actor_param(actor, x, y, param_id, width = 124)
|
||
if param_id < 0 || param_id > 7
|
||
raise ArgumentError, "能力値の ID は 0 から 7 までの数値です。"
|
||
end
|
||
if VISIBLE_SYSTEM
|
||
change_color(system_color)
|
||
draw_text(x, y, width, line_height, Vocab::param(param_id))
|
||
end
|
||
change_color(normal_color)
|
||
draw_text(x, y, width, line_height, actor.param(param_id), 2)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 矩形の描画
|
||
#--------------------------------------------------------------------------
|
||
def draw_actor_rect(actor, x, y, w, h, color, script = nil)
|
||
return if script && !eval(script)
|
||
draw_fill_rect(x, y, w, h, str2color(color))
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● アイテム名の描画
|
||
#--------------------------------------------------------------------------
|
||
def draw_item_name(item, x, y, width = 172, enabled = true)
|
||
return unless item
|
||
draw_icon(item.icon_index, x, y, enabled)
|
||
change_color(normal_color, enabled)
|
||
draw_text(x + 24, y, width, line_height, item.name)
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 通貨単位つき数値(所持金など)の描画
|
||
#--------------------------------------------------------------------------
|
||
def draw_currency_value(value, name, unit, x, y, width)
|
||
cx = text_size(unit).width
|
||
change_color(normal_color)
|
||
draw_text(x, y, width - cx - 2, line_height, value, 2)
|
||
if VISIBLE_SYSTEM
|
||
change_color(system_color)
|
||
draw_text(x, y, width, line_height, name)
|
||
draw_text(x, y, width, line_height, unit, 2)
|
||
end
|
||
end
|
||
#--------------------------------------------------------------------------
|
||
# ● 通貨単位つき数値(所持金など)の描画
|
||
#--------------------------------------------------------------------------
|
||
def draw_gold(x, y, width)
|
||
draw_currency_value(
|
||
$game_party.gold, VOCABS[:gold], Vocab::currency_unit, x, y, width)
|
||
end
|
||
end
|