#=============================================================================== # Zetu Engine V: Choices Extention # by Zetu # --- Created: 12/30/2014 # --- Updated: 01/06/2015 v1.02 #------------------------------------------------------------------------------- # Instructions: Place special commands inside Display Choices. # [mode=?] # Option: H # Displays choices horizontally # Option: C # Centers choice display # Option: X # Shows no back window while displayed # Option: F # Fixes location of first selection # Option: U, Adds F, H, C # Centers options on item, rather than window # Option: R, Ignores H, U # Counts as X. Display choices in a circular fasion. # [img=?] # Displays an image with the specified filename as an option. Option: I # [switch=?] # Only shows if specified switch ID is ON. #------------------------------------------------------------------------------- # Changelog: # v1.01 # * Fixed bug causing normal text to not adapt window size. # < Reported by ArbitraryGuy > # v1.02 # + Added [icon=?] # + Added [switch=?] # + Added F mode option. # + Added U mode option. # + Added Feature to combine Choice Box Dialogs. #=============================================================================== class Window_Command < Window_Selectable #============================================================================= # Create Objects #----------------------------------------------------------------------------- alias :zev_choice_add_command :add_command def add_command(name, symbol, enabled = true, ext = nil) command = name.dup if command =~ /\[mode\=(.+?)\]/i modes = $1.lstrip.rstrip.upcase modes.split(//).each do |m| @modes |= [m] case m when "U" @modes |= ["H", "C", "F"] end end command.gsub!(/\[mode\=.+?\]/i, "") end if name =~ /\[img\=(.+?)\]/i @modes |= ["I"] filename = $1.lstrip.rstrip width = Cache.system(filename).width height = Cache.system(filename).height @list.push({:name=>command, :symbol=>symbol, :enabled=>enabled, :ext=>ext, :zev_ext=>:image, :filename=>filename, :width=>width, :height=>height}) else zev_choice_add_command(command, symbol, enabled, ext) end end #============================================================================= # Clear #----------------------------------------------------------------------------- alias :zev_stabs_clear_command_list :clear_command_list def clear_command_list @modes = [] zev_stabs_clear_command_list end #============================================================================= # Conditions #----------------------------------------------------------------------------- def mode_include?(s) return false unless @modes return true if @modes.include?(s) return false end end class Window_ChoiceList < Window_Command alias :zev_sbp_start :start def start zev_sbp_start update_placement select(0) end #============================================================================= # Update #----------------------------------------------------------------------------- def update super update_xy(self.index) end def update_placement update_size update_xy self.opacity = mode_include?("X") ? 0 : 255 end def update_size self.width = contents_width + padding * 2 self.height = contents_height + padding * 2 end def update_xy(index = 0) self.x = Graphics.width - width if @message_window.y >= Graphics.height / 2 self.y = @message_window.y - height else if mode_include?("C") self.y = Graphics.height + @message_window.y + @message_window.height - self.height else self.y = @message_window.y + @message_window.height end end if mode_include?("C") self.x /= 2 self.y /= 2 end if mode_include?("U") self.x = (Graphics.width - item_rect(index).width) / 2 end if mode_include?("F") if mode_include?("H") self.x -= get_special_x(index) else self.y -= get_special_y(index) end end end def update_padding_bottom if mode_include?("I") self.padding_bottom = 0 else super end end def ensure_cursor_visible unless mode_include?("R") super end end #============================================================================= # Object Calls #----------------------------------------------------------------------------- def call_cancel_handler $game_message.choice_cancel_proc.call($game_message.choice_cancel_type - 1) close end #============================================================================= # Conditions #----------------------------------------------------------------------------- def cancel_enabled? $game_message.choice_cancel_data != nil end #============================================================================= # Reference Objects #----------------------------------------------------------------------------- def contents_width if mode_include?("H") return sp_global_width elsif mode_include?("R") return 3 * sp_item_width(24) else return sp_item_width end end def contents_height if mode_include?("H") return sp_item_height elsif mode_include?("R") return 3 * sp_item_height(24) else return sp_global_height end end def sp_text_size(string) return Rect.new(0,0,0,0) if string.nil? bitmap = Bitmap.new(1,1) w = 8 string = string.gsub(/\\i\[\d+?\]/i) do |s| w += 24 "" end string = string.gsub(/\[mode\=.+?\]/i, "") rect = bitmap.text_size(string) rect.width += w bitmap.dispose rect end def sp_item_width(min = 96) @list.each.with_index.inject(0) { |sum, (hash,i)| [sum, (hash[:width] || [min, sp_text_size($game_message.choices[i]).width].max)].max } end def sp_item_height(min = line_height) @list.inject(0) { |sum, hash| [sum, (hash[:height] || [min,line_height].max)].max } || 0 end def sp_global_width(min = 96) @list.each.with_index.inject(0) { |sum, (hash,i)| sum+(hash[:width]|| [min, sp_text_size($game_message.choices[i]).width].max) } end def sp_global_height(min = line_height) @list.inject(0) { |sum, hash| sum + (hash[:height] || [min,line_height].max) } || 0 end def item_rect(index) data = @list[index]||{} rect = Rect.new if mode_include?("R") rect.width = sp_item_width(24) rect.height = sp_item_height(24) r = index.to_f / item_max r *= 2 * Math.acos(-1) rect.x = Math.cos(r) * sp_item_width(24) + self.contents.width / 2 rect.x -= sp_item_width(24) / 2 #rect.y = Math.sin(r) * line_height + sp_item_height(24) rect.y = Math.sin(r) * sp_item_height(24) + self.contents.height / 2 rect.y -= sp_item_height(24) / 2 elsif mode_include?("H") rect.width = data[:width] || 96 rect.height = contents_height rect.x = get_special_x(index) rect.y = 0 else rect.width = contents_width rect.height = data[:height] || item_height rect.x = 0 rect.y = get_special_y(index) end rect end def get_special_x(index) @list[0...index].inject(0) do |sum, hash| sum + (hash[:width] || 96) end || 0 end def get_special_y(index) @list[0...index].inject(0) do |sum, hash| sum + (hash[:height] || line_height) end || 0 end def col_max return @list.size if mode_include?("H") return super end def row_max return 1 if mode_include?("H") return super end def alignment return 1 if mode_include?("R") return 0 end #============================================================================= # Drawing #----------------------------------------------------------------------------- alias :zev_choice_draw_item :draw_item def draw_item(index) data = @list[index] case data[:zev_ext] when nil zev_choice_draw_item(index) when :image bitmap = Cache.system(data[:filename]) irect = item_rect(index) brect = Rect.new(0,0,data[:width],data[:height]) contents.blt(irect.x, irect.y, bitmap, brect) end end end class Game_Message attr_accessor :choice_data attr_accessor :choice_cancel_data attr_accessor :choice_cancel_proc end class Game_Interpreter alias :zev_choice_clear :clear def clear zev_choice_clear @choice_skip = {} end def add_zev_special_choice_data(ti) choice_data = {} @list[ti].parameters[0].each_with_index do |c, i| name = c.dup if name =~ /\[switch\=(\d+?)\]/i next unless $game_switches[$1.to_i] name.gsub!(/\[switch\=\d+?\]/i, "") end choice_data[i] = name end s_index = $game_message.choices.size skip = $game_message.choice_data.size choice_data.values.each {|s| $game_message.choices.push(s) } $game_message.choice_data << { :si => s_index, :skip => skip, :choice_data => choice_data.keys } if @list[ti].parameters[1] != 0 $game_message.choice_cancel_data = { :skip => skip, :n => @list[ti].parameters[1] - 1 } end end alias :zev_choice_setup_choices :setup_choices def setup_choices(params) $game_message.choice_data = [] $game_message.choice_cancel_data = nil add_zev_special_choice_data(@index) ti = @index while @list[ti] and @list[ti].code == 102 ti += 1 ti += 1 while @list[ti].indent > @indent or [402,403,404].include? @list[ti].code break if @list[ti].code != 102 add_zev_special_choice_data(ti) end $game_message.choice_proc = Proc.new {|n| data = $game_message.choice_data.select do |h| h[:si] <= n end.max_by do |h| h[:si] end @choice_skip[@indent] = data[:skip] @branch[@indent] = data[:choice_data][n - data[:si]] } $game_message.choice_cancel_proc = Proc.new{|n| data = $game_message.choice_cancel_data @choice_skip[@indent] = data[:skip] @branch[@indent] = data[:n] } end alias :zev_choice_command_102 :command_102 def command_102 return if @list[@index - 1].code == 404 if @list[@index - 1] zev_choice_command_102 end def command_402 command_skip if @branch[@indent] != @params[0] or @choice_skip[@indent] != 0 end def command_403 command_skip if @branch[@indent] != 4 or @choice_skip[@indent] != 0 end def command_404 @choice_skip[@indent] -= 1 if @choice_skip[@indent] end end