#==============================================================================
# ★ RGSS3_村人のつぶやき Ver0.11a
#==============================================================================
=begin
作者:tomoaky
webサイト:ひきも記は閉鎖しました。 ([url]http://hikimoki.sakura.ne.jp/[/url])
キャラクターの頭上にフキダシメッセージを表示します。
イベント名、あるいは実行内容の先頭に注釈コマンドでメッセージを設定します。
<mrbt 少年>
メッセージタイプを 少年 に設定します、メッセージタイプは
自由に編集、追加することができます。
イベントコマンドのスクリプトを使い、手動でメッセージを表示することもできます。
mrbt(0, "動き理解した?")
最初の数値でメッセージを表示するイベントを指定してください、
0 で実行中のイベント、-1 でプレイヤー、1 以上でそのIDのイベントが対象です。
メッセージには以下の制御文字が利用できます、内容は文章の表示コマンドと同様です。
\V[1] / \N[1] / \P / \C[2] / \G
上記以外に \L で手動での改行が可能です。
注意事項
イベント名と注釈コマンドの両方でメッセージタイプを指定した場合は
注釈コマンドが優先されます。注釈コマンドでの指定がないイベントページでのみ
イベント名による指定が有効になります。
動作に必要な画像
Graphics/System/mrbt_window.png
2013.08.27 Ver0.11a
出現条件を満たしていないイベントがあるとエラー落ちする不具合を修正
2013.08.20 Ver0.1a
公開
=end
#==============================================================================
# ■ 設定項目
#==============================================================================
module TMMRBT
FONT_SIZE = 16 # フォントサイズ
BACK_OPACITY = 192 # つぶやきウィンドウの不透明度
MESSAGE_DURATION = 240 # つぶやきの表示時間(フレーム)
MIN_INTERVAL = 180 # 次のつぶやきまでの最小間隔(フレーム)
MAX_INTERVAL = 360 # 次のつぶやきまでの最大間隔(フレーム)
# メッセージタイプの設定
# メッセージは '' で囲み、カンマで区切って必要な数だけ設定します
DATABASE = {}
DATABASE["少年"] = ['わーい!', '\C[2]動き\C[0]理解した?', '\N[1]さん!\Lこんにちは!']
DATABASE["盗賊"] = ['げへへへ', 'ひゃっはーー!!']
end
#==============================================================================
# ■ Game_Character
#==============================================================================
class Game_Character
#--------------------------------------------------------------------------
# ○ 現在のつぶやき内容を返す
#--------------------------------------------------------------------------
def mrbt
@mrbt
end
#--------------------------------------------------------------------------
# ○ つぶやきをセット
#--------------------------------------------------------------------------
def set_mrbt(text)
@mrbt = text
end
end
#==============================================================================
# ■ Game_Event
#==============================================================================
class Game_Event
#--------------------------------------------------------------------------
# ● イベントページの設定をセットアップ
#--------------------------------------------------------------------------
alias tmmrbt_game_event_setup_page_settings setup_page_settings
def setup_page_settings
tmmrbt_game_event_setup_page_settings
set_next_mrbt_count
@mrbt_type = /<mrbt\s+(\S+?)>/i =~ @event.name ? $1 : nil
if @list
@list.each do |list|
if list.code == 108 || list.code == 408
@mrbt_type = $1 if /<mrbt\s+(\S+?)>/i =~ list.parameters[0]
else
break
end
end
else
@mrbt = nil
end
end
#--------------------------------------------------------------------------
# ● フレーム更新
#--------------------------------------------------------------------------
def update
super
update_mrbt
end
#--------------------------------------------------------------------------
# ○ つぶやきの更新
#--------------------------------------------------------------------------
def update_mrbt
if @mrbt_count && @mrbt_count > 0
@mrbt_count -= 1
if @mrbt_count == 0
set_mrbt(get_random_mrbt)
set_next_mrbt_count
end
end
end
#--------------------------------------------------------------------------
# ○ ランダムつぶやきの内容取得
#--------------------------------------------------------------------------
def get_random_mrbt
return nil unless @mrbt_type && TMMRBT::DATABASE[@mrbt_type]
TMMRBT::DATABASE[@mrbt_type][rand(TMMRBT::DATABASE[@mrbt_type].size)].clone
end
#--------------------------------------------------------------------------
# ○ ランダムつぶやきの待機時間をセット
#--------------------------------------------------------------------------
def set_next_mrbt_count
n = rand([TMMRBT::MAX_INTERVAL - TMMRBT::MIN_INTERVAL, 1].max)
@mrbt_count = TMMRBT::MIN_INTERVAL + n
end
end
#==============================================================================
# ■ Game_Interpreter
#==============================================================================
class Game_Interpreter
#--------------------------------------------------------------------------
# ● 指定したIDのイベントにつぶやきを強制
#--------------------------------------------------------------------------
def mrbt(id, text)
event = $game_map.interpreter.get_character(id)
event.set_mrbt(text) if event
end
end
#==============================================================================
# ■ Sprite_Character
#==============================================================================
class Sprite_Character
#--------------------------------------------------------------------------
# ● オブジェクト初期化
# viewport : ビューポート
# character : キャラクター (Game_Character)
#--------------------------------------------------------------------------
alias tmmrbt_sprite_character_initialize initialize
def initialize(viewport, character = nil)
@bitmap_mrbt = Cache.system("mrbt_window")
@mrbt_duration = 0
tmmrbt_sprite_character_initialize(viewport, character)
end
#--------------------------------------------------------------------------
# ● 解放
#--------------------------------------------------------------------------
alias tmmrbt_sprite_character_dispose dispose
def dispose
dispose_mrbt
tmmrbt_sprite_character_dispose
end
#--------------------------------------------------------------------------
# ○ フキダシメッセージの解放
#--------------------------------------------------------------------------
def dispose_mrbt
if @mrbt_sprite
@mrbt_sprite.bitmap.dispose if @mrbt_sprite.bitmap
@mrbt_sprite.dispose
@mrbt_sprite = nil
end
end
#--------------------------------------------------------------------------
# ● その他の更新
#--------------------------------------------------------------------------
alias tmmrbt_sprite_character_update_other update_other
def update_other
tmmrbt_sprite_character_update_other
update_mrbt
end
#--------------------------------------------------------------------------
# ○ フキダシメッセージの更新
#--------------------------------------------------------------------------
def update_mrbt
if @mrbt_duration > 0
@mrbt_duration -= 1
if @mrbt_duration == 0
@character.set_mrbt(nil)
else
@mrbt_sprite.x = x
@mrbt_sprite.y = y - height
@mrbt_sprite.opacity = @mrbt_duration * 24
end
end
end
#--------------------------------------------------------------------------
# ● 新しいエフェクトの設定
#--------------------------------------------------------------------------
alias tmmrbt_sprite_character_setup_new_effect setup_new_effect
def setup_new_effect
tmmrbt_sprite_character_setup_new_effect
if @mrbt != @character.mrbt
@mrbt = @character.mrbt
start_mrbt(@mrbt)
end
end
#--------------------------------------------------------------------------
# ○ 文字色取得
# n : 文字色番号 (0~31)
#--------------------------------------------------------------------------
def text_color(n)
x = (n % 8) * 8
y = 32 + (n / 8) * 8
return @bitmap_mrbt.get_pixel(x, y)
end
#--------------------------------------------------------------------------
# ○ 特殊文字の変換
#--------------------------------------------------------------------------
def convert_special_characters(text)
text.gsub!(/\\/) { "\e" }
text.gsub!(/\e\e/) { "\\" }
text.gsub!(/\eV\[([0-9]+)\]/i) { $game_variables[$1.to_i] }
text.gsub!(/\eV\[([0-9]+)\]/i) { $game_variables[$1.to_i] }
text.gsub!(/\eN\[([0-9]+)\]/i) { actor_name($1.to_i) }
text.gsub!(/\eP\[(\d+)\]/i) { party_member_name($1.to_i) }
text.gsub!(/\eG/i) { Vocab::currency_unit }
text.gsub!(/\eL/i) { "\x00" }
text.gsub!(/\eC\[([0-9]+)\]/i) { "\x01[#{$1}]" }
text
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 start_mrbt(text)
dispose_mrbt
return unless text
@mrbt_duration = TMMRBT::MESSAGE_DURATION
text = convert_special_characters(text)
pos = {:x => 4, :y => 0, :width => 0, :line_height => TMMRBT::FONT_SIZE + 4}
bitmap = Bitmap.new(160, 160)
bitmap.font.size = TMMRBT::FONT_SIZE
loop do
c = text.slice!(/./m) # 次の文字を取得
case c
when nil
break # 描画すべき文字がなければ終了
when "\x00" # 改行
process_new_line(pos)
when "\x01" # \C[n] (文字色変更)
text.sub!(/\[([0-9]+)\]/, "")
bitmap.font.color = text_color($1.to_i)
else
bitmap.draw_text(pos[:x], pos[:y], 40, pos[:line_height], c)
c_width = bitmap.text_size(c).width
pos[:x] += c_width
process_new_line(pos) if pos[:x] >= 140 # 右端にきていれば改行
end
end
w = [pos[:x], pos[:width]].max + 4
h = pos[:y] + (pos[:x] == 4 ? 0 : pos[:line_height])
create_mrbt_sprite(w, h) # フキダシウィンドウのスプライトを作成
@mrbt_sprite.bitmap.blt(0, 0, bitmap, bitmap.rect)
bitmap.dispose
update_mrbt
end
#--------------------------------------------------------------------------
# ○ 改行の処理
#--------------------------------------------------------------------------
def process_new_line(pos)
pos[:width] = pos[:x] if pos[:width] < pos[:x]
pos[:x] = 4
pos[:y] += pos[:line_height]
end
#--------------------------------------------------------------------------
# ○ フキダシウィンドウのスプライトを作成
#--------------------------------------------------------------------------
def create_mrbt_sprite(width, height)
@mrbt_sprite = ::Sprite.new(nil)
@mrbt_sprite.z = 90
@mrbt_sprite.ox = width / 2
@mrbt_sprite.oy = height + 4
@mrbt_sprite.bitmap = Bitmap.new(width, height + 8)
rect = Rect.new(0, 0, 8, 8)
alpha = TMMRBT::BACK_OPACITY
@mrbt_sprite.bitmap.blt(0, 0, @bitmap_mrbt, rect, alpha)
rect.x += 8
@mrbt_sprite.bitmap.blt(width - 8, 0, @bitmap_mrbt, rect, alpha)
rect.y += 8
@mrbt_sprite.bitmap.blt(width - 8, height - 8, @bitmap_mrbt, rect, alpha)
rect.x -= 8
@mrbt_sprite.bitmap.blt(0, height - 8, @bitmap_mrbt, rect, alpha)
rect.set(16, 0, 8, 8)
@mrbt_sprite.bitmap.blt(@mrbt_sprite.ox - 4, height, @bitmap_mrbt, rect, alpha)
color = @bitmap_mrbt.get_pixel(8, 8)
color.alpha = alpha
@mrbt_sprite.bitmap.fill_rect(8, 0, width - 16, height, color)
@mrbt_sprite.bitmap.fill_rect(0, 8, 8, height - 16, color)
@mrbt_sprite.bitmap.fill_rect(width - 8, 8, 8, height - 16, color)
end
end