# ============================================================================= # TheoAllen - Message Ballon # Version : 1.0 # Contact : www.rpgmakerid.com (or) http://theolized.blogspot.com # (English Documentation) # ============================================================================= ($imported ||= {})[:Theo_MessageBallon] = true # ============================================================================= # CHANGE LOGS: # ----------------------------------------------------------------------------- # 2013.09.05 - Finished script # ============================================================================= =begin ------------------------------------------------------------------------ Introdurction : ------------------------------------------------------------------------ This script allow you to show the dialog inside ballon box right above character ------------------------------------------------------------------------ How to use : ------------------------------------------------------------------------ Put this script bellow material but above main Put the image for tail pointer box in Graphics/system. And don't forget to name it as "ballonpointer" Edit the configuration if necessary. And follow the script call rules ------------------------------------------------------------------------ Script Calls : ------------------------------------------------------------------------ - message.ballon Call this script to make message window shown as ballon message - message.normal Call this script to make window back to normal - message.subject = number Call this script to determine who is speak. Number is same as event ID. If you put 0, then the player will be the speaker. If the event ID didn't exist, then message will be back to usual message window. ------------------------------------------------------------------------ Terms of use : ------------------------------------------------------------------------ Credit me, TheoAllen. You are free to edit this script by your own. As long as you don't claim it yours. For commercial purpose, don't forget to give me a free copy of the game. =end # ============================================================================= # Configuration : # ============================================================================= module THEO module Msg Buffer_Y = 32 # Distance Y from sprite (default: 32) FontSize = 22 # Font size for ballon mode BackColor1 = Color.new(100,100,100,150) # Upper background color. Must be filled by : # Color.new(red,green,blue,alpha) BackColor2 = Color.new(0,0,0,150) # Lower background color. Must be filled by : # Color.new(red,green,blue,alpha) BorderColor = Color.new(0,0,0,255) # Border Color for ballon. Must be filled by : # Color.new(red,green,blue,alpha) BorderSize = 2 # Border size end end # ============================================================================= # End of configuration # ============================================================================= class Bitmap def border_fill(color,size = 1) fill_rect(0,0,width,size,color) fill_rect(0,0,size,height,color) fill_rect(width-size,0,size,height,color) fill_rect(0,height-size,width,size,color) end end class Game_Interpreter def message $game_message end end class Game_Message attr_accessor :ballon_refresh attr_accessor :subject attr_reader :type alias theo_msgballon_init initialize def initialize theo_msgballon_init @subject = 0 normal end def ballon @type = :ballon @ballon_refresh = true end def normal @type = :normal @ballon_refresh = true end def ballon? return false unless SceneManager.scene_is?(Scene_Map) @type == :ballon && @subject > -1 && !get_char.nil? end # ------------------------------------------------------- # Destruct escape character for length calculation # ------------------------------------------------------- def convert_escape_characters(text) result = text.to_s.clone result.gsub!(/\\/) { "\e" } result.gsub!(/\e\e/) { "\\" } result.gsub!(/\eV\[(\d+)\]/i) { $game_variables[$1.to_i] } 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!(/\eC\[(\d+)\]/i) { "" } # Destroy change color code result.gsub!(/\eI\[(\d+)\]/i) { " " } # Destroy draw icon result end def actor_name(n) actor = n >= 1 ? $game_actors[n] : nil actor ? actor.name : "" end def party_member_name(n) actor = n >= 1 ? $game_party.members[n - 1] : nil actor ? actor.name : "" end def longest_text test = Bitmap.new(1,1) test.font.size = THEO::Msg::FontSize txts = [] @texts.each do |txt| txts.push(convert_escape_characters(txt)) end longest = txts.sort do |a,b| test.text_size(b).width <=> test.text_size(a).width end[0] result = test.text_size(longest).width test.dispose return result end def get_char if @subject == 0 player = $game_player return Point.new(player.screen_x, player.screen_y) else event = $game_map.events[@subject] return nil unless event return Point.new(event.screen_x, event.screen_y) end end def total_text @texts.size end end class Point attr_accessor :x attr_accessor :y def initialize(x,y) @x, @y = x, y end end class BallonPointer < Sprite attr_reader :window attr_reader :pos def initialize(viewport,window) super(viewport) @window = window @pos = :upper self.bitmap = Cache.system("ballonpointer") to_center update end def pos=(pos) @pos = pos update_placement end def to_center self.ox = width/2 self.oy = height end def update super if window.ballon? self.visible = window.open? update_placement else self.visible = false end end def update_placement self.x = window.char.x if pos == :upper self.y = window.char.y - THEO::Msg::Buffer_Y - 2 self.angle = 0 else self.angle = 180 self.y = window.char.y end end end class Window_Message < Window_Base alias theo_msgballon_init initialize def initialize theo_msgballon_init @pointer = BallonPointer.new(viewport,self) end alias theo_msgballon_clear_instances clear_instance_variables def clear_instance_variables theo_msgballon_clear_instances @ballon = false @subject = -1 end alias theo_msgballon_settings_changed? settings_changed? def settings_changed? theo_msgballon_settings_changed? || ballon_setting_changed? end def ballon_setting_changed? @ballon != ballon? || @subject != $game_message.subject end def setup_window if ballon? setup_ballon else setup_normal end end def setup_normal h = fitting_height(visible_line_number) w = Graphics.width self.width = w self.height = h end def setup_ballon h = fitting_height($game_message.total_text) + 2 w = $game_message.longest_text + 10 + (standard_padding * 2) self.width = w self.height = h self.opacity = 0 end def ballon? $game_message.ballon? end alias theo_msgballon_update_bg update_background def update_background recreate_choice if @ballon != ballon? @ballon = ballon? @subject = $game_message.subject theo_msgballon_update_bg end alias theo_msgballon_normal_placement update_placement def update_placement setup_window theo_msgballon_normal_placement if ballon? update_ballon_placement else self.x = 0 end end def char $game_message.get_char end def update_ballon_placement xpos = [[char.x - width/2, - standard_padding].max, Graphics.width - width + standard_padding].min ypos = char.y - height - THEO::Msg::Buffer_Y @pointer.pos = :upper if ypos < 0 ypos = char.y - 2 @pointer.pos = :lower end self.x = xpos self.y = ypos end alias theo_msgballon_new_page new_page def new_page(text, pos) if ballon? return ballon_new_page(text, pos) end theo_msgballon_new_page(text, pos) end def ballon_new_page(text, pos) setup_ballon update_ballon_placement contents.clear entire_fill 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 alias theo_ballon_new_line_x new_line_x def new_line_x if ballon? return 4 else theo_ballon_new_line_x end end alias theo_msgballon_update update def update theo_msgballon_update @pointer.update update_ballon_placement if ballon? && !@opening && !@closing recreate_choice if $game_message.ballon_refresh end def recreate_choice @choice_window.dispose @choice_window = Window_ChoiceList.new(self) $game_message.ballon_refresh = false end def entire_fill contents.gradient_fill_rect(contents.rect,THEO::Msg::BackColor1, THEO::Msg::BackColor2,true) contents.border_fill(THEO::Msg::BorderColor,THEO::Msg::BorderSize) end alias theo_msgballon_width= width= def width=(width) self.theo_msgballon_width = width create_contents end alias theo_msgballon_height= height= def height=(height) self.theo_msgballon_height = height create_contents end alias theo_msgballon_line_height line_height def line_height if ballon? THEO::Msg::FontSize else theo_msgballon_line_height end end alias theo_msgballon_reset_font reset_font_settings def reset_font_settings theo_msgballon_reset_font contents.font.size = THEO::Msg::FontSize if ballon? end # ---------------------------------------------------------------- # Overwrite input pause ~ # ---------------------------------------------------------------- def input_pause self.pause = true unless ballon? wait(10) Fiber.yield until Input.trigger?(:B) || Input.trigger?(:C) Input.update self.pause = false unless ballon? end end class Window_ChoiceList < Window_Command alias theo_msgballon_start start def start reset_window theo_msgballon_start end def reset_window self.opacity = 255 end def setup_ballon self.opacity = 0 entire_fill end def entire_fill dispose_background @back_bitmap = Bitmap.new(contents.width,contents.height) @back_sprite = Sprite.new(viewport) @back_sprite.bitmap = @back_bitmap @back_sprite.x = x + standard_padding @back_sprite.y = y + standard_padding bmp = @back_sprite.bitmap bmp.gradient_fill_rect(contents.rect,THEO::Msg::BackColor1, THEO::Msg::BackColor2,true) bmp.border_fill(THEO::Msg::BorderColor,THEO::Msg::BorderSize) @back_sprite.visible = false end alias theo_msgballon_reset_font reset_font_settings def reset_font_settings theo_msgballon_reset_font contents.font.size = THEO::Msg::FontSize if @message_window.ballon? end alias theo_msgballon_draw_all draw_all_items def draw_all_items setup_ballon if @message_window.ballon? theo_msgballon_draw_all end alias theo_msgballon_update_placement update_placement def update_placement theo_msgballon_update_placement if @message_window.ballon? update_ballon_placement end end def update_ballon_placement msg = @message_window self.y = msg.y self.x = msg.x + msg.width - standard_padding * 2 if (x + width) > Graphics.width self.x = msg.x - width + standard_padding * 2 end end alias theo_msgballon_line_height line_height def line_height if @message_window.ballon? THEO::Msg::FontSize else theo_msgballon_line_height end end def dispose_background @back_bitmap.dispose if @back_bitmap @back_sprite.dispose if @back_sprite end alias theo_msgballon_close close def close dispose_background theo_msgballon_close end alias theo_msgballon_update update def update theo_msgballon_update @back_sprite.visible = open? if @back_sprite && !@back_sprite.disposed? end end