modern_algebra

ATS: Choice Options 1.0.0

Jan 27th, 2013
3,159
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #==============================================================================
  2. #    ATS: Choice Options [VXA]
  3. #    Version: 1.0.0
  4. #    Author: modern algebra (rmrk.net)
  5. #    Date: 27 January 2013
  6. #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  7. #  Description:
  8. #
  9. #    This script improves your control over the choice box by permitting more
  10. #   than four choices in a box, each of which you can disable or remove
  11. #   contingent on the value of any given switch. Additionally, it also allows
  12. #   you to extend the length of the choice beyond the editor's spacial
  13. #   limitations, allowing you to have long choices, and it adds an option for a
  14. #   help window to assist in describing the choices. Aside from that dynamic
  15. #   control over multiple choice branches, you are also permitted to set the
  16. #   number of columns in the choice box, its size, and its position. There are
  17. #   other more minor features as well, which you can learn about in the
  18. #   instructions.
  19. #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  20. #  ATS Series:
  21. #
  22. #    This script is part of the Advanced Text System series of scripts. These
  23. #   scripts are based off the Advanced Text System for RMVX, but since RMVX Ace
  24. #   has a much more sensibly designed message system, it is no longer necessary
  25. #   that it be one large script. For that reason, and responding to feedback on
  26. #   the ATS, I have split the ATS into multiple different scripts so that you
  27. #   only need to pick up the components for the features that you want. It is
  28. #   therefore easier to customize and configure.
  29. #
  30. #    To find more scripts in the ATS Series, please visit:
  31. #      http://rmrk.net/index.php/topic,44525.0.html
  32. #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  33. #  Instructions:
  34. #
  35. #    There are a lot of configuration options in this script, and I direct you
  36. #   to the Editable Region at line 102 for detailed comments on what each does
  37. #   Here, I will just list them:
  38. #
  39. #          :append_choices                    :choice_column_num
  40. #          :choice_spacing                    :choice_win_padding
  41. #          :choice_win_x                      :choice_win_y
  42. #          :choice_win_x_offset               :choice_win_y_offset
  43. #          :choice_win_width                  :choice_win_height
  44. #          :choice_help_win_lines             :choice_format
  45. #          :choice_disabled_opacity
  46. #
  47. #    As with other ATS scripts, you can change the value of these options in
  48. #   game with the following codes in a script call:
  49. #
  50. #      ats_next(:message_option, x)
  51. #      ats_all(:message_option, x)
  52. #
  53. #   Where :message_option is the symbol you want and x is the value you want
  54. #   to change it to. ats_next will only change it for the very next message,
  55. #   while ats_all will change it for every message to follow.
  56. #
  57. #    If any of the values are set to an incorrect value, you will get a popup
  58. #   telling you at the start of the game if you are test playing. If you are
  59. #   running the actual game, however, the popup will not occur, and neither
  60. #   will it occur if you pass a wrong value to the options through the ats_all
  61. #   or ats_next commands.
  62. #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  63. #  List of Special Message Codes:
  64. #
  65. #    The following is a complete list of the message codes at your disposal.
  66. #   Simply insert them into a choice text (or a comment, if specified).
  67. #
  68. # \a[L] - Aligns the text to the left for this choice. Can also use \a[0].
  69. # \a[C] - Aligns the text to the centre for this choice. Can also use \a[1].
  70. # \a[R] - Aligns the text to the right for this choice. Can also use \a[2].
  71. # \s[n] - Will only draw choice if the switch with ID n is ON.
  72. # \s![n] - Will only draw choice if the switch with ID n is OFF.
  73. # \d[n] - Will disable choice if the switch with ID n is ON.
  74. # \d![n] - Will disable choice if the switch with ID n is OFF.
  75. #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  76. #  Comment Codes:
  77. #
  78. # \+{text} - This code must be placed in a comment directly below a choice
  79. #     branch, and it will add the content of text to the choice.
  80. # \h{text} - This code must be placed in a comment directly below a choice
  81. #     branch, and it will define the help text for that choice. If no help text
  82. #     is set for any choice, then the help window will not show up.
  83. #==============================================================================
  84.  
  85. $imported = {} unless $imported
  86. $imported[:ATS_ChoiceOptions] = true
  87.  
  88. #==============================================================================
  89. # ** Game_ATS
  90. #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  91. #  Summary of Changes:
  92. #    new public instance variables - append_choices; choice_column_num;
  93. #      choice_spacing; choice_win_padding; choice_win_x; choice_win_x_offset;
  94. #      choice_win_y; choice_win_y_offset; choice_win_width; choice_win_height;
  95. #      choice_help_win_lines; choice_format
  96. #==============================================================================
  97.  
  98. class Game_ATS
  99.   CONFIG ||= {}
  100.   CONFIG[:ats_choice_options] = {
  101.       ats_choice_options: true,
  102.     #\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  103.     #  EDITABLE REGION
  104.       #||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  105.     #  :append_choices - If true, subsequent choice commands in an event will
  106.     # be joined together into one large choice box. If false, they won't be.
  107.     append_choices:         true,
  108.     #  :choice_column_num - The number of columns in a choice box
  109.     choice_column_num:      1,
  110.     #  :choice_spacing - If :choice_column_num is greater than one, this is
  111.     # the number of pixels between columns
  112.     choice_spacing:         8,
  113.     #  :choice_win_padding - This determines the size of the choice window's
  114.     # border. The default for most other windows is 12.
  115.     choice_win_padding:     12,
  116.     #  :choice_win_x - This controls the horizontal position of the choice
  117.     # window. It can be set to either :L, :R, :C, or an integer. If an integer,
  118.     # then it is set directly to that x-coordinate. If :L, it is flush with the
  119.     # left side of the message window. If :C, it is in the centre of the
  120.     # message window. If :R, it is flush with the right side of the message
  121.     # window.
  122.     choice_win_x:           :R,
  123.     #  :choice_win_x_offset - This is the number of pixels offset when
  124.     # :choice_win_x is set to :L or :R. When :L, it is added. When :R, it is
  125.     # subtracted.
  126.     choice_win_x_offset:    0,
  127.     #  :choice_win_y - This controls the vertical position of the choice window.
  128.     # It can be set to either :T, :B, or an integer. If an integer, then it is
  129.     # set directly to that y-coordinate. If :T, it is flush with the top of the
  130.     # message window. If :B, it is flush with the bottom of the message window.
  131.     choice_win_y:           :T,
  132.     #  :choice_win_y_offset - This is the number of pixels offset when
  133.     # :choice_win_y is set to :T or :B. When :T, it is added. When :B, it is
  134.     # subtracted.
  135.     choice_win_y_offset:    0,
  136.     #  :choice_win_width - This is the width of the choice window. When it is
  137.     # a range ( a..b ), then the window will be at least a pixels wide and at
  138.     # most b pixels wide, but it will otherwise try to match the size of the
  139.     # longest choice. If you want to set the width directly, just use a single
  140.     # integer here, not a range.
  141.     choice_win_width:       96..Graphics.width,
  142.     #  :choice_win_height - This is the height of the choice window. When it is
  143.     # a range ( a..b ), then the window will be at least a pixels high and at
  144.     # most b pixels high, but it will otherwise try to match the total number
  145.     # of rows in the choice window. If you want to set the height directly,
  146.     # just use a single integer here, not a range.
  147.     choice_win_height:      48..120,
  148.     #  :choice_help_win_lines - Number of lines that can fit in the help window
  149.     choice_help_win_lines:  1,
  150.     #  :choice_format - This allows you to set a format into which all choices
  151.     # will be forced. It can be useful if you want all choices to be a specific
  152.     # colour, or if you want all choices to be indented, but do not want to
  153.     # repeat the codes or spaces in every choice. Basically, it is a string,
  154.     # and somewhere in the string there needs to be %s. That is what will be
  155.     # replaced by the actual choice text. EXAMPLES: If this is '\c[4]%s\c[0]',
  156.     # and you had a choice: 'Yes', then it would be as if you input into the
  157.     # choice box the text: '\c[4]Yes\c[0]'
  158.     choice_format:          '%s',
  159.     #  :choice_disabled_opacity - This sets the opacity of disabled choices.
  160.     # It is an integer between 0 (fully transparent) and 255 (fully opaque)
  161.     choice_disabled_opacity: 128
  162.       #||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  163.     #  END EDITABLE REGION
  164.     #////////////////////////////////////////////////////////////////////////
  165.   }
  166.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  167.   # * Public Instance Variables
  168.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  169.   CONFIG[:ats_choice_options].keys.each { |key| attr_accessor key }
  170. end
  171.  
  172. #==============================================================================
  173. #  Initialize Common ATS Data if no other ATS script interpreted first
  174. #==============================================================================
  175.  
  176. if !$imported[:AdvancedTextSystem]
  177.   #============================================================================
  178.   # *** DataManager
  179.   #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  180.   #  Summary of Changes:
  181.   #    aliased method - create_game_objects; make_save_contents;
  182.   #      extract_save_contents
  183.   #============================================================================
  184.   module DataManager
  185.     class << self
  186.       alias modb_ats_crtgmobj_6yh7 create_game_objects
  187.       alias mlba_ats_mksave_5tg9 make_save_contents
  188.       alias ma_ats_extrcsvcon_8uj2 extract_save_contents
  189.     end
  190.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  191.     # * Create Game Objects
  192.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  193.     def self.create_game_objects(*args, &block)
  194.       modb_ats_crtgmobj_6yh7(*args, &block)
  195.       $game_ats = Game_ATS.new
  196.       $game_ats.init_new_installs
  197.     end
  198.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  199.     # * Make Save Contents
  200.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  201.     def self.make_save_contents(*args, &block)
  202.       contents = mlba_ats_mksave_5tg9(*args, &block)
  203.       contents[:ats] = $game_ats
  204.       contents
  205.     end
  206.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  207.     # * Extract Save Contents
  208.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  209.     def self.extract_save_contents(contents, *args, &block)
  210.       ma_ats_extrcsvcon_8uj2(contents, *args, &block)
  211.       $game_ats = contents[:ats] ? contents[:ats] : Game_ATS.new
  212.       $game_ats.init_new_installs
  213.     end
  214.   end
  215.  
  216.   #============================================================================
  217.   # ** Game_ATS
  218.   #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  219.   #  This class holds the default data for all scripts in the ATS series
  220.   #============================================================================
  221.  
  222.   class Game_ATS
  223.     def initialize; reset; end
  224.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  225.     # * Reset any or all installed ATS scripts
  226.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  227.     def reset(script_name = nil)
  228.       if script_name.is_a? (Symbol) # If script to reset specified
  229.         CONFIG[script_name].each_pair { |key, value|
  230.           self.send("#{key}=".to_sym, value)
  231.           $game_message.send("#{key}=".to_sym, value)
  232.         }
  233.       else                          # Reset all ATS scripts
  234.         CONFIG.keys.each { |script| reset(script) }
  235.       end
  236.     end
  237.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  238.     # * Initialize any newly installed ATS scripts
  239.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  240.     def init_new_installs
  241.       CONFIG.keys.each { |script| reset(script) unless self.send(script) }
  242.     end
  243.   end
  244.  
  245.   #============================================================================
  246.   # ** Game_Message
  247.   #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  248.   #  Summary of Changes:
  249.   #    aliased method - clear
  250.   #============================================================================
  251.  
  252.   class Game_Message
  253.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  254.     # * Clear
  255.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  256.     alias mlb_ats_clrats_5tv1 clear
  257.     def clear(*args, &block)
  258.       mlb_ats_clrats_5tv1(*args, &block) # Run Original Method
  259.       return if !$game_ats
  260.       Game_ATS::CONFIG.values.each { |installed|
  261.         installed.keys.each { |key| self.send("#{key}=".to_sym, $game_ats.send(key)) }
  262.       }
  263.     end
  264.   end
  265.  
  266.   #============================================================================
  267.   # ** Game_Interpreter
  268.   #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  269.   #  Summary of Changes:
  270.   #    new methods - ats_all; ats_next
  271.   #============================================================================
  272.  
  273.   class Game_Interpreter
  274.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  275.     # * ATS All
  276.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  277.     def ats_all(sym, *args, &block)
  278.       $game_ats.send("#{sym}=".to_sym, *args, &block)
  279.       ats_next(sym, *args, &block)
  280.     end
  281.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  282.     # * ATS Next
  283.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  284.     def ats_next(sym, *args, &block)
  285.       $game_message.send("#{sym}=".to_sym, *args, &block)
  286.     end
  287.   end
  288.  
  289.   $imported[:AdvancedTextSystem] = true
  290. end
  291.  
  292. # If testing the game, alert the user if any configuration values are incorrect
  293. if $TEST
  294.   config = Game_ATS::CONFIG[:ats_choice_options]
  295.   # Choices that must be a boolean
  296.   if !!config[:append_choices] != config[:append_choices]
  297.     msgbox("Configuration Error in ATS: Choice Options!\nThe :append_choices value should be set to either true or false.")
  298.   end
  299.   # Choices that must be a formatting string
  300.   if !config[:choice_format].is_a?(String) || !config[:choice_format][/%s/]
  301.     msgbox("Configuration Error in ATS: Choice Options!\nThe :choice_format value must be a string that includes %s.")
  302.   end
  303.   # Choices that must be Numeric
  304.   [:choice_win_x_offset, :choice_win_y_offset, :choice_disabled_opacity].each { |option|
  305.     if !config[option].is_a?(Numeric)
  306.       msgbox("Configuration Error in ATS: Choice Options!\nThe #{option} value should be set to an integer.")
  307.     end
  308.   }
  309.   # Choices that must be Numeric and greater than 0
  310.   [:choice_column_num, :choice_help_win_lines, :choice_spacing,
  311.     :choice_win_padding].each { |option|
  312.     if !config[option].is_a?(Numeric) || config[option] <= 0
  313.       msgbox("Configuration Error in ATS: Choice Options!\nThe #{option} value should be set to an integer greater than 0.")
  314.     end
  315.   }
  316.   # Choices that must be either Numeric or a Range
  317.   [:choice_win_width, :choice_win_height].each { |option|
  318.     if !config[option].is_a?(Numeric) && !config[option].is_a?(Range)
  319.       msgbox("Configuration Error in ATS: Choice Options!\nThe #{option} value should be set to an integer greater than 0 or a range")
  320.     end
  321.   }
  322.   # Choices that must be either Numeric or a Symbol
  323.   [:choice_win_x, :choice_win_y].each { |option|
  324.     if !config[option].is_a?(Numeric) && !config[option].is_a?(Symbol)
  325.       msgbox("Configuration Error in ATS: Choice Options!\nThe #{option} value should be set to an integer or a symbol.")
  326.     end
  327.   }
  328. end
  329.  
  330. #==============================================================================
  331. # ** Game_Message
  332. #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  333. #  Summary of Changes:
  334. #    new public instance variables - append_choices; choice_column_num;
  335. #      choice_spacing; choice_win_padding; choice_win_x; choice_win_x_offset;
  336. #      choice_win_y; choice_win_y_offset; choice_win_width; choice_win_height
  337. #==============================================================================
  338.  
  339. class Game_Message
  340.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  341.   # * Public Instance Variables
  342.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  343.   Game_ATS::CONFIG[:ats_choice_options].keys.each { |key| attr_accessor key }
  344.   attr_accessor :choice_help_texts
  345.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  346.   # * Clear
  347.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  348.   alias ma_clr_9vs5 clear
  349.   def clear(*args)
  350.     @choice_help_texts = []
  351.     ma_clr_9vs5(*args) # Run Original Method
  352.   end
  353. end
  354.  
  355. #==============================================================================
  356. # ** Game_Interpreter
  357. #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  358. #  Summary of Changes:
  359. #    overwritten method - command_403
  360. #    aliased method - setup_choices
  361. #    new methods - append_choice_branches; append_choice_process; choice_plus;
  362. #      choice_plus_process; choice_plus_comment
  363. #==============================================================================
  364.  
  365. class Game_Interpreter
  366.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  367.   # * Setup Choices
  368.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  369.   alias maatsco_setupchoics_3jx2 setup_choices
  370.   def setup_choices(params, *args, &block)
  371.     params[0].clear
  372.     params = atsco_interpret_choice_branch(params, @index + 1)
  373.     maatsco_setupchoics_3jx2(params, *args, &block) # Call original method
  374.   end
  375.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  376.   # * When Cancel
  377.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  378.   def command_403
  379.     check = @list[@index].parameters[0].nil? ? 4 : @list[@index].parameters[0]
  380.     command_skip if @branch[@indent] != check
  381.   end
  382.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  383.   # * Interpret Choice Branch
  384.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  385.   def atsco_interpret_choice_branch(params, index = @index)
  386.     if params[2]
  387.       params[1] = params[2]
  388.     else
  389.       params[2] = params[1]
  390.     end
  391.     loop do
  392.       break unless @list[index]
  393.       if @list[index].indent == @indent
  394.         params, index = atsco_interpret_choice_command(params, index)
  395.         break if @list[index].code == 404
  396.       end
  397.       index += 1
  398.     end
  399.     params
  400.   end
  401.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  402.   # * Interpret Choice Command
  403.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  404.   def atsco_interpret_choice_command(params, index)
  405.     params, index = case @list[index].code
  406.     when 102 then atsco_interpret_command_102(params, index) # Show Choices
  407.     when 402 then atsco_interpret_command_402(params, index) # Choice Branch
  408.     when 403 then atsco_interpret_command_403(params, index) # Cancel Branch
  409.     when 404 then atsco_interpret_command_404(params, index) # End Branch
  410.     end
  411.     return params, index
  412.   end
  413.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  414.   # * Append Choice
  415.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  416.   def atsco_interpret_command_102(params, index)
  417.     if $game_message.append_choices
  418.       unless @list[index].parameters[1] == 0 # Unless no Cancel Branch
  419.         params[1] = params[0].size + @list[index].parameters[1] # Set Cancel
  420.         params[2] += @list[index].parameters[1]
  421.       end
  422.       # Remove Command from Event command list
  423.       @list.delete_at(index)
  424.       index -= 1
  425.     end
  426.     return params, index
  427.   end
  428.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  429.   # * Append Choice
  430.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  431.   def atsco_interpret_command_402(params, index)
  432.     # Accomodate for incorrect configuration of choice_format
  433.     $game_message.choice_format = "" unless $game_message.choice_format.is_a?(String)
  434.     $game_message.choice_format += '%s' unless $game_message.choice_format[/%s/]
  435.     # Choice Plus
  436.     plus_text, help_text = atsco_process_choice_comment(index + 1)
  437.     choice_name = sprintf($game_message.choice_format, @list[index].parameters[1] + plus_text)
  438.     del = false
  439.     # Switch Conditions
  440.     choice_name.gsub!(/\\S(!?)\[\s*(\d+)\s*\]/i) {
  441.       # Set to delete if any condition not met
  442.       del = true if ($1.empty? ? !$game_switches[$2.to_i] :
  443.         $game_switches[$2.to_i]); "" }
  444.     if del # If deleting
  445.       @list[index].parameters[0] = -1
  446.       # If cancel branch after this option
  447.       if params[1] > params[0].size && params[1] < 1000
  448.         params[1] -= 1 # Reduce ID of cancel
  449.         params[1] = 0 if params[1] == params[0].size # If this was cancel, disable
  450.       end
  451.     else
  452.       # Set index
  453.       @list[index].parameters[0] = params[0].size
  454.       # Add to choice array
  455.       params[0].push(choice_name)
  456.       # Add to Help Window
  457.       $game_message.choice_help_texts.push(help_text)
  458.     end
  459.     return params, index
  460.   end
  461.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  462.   # * Append Choice
  463.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  464.   def atsco_interpret_command_403(params, index)
  465.     # Only do this if no parameter already set
  466.     if $game_message.append_choices
  467.       if !@list[index].parameters[0]
  468.         # Set the cancel option to this branch
  469.         params[1] += 1000
  470.         @list[index].parameters[0] = params[1] - 1
  471.       else
  472.         params[1] = @list[index].parameters[0] + 1
  473.       end
  474.     end
  475.     return params, index
  476.   end
  477.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  478.   # * Append Choice
  479.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  480.   def atsco_interpret_command_404(params, index)
  481.     # Delete it if next code is a choice box
  482.     next_command = @list[index + 1]
  483.     if $game_message.append_choices && next_command.indent == @indent && next_command.code == 102
  484.       @list.delete_at(index)
  485.       index -= 1
  486.     end
  487.     return params, index
  488.   end
  489.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  490.   # * Process Comment
  491.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  492.   def atsco_process_choice_comment(index)
  493.     # Collect Subsequent comments
  494.     comment = ""
  495.     while @list[index].code == 108 || @list[index].code == 408
  496.       comment += @list[index].parameters[0]
  497.       index += 1
  498.     end
  499.     return choice_plus_comment(comment, index), choice_help_comment(comment, index)
  500.   end
  501.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  502.   # * Choice + Processing
  503.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  504.   def choice_plus_comment(comment, index)
  505.     # Add the content of any \+{} code
  506.     text = ""
  507.     comment.scan(/\\\+{(.+?)}/im) { |str| text += str[0] }
  508.     return text.gsub(/\n/, "")
  509.   end
  510.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  511.   # * Choice Help Processing
  512.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  513.   def choice_help_comment(comment, index)
  514.     # Add the content of any \H{} code
  515.     text = ""
  516.     comment.scan(/\\H{(.+?)}/im) { |str| text += str[0] }
  517.     return text.gsub(/\n/, "")
  518.   end
  519. end
  520.  
  521. unless $imported[:"MA_ParagraphFormat_1.0.1"] # Overwrite if earlier version
  522.   #============================================================================
  523.   # ** MA_Window_ParagraphFormat
  524.   #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  525.   #  This module inserts into Window_Base and provides a method to format the
  526.   # strings so as to go to the next line if it exceeds a set limit. This is
  527.   # designed to work with draw_text_ex, and a string formatted by this method
  528.   # should go through that, not draw_text.
  529.   #============================================================================
  530.  
  531.   module MA_Window_ParagraphFormat
  532.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  533.     # * Calc Line Width
  534.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  535.     def mapf_calc_line_width(line, tw = 0, contents_dummy = false)
  536.       return tw if line.nil?
  537.       line = line.clone
  538.       unless contents_dummy
  539.         real_contents = contents # Preserve Real Contents
  540.         # Create a dummy contents
  541.         self.contents = Bitmap.new(contents_width, 24)
  542.         reset_font_settings
  543.       end
  544.       pos = {x: 0, y: 0, new_x: 0, height: calc_line_height(line)}
  545.       test = @atsf_testing
  546.       @atsf_testing = true # This
  547.       while line[/^(.*?)\e(.*)/]
  548.         tw += text_size($1).width
  549.         line = $2
  550.         # Remove all ancillaries to the code, like parameters
  551.         code = obtain_escape_code(line)
  552.         # If direct setting of x, reset tw.
  553.         tw = 0 if ($imported[:ATS_SpecialMessageCodes] && code.upcase == 'X') ||
  554.           ($imported["YEA-MessageSystem"] && code.upcase == 'PX')
  555.         #  If I need to do something special on the basis that it is testing,
  556.         # alias process_escape_character and differentiate using @atsf_testing
  557.         process_escape_character(code, line, pos)
  558.       end
  559.       @atsf_testing = test
  560.       #  Add width of remaining text, as well as the value of pos[:x] under the
  561.       # assumption that any additions to it are because the special code is
  562.       # replaced by something which requires space (like icons)
  563.       tw += text_size(line).width + pos[:x]
  564.       unless contents_dummy
  565.         contents.dispose # Dispose dummy contents
  566.         self.contents = real_contents # Restore real contents
  567.       end
  568.       return tw
  569.     end
  570.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  571.     # * Format Paragraph
  572.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  573.     def mapf_format_paragraph(text, max_width = contents_width)
  574.       text = text.clone
  575.       #  Create a Dummy Contents - I wanted to boost compatibility by using the
  576.       # default process method for escape codes. It may have the opposite effect,
  577.       # for some :(
  578.       real_contents = contents # Preserve Real Contents
  579.       self.contents = Bitmap.new(contents_width, 24)
  580.       reset_font_settings
  581.       paragraph = ""
  582.       while !text.empty?
  583.         oline, nline, tw = mapf_format_by_line(text.clone, max_width)
  584.         # Replace old line with the new one
  585.         text.sub!(/#{Regexp.escape(oline)}/m, nline)
  586.         paragraph += text.slice!(/.*?(\n|$)/)
  587.         text.lstrip!
  588.       end
  589.       contents.dispose # Dispose dummy contents
  590.       self.contents = real_contents # Restore real contents
  591.       return paragraph
  592.     end
  593.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  594.     # * Format By Line
  595.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  596.     def mapf_format_by_line(text, max_width = contents_width)
  597.       oline, nline, tw = "", "", 0
  598.       loop do
  599.         #  Format each word until reach the width limit
  600.         oline, nline, tw, done = mapf_format_by_word(text, nline, tw, max_width)
  601.         return oline, nline, tw if done
  602.       end
  603.     end
  604.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  605.     # * Format By Word
  606.     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  607.     def mapf_format_by_word(text, line, tw, max_width)
  608.       return line, line, tw, true if text.nil? || text.empty?
  609.       # Extract next word
  610.       if text.sub!(/([ \t\r\f]*)(\S*)([\n\f]?)/, "") != nil
  611.         prespace, word, line_end = $1, $2, $3
  612.         ntw = mapf_calc_line_width(word, tw, true)
  613.         pw = contents.text_size(prespace).width
  614.         if (pw + ntw >= max_width)
  615.           # Insert
  616.           if line.empty?
  617.             # If one word takes entire line
  618.             return prespace + word, word + "\n", ntw, true
  619.           else
  620.             return line + prespace + word, line + "\n" + word, tw, true
  621.           end
  622.         else
  623.           line += prespace + word
  624.           tw = pw + ntw
  625.           # If the line is force ended, then end
  626.           return line, line, tw, true if !line_end.empty?
  627.         end
  628.       else
  629.         return line, line, tw, true
  630.       end
  631.       return line, line, tw, false
  632.     end
  633.   end
  634.  
  635.   class Window_Base
  636.     include MA_Window_ParagraphFormat unless $imported[:"MA_ParagraphFormat_1.0"]
  637.   end
  638.  
  639.   $imported[:"MA_ParagraphFormat_1.0"] = true
  640.   $imported[:"MA_ParagraphFormat_1.0.1"] = true
  641. end
  642.  
  643. #==============================================================================
  644. # ** Window_Message
  645. #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  646. #  Summary of Changes:
  647. #    aliased methods - create_all_windows
  648. #==============================================================================
  649.  
  650. class Window_Message
  651.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  652.   # * Create All Windows
  653.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  654.   alias maatsco_creatwindows_6bq3 create_all_windows
  655.   def create_all_windows(*args)
  656.     maatsco_creatwindows_6bq3(*args) # Call original method
  657.     @atsmo_all_windows.push(@choice_window.help_window) if $imported[:ATS_MessageOptions]
  658.   end
  659. end
  660.  
  661. #==============================================================================
  662. # ** Window_ChoiceList
  663. #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  664. #  Summary of Changes:
  665. #    overwritten methods - update_placement; max_choice_width; col_max
  666. #    aliased method - start
  667. #    new methods - all_line_widths
  668. #==============================================================================
  669.  
  670. class Window_ChoiceList
  671.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  672.   # * Object Initialization
  673.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  674.   alias maatsco_iniz_4hb6 initialize
  675.   def initialize(*args)
  676.     @all_line_heights, @all_line_ys, @all_choice_widths = [], [], []
  677.     maatsco_iniz_4hb6(*args)
  678.     self.z = @message_window.z + 2 # Above Message Window and Name Window
  679.     # Setup Help Window
  680.     lines = $game_message.choice_help_win_lines
  681.     self.help_window = Window_Help.new(lines > 0 ? lines : 1)
  682.     help_window.z = self.z
  683.     help_window.hide
  684.   end
  685.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  686.   # * Start
  687.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  688.   alias maatsco_start_3us4 start
  689.   def start(*args, &block)
  690.     format_choices
  691.     maatsco_start_3us4(*args, &block) # Call original method
  692.   end
  693.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  694.   # * Create Command List
  695.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  696.   alias maatsco_mkcmmndlist_7bc3 make_command_list
  697.   def make_command_list(*args)
  698.     maatsco_mkcmmndlist_7bc3(*args) # Call original method
  699.     @list.each_with_index { |c, i| c[:enabled] = maatsco_choice_enabled?(i) }
  700.   end
  701.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  702.   # * Draw Item
  703.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  704.   alias maatsco_drwitm_3yh5 draw_item
  705.   def draw_item(index, *args)
  706.     @drawing_index = index  # Preserve Index to know whether to disable colour
  707.     change_color(contents.font.color)
  708.     maatsco_drwitm_3yh5(index, *args)
  709.     @drawing_index = nil
  710.   end
  711.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  712.   # * Change Text Drawing Color
  713.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  714.   def change_color(colour, enabled = true, *args)
  715.     super(colour, @drawing_index ? command_enabled?(@drawing_index) : enabled, *args)
  716.   end
  717.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  718.   # * Choice Enabled?
  719.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  720.   def maatsco_choice_enabled?(index)
  721.     name = command_name(index)
  722.     enabled = true
  723.     # Disable Codes
  724.     name.gsub!(/\e[Dd](!?)\[\s*(\d+)\s*\]/i) {
  725.       # Disable if D! switch is ON or if D switch is OFF
  726.       enabled = false if ($1.empty? ? $game_switches[$2.to_i] :
  727.         !$game_switches[$2.to_i]); "" }
  728.     enabled
  729.   end
  730.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  731.   # * Format Choices
  732.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  733.   def format_choices
  734.     # Convert escape characters
  735.     $game_message.choices.collect! {|s|
  736.       convert_escape_characters(s.gsub(/\s*\n\s*/, " ")) }
  737.     @all_choice_widths = get_all_choice_widths
  738.     @choice_width = max_choice_width
  739.     # Get maximum in each line
  740.     @choice_width = (calc_window_width - (padding*2) - (spacing*(col_max - 1))) / col_max
  741.     $game_message.choices.collect! {|s| mapf_format_paragraph(s, @choice_width) }
  742.     @all_line_heights = get_line_heights
  743.     # Set up @all_line_ys
  744.     @all_line_ys.clear
  745.     ah = 0
  746.     for h in @all_line_heights
  747.       @all_line_ys.push(ah)
  748.       ah += h
  749.     end
  750.   end
  751.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  752.   # * Convert Escape Characters
  753.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  754.   if instance_methods(false).include?(:convert_escape_characters)
  755.     # If convert_escape_characters already defined in Window_Message, just alias
  756.     alias maatsco_convertesc_5bs7 convert_escape_characters
  757.     def convert_escape_characters(*args, &block)
  758.       maatsco_convert_escape_characters(maatsco_convertesc_5bs7(*args, &block))
  759.     end
  760.   else
  761.     # If convert_escape_characters undefined in Window_Message, call super method
  762.     def convert_escape_characters(*args, &block)
  763.       maatsco_convert_escape_characters(super(*args, &block))
  764.     end
  765.   end
  766.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  767.   # * ATS CO Convert Escape Characters
  768.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  769.   def maatsco_convert_escape_characters(text)
  770.     text.gsub!(/\e(N|LB)/i, "\n") unless $imported[:ATS_SpecialMessageCodes]
  771.     text.gsub!(/\eA\[([012])\]/i) { "\eALIGN\[#{$1}\]" }
  772.     text.gsub!(/\eA\[([LRC])\]/i) { "\eALIGN\[#{$1.upcase == 'L' ? 0 : $1.upcase == 'C' ? 1 : 2}\]" }
  773.     text
  774.   end
  775.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  776.   # * Process Escape Character
  777.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  778.   if instance_methods(false).include?(:process_escape_character)
  779.     # If convert_escape_characters already defined in Window_Message, just alias
  780.     alias maatsco_processescchr_4bm8 process_escape_character
  781.     def process_escape_character(code, text, pos, *args)
  782.       maatsco_process_escape_character(code, text, pos)
  783.       maatsco_processescchr_4bm8(code, text, pos, *args)
  784.     end
  785.   else
  786.     # If convert_escape_characters undefined in Window_Message, call super method
  787.     def process_escape_character(code, text, pos, *args)
  788.       maatsco_process_escape_character(code, text, pos)
  789.       super(code, text, pos, *args)
  790.     end
  791.   end
  792.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  793.   # * ATS CO Process Escape Character
  794.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  795.   def maatsco_process_escape_character(code, text, pos)
  796.     if code.upcase == 'ALIGN'
  797.       align = (obtain_escape_param(text) % 3)
  798.       return if @atsf_testing || align == 0
  799.       nl = text[/.*/]
  800.       return if !nl
  801.       lw = mapf_calc_line_width(nl)
  802.       spc = (@choice_width - (pos[:x] % (@choice_width + spacing))) - lw
  803.       pos[:x] += spc / (align == 1 ? 2 : 1)
  804.     end
  805.   end
  806.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  807.   # * Update Window Position & Size
  808.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  809.   def update_placement
  810.     self.width = calc_window_width
  811.     self.height = calc_window_height
  812.     self.x = calc_window_x
  813.     self.x = x < 0 ? 0 : x + width > Graphics.width ? Graphics.width - width : x
  814.     self.y = calc_window_y
  815.     self.y = y < 0 ? 0 : y + height > Graphics.height ? Graphics.height - height : y
  816.   end
  817.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  818.   # * Calculate Window's Width
  819.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  820.   def calc_window_width # Get the width
  821.     r = $game_message.choice_win_width
  822.     if r.is_a?(Range)
  823.       # Auto setting
  824.       w = (standard_padding*2) + (@choice_width*col_max) + (spacing*(col_max - 1))
  825.       w < r.first ? r.first : w > r.last ? r.last : w
  826.     else
  827.       # Direct setting
  828.       r > (standard_padding*2) ? r : standard_padding*2 + 24
  829.     end
  830.   end
  831.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  832.   # * Calculate Window's Height
  833.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  834.   def calc_window_height # Get the height
  835.     r = $game_message.choice_win_height
  836.     if r.is_a?(Range)
  837.       # Auto Setting
  838.       h = (standard_padding*2) + (@all_line_heights.inject(0, :+))
  839.       h < r.first ? r.first : h > r.last ? r.last : h
  840.     else
  841.       # Direct setting
  842.       r > (standard_padding*2) ? r : standard_padding*2 + 24
  843.     end
  844.   end
  845.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  846.   # * Calculate X Position
  847.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  848.   def calc_window_x
  849.     if $game_message.choice_win_x.is_a?(Symbol)
  850.       # Auto Setting
  851.       if !@message_window.close?
  852.         # Message window is open
  853.         mx, mw = @message_window.x, @message_window.width
  854.         xo = $game_message.choice_win_x_offset
  855.         case $game_message.choice_win_x.to_s.downcase.to_sym
  856.         when :l, :left then mx + xo                            # Left
  857.         when :c, :centre, :center then mx + ((mw - width) / 2) # Centre
  858.         else mx + mw - width - xo                              # Right
  859.         end
  860.       else
  861.         # Centre if Message window not shown
  862.         (Graphics.width - width) / 2
  863.       end
  864.     else
  865.       # Direct setting
  866.       $game_message.choice_win_x
  867.     end
  868.   end
  869.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  870.   # * Calculate Y Position
  871.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  872.   def calc_window_y
  873.     if $game_message.choice_win_y.is_a?(Symbol)
  874.       # Auto Setting
  875.       if !@message_window.close?
  876.         # Message window is open
  877.         my, mh = @message_window.y, @message_window.height
  878.         yo = $game_message.choice_win_y_offset
  879.         align = my + mh + height > Graphics.height ? :t : my - height < 0 ? :b :
  880.           $game_message.choice_win_y.to_s.downcase.to_sym
  881.         case align
  882.         when :b, :bottom then my + mh - yo # Bottom
  883.         else my - height + yo              # Top
  884.         end
  885.       else
  886.         # Centre if Message window not shown
  887.         (Graphics.height - height) / 2
  888.       end
  889.     else
  890.       # Direct setting
  891.       $game_message.choice_win_y
  892.     end
  893.   end
  894.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  895.   # * Get Maximum Width of Choices
  896.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  897.   def get_all_choice_widths
  898.     # Create dummy bitmap
  899.     real_contents = contents
  900.     self.contents = Bitmap.new(contents_width, 24)
  901.     reset_font_settings
  902.     choice_widths = $game_message.choices.collect {|s|
  903.       s.split(/\n/).collect {|s2| mapf_calc_line_width(s2, 0, true) }.max}
  904.     self.contents.dispose
  905.     # Restore real bitmap
  906.     self.contents = real_contents
  907.     choice_widths
  908.   end
  909.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  910.   # * Get Maximum Width of Choices
  911.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  912.   def get_line_heights
  913.     line_heights = Array.new(1 + (($game_message.choices.size - 1) / col_max), 0)
  914.     for i in 0...$game_message.choices.size
  915.       h = $game_message.choices[i].split(/\n/).inject(0) {|sum, s2| sum + calc_line_height(s2) }
  916.       line_heights[i / col_max] = h if h > line_heights[i / col_max]
  917.     end
  918.     line_heights
  919.   end
  920.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  921.   # * Get Rectangle for Drawing Items
  922.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  923.   def item_rect(index)
  924.     rect = Rect.new
  925.     rect.width = item_width
  926.     rect.height = @all_line_heights.empty? ? item_height : @all_line_heights[index / col_max]
  927.     rect.x = index % col_max * (rect.width + spacing)
  928.     rect.y = @all_line_ys.empty? ? index / col_max * rect.height : @all_line_ys[index / col_max]
  929.     rect
  930.   end
  931.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  932.   # * Get Maximum Width of Choices
  933.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  934.   def max_choice_width
  935.     ($game_message.choices.empty? || @all_choice_widths.empty?) ? 12 : (@all_choice_widths.max + 8)
  936.   end
  937.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  938.   # * Update Bottom Padding
  939.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  940.   def update_padding_bottom(*args)
  941.     if @all_line_ys.empty?
  942.       super(*args)
  943.     else
  944.       ah = 0
  945.       max = oy + height - (2*standard_padding)
  946.       for h in @all_line_heights
  947.         break if ah + h > max
  948.         ah += h
  949.       end
  950.       self.padding_bottom = padding + (max - ah)
  951.     end
  952.   end
  953.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  954.   # * Calculate Height of Window Contents
  955.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  956.   def contents_height(*args)
  957.     @all_line_heights.empty? ? super(*args) : @all_line_heights.inject(0, :+)
  958.   end
  959.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  960.   # * Get Top Row
  961.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  962.   def top_row(*args)
  963.     r = @all_line_ys.empty? ? nil : @all_line_ys.index(oy)
  964.     r ? r : super(*args)
  965.   end
  966.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  967.   # * Set Top Row
  968.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  969.   def top_row=(row)
  970.     row = 0 if row < 0
  971.     row = row_max - 1 if row > row_max - 1
  972.     self.oy = @all_line_ys.empty? ? row * item_height : @all_line_ys[row]
  973.     update_padding_bottom
  974.   end
  975.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  976.   # * Get Number of Rows Displayable on 1 Page
  977.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  978.   def page_row_max(*args)
  979.     if @all_line_ys.empty?
  980.       super(*args)
  981.     else
  982.       r = top_row
  983.       hmax = oy + height - (2*standard_padding)
  984.       loop do
  985.         break if r >= @all_line_ys.size
  986.         break if @all_line_ys[r] + @all_line_heights[r] > hmax
  987.         r += 1
  988.       end
  989.       [r - top_row, 1].max
  990.     end
  991.   end
  992.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  993.   # * Number of columns
  994.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  995.   def col_max
  996.     [[$game_message.choices.size, $game_message.choice_column_num].min, 1].max
  997.   end
  998.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  999.   # * Translcent Opacity
  1000.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1001.   def translucent_opacity(*args)
  1002.     o = $game_message.choice_disabled_opacity
  1003.     o.is_a?(Numeric) ? o : super(*args)
  1004.   end
  1005.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1006.   # * Standard Padding
  1007.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1008.   def standard_padding(*args)
  1009.     p = $game_message.choice_win_padding
  1010.     (p.is_a?(Numeric) && p > 0) ? p : super(*args)
  1011.   end
  1012.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1013.   # * Get Spacing for Items Arranged Side by Side
  1014.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1015.   def spacing(*args)
  1016.     s = $game_message.choice_spacing
  1017.     (s.is_a?(Numeric) && s > 0) ? s : super(*args)
  1018.   end
  1019.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1020.   # * Item Width
  1021.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1022.   def item_width(*args)
  1023.     @choice_width ? @choice_width : super(*args)
  1024.   end
  1025.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1026.   # * Open
  1027.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1028.   def open
  1029.     super
  1030.     setup_help_window if $game_message.choice_help_texts.any? { |h| !h.empty? }
  1031.   end
  1032.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1033.   # * Close
  1034.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1035.   def close
  1036.     super
  1037.     help_window.hide
  1038.   end
  1039.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1040.   # * Setup Help Window
  1041.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1042.   def setup_help_window
  1043.     help_window.show
  1044.     r = 0...help_window.height
  1045.     bot = ((r === @message_window.y) || (r === y))
  1046.     help_window.y = bot ? Graphics.height - help_window.height : 0
  1047.   end
  1048.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1049.   # * Update Help Text
  1050.   #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1051.   def update_help
  1052.     if index >= 0 && $game_message.choice_help_texts[index].is_a?(String)
  1053.       @help_window.set_text($game_message.choice_help_texts[index])
  1054.     else
  1055.       help_window.clear
  1056.     end
  1057.   end
  1058. end
RAW Paste Data