sacred-ritual-academy/Scripts/Window_Message.rb
2025-03-18 19:45:34 -05:00

396 lines
15 KiB
Ruby
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#==============================================================================
# ■ Window_Message
#------------------------------------------------------------------------------
#  文章表示に使うメッセージウィンドウです。
#==============================================================================
class Window_Message < Window_Base
#--------------------------------------------------------------------------
# ● オブジェクト初期化
#--------------------------------------------------------------------------
def initialize
super(0, 0, window_width, window_height)
self.z = 200
self.openness = 0
create_all_windows
create_back_bitmap
create_back_sprite
clear_instance_variables
end
#--------------------------------------------------------------------------
# ● ウィンドウ幅の取得
#--------------------------------------------------------------------------
def window_width
Graphics.width
end
#--------------------------------------------------------------------------
# ● ウィンドウ高さの取得
#--------------------------------------------------------------------------
def window_height
fitting_height(visible_line_number)
end
#--------------------------------------------------------------------------
# ● インスタンス変数のクリア
#--------------------------------------------------------------------------
def clear_instance_variables
@fiber = nil # ファイバー
@background = 0 # 背景タイプ
@position = 2 # 表示位置
clear_flags
end
#--------------------------------------------------------------------------
# ● フラグのクリア
#--------------------------------------------------------------------------
def clear_flags
@show_fast = false # 早送りフラグ
@line_show_fast = false # 行単位早送りフラグ
@pause_skip = false # 入力待ち省略フラグ
end
#--------------------------------------------------------------------------
# ● 表示行数の取得
#--------------------------------------------------------------------------
def visible_line_number
return 4
end
#--------------------------------------------------------------------------
# ● 解放
#--------------------------------------------------------------------------
def dispose
super
dispose_all_windows
dispose_back_bitmap
dispose_back_sprite
end
#--------------------------------------------------------------------------
# ● フレーム更新
#--------------------------------------------------------------------------
def update
super
update_all_windows
update_back_sprite
update_fiber
end
#--------------------------------------------------------------------------
# ● ファイバーの更新
#--------------------------------------------------------------------------
def update_fiber
if @fiber
@fiber.resume
elsif $game_message.busy? && !$game_message.scroll_mode
@fiber = Fiber.new { fiber_main }
@fiber.resume
else
$game_message.visible = false
end
end
#--------------------------------------------------------------------------
# ● 全ウィンドウの作成
#--------------------------------------------------------------------------
def create_all_windows
@gold_window = Window_Gold.new
@gold_window.x = Graphics.width - @gold_window.width
@gold_window.y = 0
@gold_window.openness = 0
@choice_window = Window_ChoiceList.new(self)
@number_window = Window_NumberInput.new(self)
@item_window = Window_KeyItem.new(self)
end
#--------------------------------------------------------------------------
# ● 背景ビットマップの作成
#--------------------------------------------------------------------------
def create_back_bitmap
@back_bitmap = Bitmap.new(width, height)
rect1 = Rect.new(0, 0, width, 12)
rect2 = Rect.new(0, 12, width, height - 24)
rect3 = Rect.new(0, height - 12, width, 12)
@back_bitmap.gradient_fill_rect(rect1, back_color2, back_color1, true)
@back_bitmap.fill_rect(rect2, back_color1)
@back_bitmap.gradient_fill_rect(rect3, back_color1, back_color2, true)
end
#--------------------------------------------------------------------------
# ● 背景色 1 の取得
#--------------------------------------------------------------------------
def back_color1
Color.new(0, 0, 0, 100)#背景濃さもとは160
end
#--------------------------------------------------------------------------
# ● 背景色 2 の取得
#--------------------------------------------------------------------------
def back_color2
Color.new(0, 0, 0, 0)
end
#--------------------------------------------------------------------------
# ● 背景スプライトの作成
#--------------------------------------------------------------------------
def create_back_sprite
@back_sprite = Sprite.new
@back_sprite.bitmap = @back_bitmap
@back_sprite.visible = false
@back_sprite.z = z - 1
end
#--------------------------------------------------------------------------
# ● 全ウィンドウの解放
#--------------------------------------------------------------------------
def dispose_all_windows
@gold_window.dispose
@choice_window.dispose
@number_window.dispose
@item_window.dispose
end
#--------------------------------------------------------------------------
# ● 背景ビットマップの解放
#--------------------------------------------------------------------------
def dispose_back_bitmap
@back_bitmap.dispose
end
#--------------------------------------------------------------------------
# ● 背景スプライトの解放
#--------------------------------------------------------------------------
def dispose_back_sprite
@back_sprite.dispose
end
#--------------------------------------------------------------------------
# ● 全ウィンドウの更新
#--------------------------------------------------------------------------
def update_all_windows
@gold_window.update
@choice_window.update
@number_window.update
@item_window.update
end
#--------------------------------------------------------------------------
# ● 背景スプライトの更新
#--------------------------------------------------------------------------
def update_back_sprite
@back_sprite.visible = (@background == 1)
@back_sprite.y = y
@back_sprite.opacity = openness
@back_sprite.update
end
#--------------------------------------------------------------------------
# ● ファイバーのメイン処理
#--------------------------------------------------------------------------
def fiber_main
$game_message.visible = true
update_background
update_placement
loop do
process_all_text if $game_message.has_text?
process_input
$game_message.clear
@gold_window.close
Fiber.yield
break unless text_continue?
end
close_and_wait
$game_message.visible = false
@fiber = nil
end
#--------------------------------------------------------------------------
# ● ウィンドウ背景の更新
#--------------------------------------------------------------------------
def update_background
@background = $game_message.background
self.opacity = @background == 0 ? 255 : 0
end
#--------------------------------------------------------------------------
# ● ウィンドウ位置の更新
#--------------------------------------------------------------------------
def update_placement
@position = $game_message.position
self.y = @position * (Graphics.height - height) / 2
@gold_window.y = y > 0 ? 0 : Graphics.height - @gold_window.height
end
#--------------------------------------------------------------------------
# ● 全テキストの処理
#--------------------------------------------------------------------------
def process_all_text
open_and_wait
text = convert_escape_characters($game_message.all_text)
pos = {}
new_page(text, pos)
process_character(text.slice!(0, 1), text, pos) until text.empty?
end
#--------------------------------------------------------------------------
# ● 入力処理
#--------------------------------------------------------------------------
def process_input
if $game_message.choice?
input_choice
elsif $game_message.num_input?
input_number
elsif $game_message.item_choice?
input_item
else
input_pause unless @pause_skip
end
end
#--------------------------------------------------------------------------
# ● ウィンドウを開き、完全に開くまで待つ
#--------------------------------------------------------------------------
def open_and_wait
open
Fiber.yield until open?
end
#--------------------------------------------------------------------------
# ● ウィンドウを閉じ、完全に閉じるまで待つ
#--------------------------------------------------------------------------
def close_and_wait
close
Fiber.yield until all_close?
end
#--------------------------------------------------------------------------
# ● 全ウィンドウが完全に閉じているか判定
#--------------------------------------------------------------------------
def all_close?
close? && @choice_window.close? &&
@number_window.close? && @item_window.close?
end
#--------------------------------------------------------------------------
# ● 文章を続けて表示するか判定
#--------------------------------------------------------------------------
def text_continue?
$game_message.has_text? && !settings_changed?
end
#--------------------------------------------------------------------------
# ● 背景と位置の変更判定
#--------------------------------------------------------------------------
def settings_changed?
@background != $game_message.background ||
@position != $game_message.position
end
#--------------------------------------------------------------------------
# ● ウェイト
#--------------------------------------------------------------------------
def wait(duration)
duration.times { Fiber.yield }
end
#--------------------------------------------------------------------------
# ● 早送りフラグの更新
#--------------------------------------------------------------------------
def update_show_fast
@show_fast = true if Input.trigger?(:C)
end
#--------------------------------------------------------------------------
# ● 一文字出力後のウェイト
#--------------------------------------------------------------------------
def wait_for_one_character
update_show_fast
Fiber.yield unless @show_fast || @line_show_fast
end
#--------------------------------------------------------------------------
# ● 改ページ処理
#--------------------------------------------------------------------------
def new_page(text, pos)
contents.clear
draw_face($game_message.face_name, $game_message.face_index, 0, 0)
reset_font_settings
pos[:x] = new_line_x
pos[:y] = 0
pos[:new_x] = new_line_x
pos[:height] = calc_line_height(text)
clear_flags
end
#--------------------------------------------------------------------------
# ● 改行位置の取得
#--------------------------------------------------------------------------
def new_line_x
$game_message.face_name.empty? ? 0 : 112
end
#--------------------------------------------------------------------------
# ● 通常文字の処理
#--------------------------------------------------------------------------
def process_normal_character(c, pos)
super
wait_for_one_character
end
#--------------------------------------------------------------------------
# ● 改行文字の処理
#--------------------------------------------------------------------------
def process_new_line(text, pos)
@line_show_fast = false
super
if need_new_page?(text, pos)
input_pause
new_page(text, pos)
end
end
#--------------------------------------------------------------------------
# ● 改ページが必要か判定
#--------------------------------------------------------------------------
def need_new_page?(text, pos)
pos[:y] + pos[:height] > contents.height && !text.empty?
end
#--------------------------------------------------------------------------
# ● 改ページ文字の処理
#--------------------------------------------------------------------------
def process_new_page(text, pos)
text.slice!(/^\n/)
input_pause
new_page(text, pos)
end
#--------------------------------------------------------------------------
# ● 制御文字によるアイコン描画の処理
#--------------------------------------------------------------------------
def process_draw_icon(icon_index, pos)
super
wait_for_one_character
end
#--------------------------------------------------------------------------
# ● 制御文字の処理
# code : 制御文字の本体部分(「\C[1]」なら「C」
# text : 描画処理中の文字列バッファ(必要なら破壊的に変更)
# pos : 描画位置 {:x, :y, :new_x, :height}
#--------------------------------------------------------------------------
def process_escape_character(code, text, pos)
case code.upcase
when '$'
@gold_window.open
when '.'
wait(15)
when '|'
wait(60)
when '!'
input_pause
when '>'
@line_show_fast = true
when '<'
@line_show_fast = false
when '^'
@pause_skip = true
else
super
end
end
#--------------------------------------------------------------------------
# ● 入力待ち処理
#--------------------------------------------------------------------------
def input_pause
self.pause = true
wait(10)
Fiber.yield until Input.trigger?(:B) || Input.trigger?(:C)
Input.update
self.pause = false
end
#--------------------------------------------------------------------------
# ● 選択肢の入力処理
#--------------------------------------------------------------------------
def input_choice
@choice_window.start
Fiber.yield while @choice_window.active
end
#--------------------------------------------------------------------------
# ● 数値の入力処理
#--------------------------------------------------------------------------
def input_number
@number_window.start
Fiber.yield while @number_window.active
end
#--------------------------------------------------------------------------
# ● アイテムの選択処理
#--------------------------------------------------------------------------
def input_item
@item_window.start
Fiber.yield while @item_window.active
end
end