From 1cba1adf664550e543869065dfd499408dfcce26 Mon Sep 17 00:00:00 2001 From: Michael Shirt Date: Sat, 29 Oct 2016 18:44:06 -0600 Subject: [PATCH] Fixing bug with window prompts and adding credits message box The game would try to catch up in frames when a window prompt was opened, so if the window was open for 140 frames the game would process the next 140 frames instantly after the game was closed. To fix this, I have the window prompt time how long it's opened and then I tell the game to sleep for however many frames it was opened for. Credits message works but does not yet have all the desired features, will finish up later. --- scripts/Credits_Message.rb | 235 +++++++++++++++++++++++++++++++++++++ scripts/EdText.rb | 14 ++- scripts/Game_Temp.rb | 3 + scripts/Interpreter 3.rb | 18 ++- scripts/Scene_Map.rb | 11 +- scripts/_scripts.txt | 1 + 6 files changed, 277 insertions(+), 5 deletions(-) create mode 100644 scripts/Credits_Message.rb diff --git a/scripts/Credits_Message.rb b/scripts/Credits_Message.rb new file mode 100644 index 0000000..4045216 --- /dev/null +++ b/scripts/Credits_Message.rb @@ -0,0 +1,235 @@ +# Displays doc message boxes +class Credits_Message + + #-------------------------------------------------------------------------- + # * Object Initialization + #-------------------------------------------------------------------------- + def initialize + @timer = 0 + + @viewport = Viewport.new(0, 0, 640, 480) + @sprite_bg = Sprite.new(@viewport) + @sprite_bg.bitmap = Bitmap.new(640, 480) + if $game_switches[104] + @sprite_bg.bitmap.fill_rect(0, 0, 640, 480, Color.new(0, 0, 0, 255)) + else + @sprite_bg.bitmap.fill_rect(0, 0, 640, 480, Color.new(255, 255, 255, 255)) + end + @sprite_text = Sprite.new(@viewport) + @contents = Bitmap.new(320, 240) + @contents.font.size = 16 + @sprite_text.bitmap = @contents + @sprite_bg.z = 0 + @sprite_text.z = 1 + @sprite_text.zoom_x = @sprite_text.zoom_y = 2 + @viewport.z = 9999 + @viewport.visible = false + + @sprite_bg.opacity = 0 + @sprite_text.opacity = 0 + + # Animation flags + @fade_in = false + @fade_out = false + end + #-------------------------------------------------------------------------- + # * Dispose + #-------------------------------------------------------------------------- + def dispose + terminate_message + $game_temp.message_window_showing = false + @contents.dispose + #@sprite_bg.dispose + @sprite_text.dispose + @viewport.dispose + end + #-------------------------------------------------------------------------- + # * Terminate Message + #-------------------------------------------------------------------------- + def terminate_message + # Call message callback + if !@skip_message_proc && $game_temp.message_proc != nil + $game_temp.message_proc.call + $game_temp.message_proc = nil + end + $game_temp.message_credits_text = nil + end + #-------------------------------------------------------------------------- + # * Refresh: Load new message text and pre-process it + #-------------------------------------------------------------------------- + def refresh + + if $game_switches[104] + @sprite_bg.bitmap.fill_rect(0, 0, 640, 480, Color.new(0, 0, 0, 255)) + else + @sprite_bg.bitmap.fill_rect(0, 0, 640, 480, Color.new(255, 255, 255, 255)) + end + + # Initialize + @timer = 0 + text = '' + y = -1 + widths = [] + + # Pre-process text + text_raw = $game_temp.message_credits_text.to_str + + # Substitute variables, actors, player name, newlines, etc + text_raw.gsub!(/\\v\[([0-9]+)\]/) do + $game_variables[$1.to_i] + end + text_raw.gsub!(/\\n\[([0-9]+)\]/) do + $game_actors[$1.to_i] != nil ? $game_actors[$1.to_i].name : "" + end + text_raw.gsub!("\\p", $game_oneshot.player_name) + text_raw.gsub!("\\n", "\n") + # Handle text-rendering escape sequences + text_raw.gsub!(/\\c\[([0-9]+)\]/, "\000[\\1]") + # Finally convert the backslash back + text_raw.gsub!("\\\\", "\\") + + @contents.font.size = 16 + + # Now split text into lines by measuring text metrics + x = y = 0 + maxwidth = @contents.width - 8 + spacesize = @contents.text_size(' ') + for i in text_raw.split(/ /) + # Split each word around newlines + newline = false + for j in i.split("\n") + # Handle newline + if newline + text << "\n" + widths << x + x = 0 + y += 1 + @contents.font.size = 24 + else + newline = true + end + + # Get width of this word and see if it goes out of bounds + width = @contents.text_size(j.gsub(/\000\[[0-9]+\]/, '')).width + if x + width > maxwidth + text << "\n" + widths << x + x = 0 + y += 1 + @contents.font.size = 24 + end + + # Append word to list + if x == 0 + text << j + else + text << ' ' << j + end + x += width + spacesize.width + end + end + widths << x + + # Prepare renderer + @contents.clear + if $game_switches[104] + @contents.font.color = Color.new(255, 255, 255, 255) + else + @contents.font.color = Color.new(0, 0, 0, 255) + end + + x = (320 - widths[0]) / 2 + y = 0 + y_top = (240 - widths.length * 24) / 2 + + @contents.font.size = 16 + + + # Get 1 text character in c (loop until unable to get text) + while ((c = text.slice!(/./m)) != nil) + # \n + if c == "\n" + y += 1 + @contents.font.size = 24 + x = (320 - widths[y]) / 2 + next + end + # \c[n] + if c == "\000" + # Change text color + text.sub!(/\[([0-9]+)\]/, "") + color = $1.to_i + if color >= 0 and color <= 7 + @contents.font.color = Window_Base.text_color(color) + end + # go to next text + next + end + # Draw text + @contents.draw_text(x, y_top + (y * 24), 40, 18, c) + # Add x to drawn text width + x += @contents.text_size(c).width + end + Graphics.frame_reset + end + #-------------------------------------------------------------------------- + # * Frame Update + #-------------------------------------------------------------------------- + def update + # Handle fade-out effect + if @fade_out + @sprite_text.opacity -= 5 + @sprite_bg.opacity -= 5 + if @sprite_text.opacity <= 0 + @sprite_text.opacity = 0 + @sprite_bg.opacity = 0 + @fade_out = false + @viewport.visible = false + $game_temp.message_window_showing = false + end + return + end + + # Handle fade-in effect + if @fade_in + @sprite_text.opacity += 5 + @sprite_bg.opacity += 5 + if @sprite_text.opacity >= 255 + @sprite_text.opacity = 255 + @sprite_bg.opacity = 255 + @fade_in = false + $game_temp.message_window_showing = true + end + return + end + + # Message is over and should be hidden or advanced to next + if $game_temp.message_credits_text == nil + @fade_out = true if @viewport.visible + else + if !@viewport.visible + # Fade in + refresh + @viewport.visible = true + @fade_in = true + end + end + + if visible + @timer += 1 + if @timer >= 150 + terminate_message + @fade_out = true + end + end + end + #-------------------------------------------------------------------------- + # * Variables + #-------------------------------------------------------------------------- + def visible + @viewport.visible + end + def visible=(val) + @viewport.visible = val + end +end diff --git a/scripts/EdText.rb b/scripts/EdText.rb index 787d555..797163c 100644 --- a/scripts/EdText.rb +++ b/scripts/EdText.rb @@ -3,11 +3,23 @@ module EdText Oneshot.msgbox Oneshot::Msg::YESNO, tr("Do you understand what this means?") end def self.info(text) + timestart = Time.now text.gsub!("\\p", $game_oneshot.player_name) Oneshot.msgbox Oneshot::Msg::INFO, tr(text) + $game_temp.prompt_wait = ((Time.now - timestart) * 60).round end def self.yesno(text) + timestart = Time.now text.gsub!("\\p", $game_oneshot.player_name) - Oneshot.msgbox Oneshot::Msg::YESNO, tr(text) + result = Oneshot.msgbox Oneshot::Msg::YESNO, tr(text) + $game_temp.prompt_wait = ((Time.now - timestart) * 60).round + return result + end + def self.err(text) + timestart = Time.now + text.gsub!("\\p", $game_oneshot.player_name) + result = Oneshot.msgbox Oneshot::Msg::ERR, tr(text) + $game_temp.prompt_wait = ((Time.now - timestart) * 60).round + return result end end diff --git a/scripts/Game_Temp.rb b/scripts/Game_Temp.rb index f7d3aa5..c074a4e 100644 --- a/scripts/Game_Temp.rb +++ b/scripts/Game_Temp.rb @@ -19,6 +19,7 @@ class Game_Temp attr_accessor :message_ed_text # Ed message text attr_accessor :message_doc_text # Text message text attr_accessor :message_desktop_text # Desktop message text + attr_accessor :message_credits_text # Desktop message text attr_accessor :choices # show choices: text attr_accessor :choice_cancel_type # show choices: cancel attr_accessor :choice_proc # show choices: callback (Proc) @@ -61,6 +62,7 @@ class Game_Temp attr_accessor :debug_index # debug screen: for saving conditions attr_accessor :footstep_sfx # current footstep sfx array attr_accessor :filmsprite # film puzzle sprite + attr_accessor :prompt_wait # wait for delay caused by prompt #-------------------------------------------------------------------------- # * Object Initialization #-------------------------------------------------------------------------- @@ -116,6 +118,7 @@ class Game_Temp @debug_index = 0 @footstep_sfx = nil @filmsprite = nil + @prompt_wait = 0 end def bgm_fadein(game_system) diff --git a/scripts/Interpreter 3.rb b/scripts/Interpreter 3.rb index 2687e8d..b1e3647 100644 --- a/scripts/Interpreter 3.rb +++ b/scripts/Interpreter 3.rb @@ -11,7 +11,7 @@ class Interpreter #-------------------------------------------------------------------------- def command_101 # If other text has been set to message_text - if $game_temp.message_text != nil || $game_temp.message_ed_text != nil || $game_temp.message_doc_text != nil || $game_temp.message_desktop_text != nil + if $game_temp.message_text != nil || $game_temp.message_ed_text != nil || $game_temp.message_doc_text != nil || $game_temp.message_desktop_text != nil || $game_temp.message_credits_text != nil # End return false end @@ -22,6 +22,8 @@ class Interpreter if text.start_with?('$') is_doc = true text.slice!(0) + elsif text.start_with?('@credits') + is_credits = true else is_doc = false end @@ -30,13 +32,16 @@ class Interpreter if @list[@index+1].code == 401 @index += 1 text << " " << @list[@index].parameters[0].rstrip - elsif @list[@index+1].code == 101 && is_doc + elsif @list[@index+1].code == 101 && (is_doc || is_credits) # 101: Another message box # Tack on if we're a doc new_text = @list[@index+1].parameters[0].strip if new_text.start_with?('$') text << "\n\n" << new_text[1..-1] @index += 1 + elsif new_text.start_with?('@credits') + text << new_text[9..-1] + @index += 1 else break end @@ -71,12 +76,19 @@ class Interpreter if face == 'ed' is_desktop = false is_ed = true + is_credits = false elsif face == 'desktop' is_desktop = true is_ed = false + is_credits = false + elsif face == 'credits' + is_desktop = false + is_ed = false + is_credits = true else is_desktop = false is_ed = false + is_credits = false $game_temp.message_face = face end @@ -98,6 +110,8 @@ class Interpreter $game_temp.message_doc_text = text elsif is_desktop $game_temp.message_desktop_text = text + elsif is_credits + $game_temp.message_credits_text = text else $game_temp.message_text = text end diff --git a/scripts/Scene_Map.rb b/scripts/Scene_Map.rb index 9ae8eb5..580644d 100644 --- a/scripts/Scene_Map.rb +++ b/scripts/Scene_Map.rb @@ -16,6 +16,7 @@ class Scene_Map @ed_message = Ed_Message.new @doc_message = Doc_Message.new @desktop_message = Desktop_Message.new + @credits_message = Credits_Message.new # Make menus @menu = Window_MainMenu.new @item_menu = Window_Item.new @@ -70,6 +71,7 @@ class Scene_Map @ed_message.dispose @doc_message.dispose @desktop_message.dispose + @credits_message.dispose # Dispose of menu @menu.dispose @item_menu.dispose @@ -102,6 +104,10 @@ class Scene_Map end # Loop loop do + if $game_temp.prompt_wait > 0 + $game_temp.prompt_wait -= 1 + return + end $game_temp.bgm_fadein($game_system) # Update map, interpreter, and player order # (this update order is important for when conditions are fulfilled @@ -135,6 +141,7 @@ class Scene_Map @ed_message.update @doc_message.update @desktop_message.update + @credits_message.update # Deactivate item if Input.trigger?(Input::DEACTIVATE) && $game_variables[1] > 0 $game_system.se_play($data_system.cancel_se) @@ -142,7 +149,7 @@ class Scene_Map end # Update the menu - if @message_window.visible || @ed_message.visible || @doc_message.visible || @desktop_message.visible + if @message_window.visible || @ed_message.visible || @doc_message.visible || @desktop_message.visible || @credits_message.visible @item_menu_refresh = true else if @item_menu_refresh @@ -226,7 +233,7 @@ class Scene_Map # Update fast travel @fast_travel.update # If showing message window - if $game_temp.message_window_showing || @ed_message.visible || @doc_message.visible || @desktop_message.visible + if $game_temp.message_window_showing || @ed_message.visible || @doc_message.visible || @desktop_message.visible || @credits_message.visible return end # Process menu opening diff --git a/scripts/_scripts.txt b/scripts/_scripts.txt index 43e046f..55df880 100644 --- a/scripts/_scripts.txt +++ b/scripts/_scripts.txt @@ -121,6 +121,7 @@ SaveLoad Ed_Message Doc_Message Desktop_Message +Credits_Message Particles Demo