#===============================================================================
# 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
filename = $game_variables[$1.to_f.to_i].lstrip.rstrip if $1.to_f.to_i > 0
width = Cache.picture(filename).width
height = Cache.picture(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.picture(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