[Hướng Dẫn] Hướng dẫn tạo nhiều lựa chọn với event [A] và Scritp [VXA]

KangKang Posts: 453Registered
* Chú thích : [A] : tất cả các phiên bản RPG
[VXA] : chỉ dành cho VXA

[size=x-large]I. TẠO NHIỀU LỰA CHỌN BẰNG EVENT [A] (ORIGINAL BY KSTHUYEN)[/size]
Khuyến cáo áp dụng với loại 2 trang (6 lựa chọn):
làm như hình vẽ:
1_zps2d091d74.png

[size=x-large]II. TẠO NHIỀU LỰA CHỌN BẰNG SCRIPT [VXA][/size]

áp dụng với 5 lựa chọn trở lên, test để biết thêm cái hay của 2 script

Script 1 (Bắt buộc):
=begin
#==============================================================================
 ** Large Choices
 Author: Tsukihime
 Date: Apr 10, 2013
------------------------------------------------------------------------------
 ** Change log
 Apr 10, 2013
   - added option to disable automatic show combining
 Mar 26, 2013
   - fixed bug where cancel choice was not properly updated
 Jan 12, 2013
   - fixed bug where the first set of nested options were numbered incorrectly
 Dec 7, 2012
   - implemented proper branch canceling
 Dec 6, 2012
   - Initial release
------------------------------------------------------------------------------   
 ** Terms of Use
 * Free to use in commercial/non-commercial projects
 * No real support. The script is provided as-is
 * Will do bug fixes, but no compatibility patches
 * Features may be requested but no guarantees, especially if it is non-trivial
 * Preserve this header
------------------------------------------------------------------------------
 ** Description
 
 This script combines groups of "show choice" options together as one large
 command. This allows you to create more than 4 choices by simply creating
 several "show choice" commands.
------------------------------------------------------------------------------
 ** Usage
 
 Add a show choice command.
 If you want more choices, add another one, and fill it out as usual.
 
 Note that you should only specify one cancel choice (if you specify more than
 one, then the last one is taken).
 
 For "branch" canceling, note that *all* cancel branches are executed.
 You should only have a cancel branch on the last set of choices
 
 You can disable automatic choice combining by enabling the "Manual Combine"
 option, which will require you to make this script call before the first
 show choice command
 
    combine_choices
    
 In order to combine choices together
#==============================================================================
=end



$imported = {} if $imported.nil?
$imported["TH_LargeChoices"] = true
#==============================================================================
# ** Configuration
#==============================================================================
module TH
  module Large_Choices
    
    # Turning this option on will require you to manually specify that
    # a sequence of Show Choice options should be combined
    Manual_Combine = false
    
#==============================================================================
# ** Rest of the script
#==============================================================================     
    Code_Filter = [402, 403, 404]
    Regex = /<large choices>/i
  end
end

class Game_Temp
  
  # temp solution to get this working
  attr_accessor :branch_choice
  
  def branch_choice
    @branch_choice || 5
  end
end

class Game_Interpreter
  
  #-----------------------------------------------------------------------------
  # Clean up
  #-----------------------------------------------------------------------------
  alias :th_large_choices_clear :clear
  def clear
    th_large_choices_clear
    @first_choice_cmd = nil
    @choice_search = 0
    @combine_choices = false
  end
  
  #-----------------------------------------------------------------------------
  # Prepare for more choices
  #-----------------------------------------------------------------------------
  alias :th_large_choices_setup_choices :setup_choices
  def setup_choices(params)
    # start with our original choices
    th_large_choices_setup_choices(params)
    
    return if TH::Large_Choices::Manual_Combine && !@combine_choices

    # store our "first" choice in the sequence
    @first_choice_cmd = @list[@index]
    
    # reset branch choice
    $game_temp.branch_choice = @first_choice_cmd.parameters[1]
    
    # Start searching for more choices
    @num_choices = $game_message.choices.size
    @choice_search = @index + 1
    search_more_choices
  end
  
  def combine_choices
    @combine_choices = true
  end
  
  #-----------------------------------------------------------------------------
  # New. Check whether the next command (after all branches) is another choice
  # command. If so, merge it with the first choice command.
  #-----------------------------------------------------------------------------
  def search_more_choices
    skip_choice_branches
    next_cmd = @list[@choice_search]
    
    # Next command isn't a "show choice" so we're done
    return if next_cmd.code != 102
    
    @choice_search += 1
    # Otherwise, push the choices into the first choice command to merge
    # the commands.
    @first_choice_cmd.parameters[0].concat(next_cmd.parameters[0])
    
    # Update all cases to reflect merged choices
    update_show_choices(next_cmd.parameters)
    update_cancel_choice(next_cmd.parameters)
    update_choice_numbers
    
    # delete the command to effectively merge the branches
    @list.delete(next_cmd)
    
    # Now search for more
    search_more_choices
  end

  #-----------------------------------------------------------------------------
  # New. Update the options for the first "show choice" command
  #-----------------------------------------------------------------------------
  def update_show_choices(params)
    params[0].each {|s| $game_message.choices.push(s) }
  end
  
  #-----------------------------------------------------------------------------
  # New. If cancel specified, update it to reflect merged choice numbers
  # The last one is taken if multiple cancel choices are specified
  #-----------------------------------------------------------------------------
  def update_cancel_choice(params)
    
    # disallow, just ignore
    return if params[1] == 0    
    
    # branch on cancel
    return update_branch_choice if params[1] == 5
    
    # num_choices is not one-based
    cancel_choice = params[1] + (@num_choices)
    # update cancel choice, as well as the first choice command
    $game_message.choice_cancel_type = cancel_choice
    @first_choice_cmd.parameters[1] = cancel_choice
  end
  
  #-----------------------------------------------------------------------------
  # New. Set the initial choice command to "branch cancel"
  #-----------------------------------------------------------------------------
  def update_branch_choice
    branch_choice = $game_message.choices.size + 1
    $game_message.choice_cancel_type = branch_choice
    $game_temp.branch_choice = branch_choice
    @first_choice_cmd.parameters[1] = branch_choice
  end
  
  def command_403
    command_skip if @branch[@indent] != $game_temp.branch_choice - 1
  end
  
  #-----------------------------------------------------------------------------
  # New. For each branch, update it to reflect the merged choice numbers.
  #-----------------------------------------------------------------------------
  def update_choice_numbers
    
    # Begin searching immediately after cmd 102 (show choice)
    i = @choice_search
    
    # Rough search for "When" commands. The search must skip nested commands
    while TH::Large_Choices::Code_Filter.include?(@list[i].code) || @list[i].indent != @indent
      if @list[i].code == 402 && @list[i].indent == @indent
        @list[i].parameters[0] = @num_choices 
        @num_choices += 1
      end
      i += 1
    end
  end
  
  #-----------------------------------------------------------------------------
  # New. Returns the next command after our choice branches
  #-----------------------------------------------------------------------------
  def skip_choice_branches
    # start search at the next command
    # skip all choice branch-related commands and any branches
    while TH::Large_Choices::Code_Filter.include?(@list[@choice_search].code) || @list[@choice_search].indent != @indent
      @choice_search += 1
    end
    return @choice_search
  end
end

Script 2 (khuyến cáo sử dụng thêm. ĐẶt dưới Script 1):
=begin
#==============================================================================
 ** Choice Options
 Author: Tsukihime
 Date: Apr 10, 2013
------------------------------------------------------------------------------
 ** Change log
 Apr 10, 2013
   - new lines automatically removed for "text" option
 Apr 9, 2013
   - added "text" choice option
 Mar 8, 2013
   - fixed a copy-by-reference issue
 Mar 6, 2013
   - hidden choice fixed
   - new script interface added
 Dec 6, 2012
   - removed multiple choice implementation to be more flexible
   - implemented scrolling choices
 Dec 4, 2012
   - added support for built-in choice editor
   - initial release
------------------------------------------------------------------------------   
 ** Terms of Use
 * Free to use in commercial/non-commercial projects
 * No real support. The script is provided as-is
 * Will do bug fixes, but no compatibility patches
 * Features may be requested but no guarantees, especially if it is non-trivial
 * Preserve this header
------------------------------------------------------------------------------
 ** Description
 
 This script provides extended control over choices.
 
 You can add "choice options" to each choice for further control over how
 they should appear, when they should appear, ...
 
------------------------------------------------------------------------------
 ** Usage
 
 To add choice option, use one of the methods defined in the reference section.
 For example, if you want to hide a choice 1 if actor 1's level is less than 5,
 you would write
   
   hide_choice(1, "$game_actors[1].level < 5")
   
------------------------------------------------------------------------------
 ** Reference
 
 The following options are available
 
 Method: disable_choice
 Effect: disables choice if condition is not met
 Usage:  Takes a string representing a boolean statement. For example,
         "$game_actors[1].level > 5" means that the condition will only be
         selectable if actor 1's level is greater than 5.
     
 Method: hide_choice
 Effect: hides choice if condition is met
 Usage:  Takes a string representing a boolean statement. For example,
         "$game_party.gold < 2000" means that the condition will not be shown
         if the party's gold is less than 2000
           
 Method: color_choice
 Effect: Very simple text color changing based on system colors
 Usage:  Takes an integer as the text color, based on the system colors.
         (eg: 2 is red by default). Check the "Window.png" file in your
         RTP folder to see the default colors
         
 Method: text_choice
 Effect: Sets the text of the choice to the custom text.
 Usage:  Takes a string that will replace whatever you place in the choice 
         editor. This allows you to exceed the 50-char limit.
------------------------------------------------------------------------------
 ** Compatibility
 
 This script must be placed below Large Choices
------------------------------------------------------------------------------
 ** Credits
 Enelvon, for scrolling choices implementation
#==============================================================================
=end



$imported = {} if $imported.nil?
$imported["Tsuki_ChoiceOptions"] = true
#==============================================================================
# ** Configuration
#==============================================================================
module Tsuki
  module Choice_Options
    
    Scroll_Choices = true         # disable this if it is causing problems
    Default_Visible_Choices = 8   # Number of choices to show by default
  end
end
#==============================================================================
# ** Rest of the script
#==============================================================================
class Game_Message
  attr_reader   :choice_map
  attr_accessor :orig_choices
  attr_accessor :choice_options
  attr_accessor :num_visible_choices
  
  alias :th_choice_options_clear :clear
  def clear
    th_choice_options_clear
    clear_choice_options
    @choice_map = []
    @orig_choices = []
    @num_visible_choices = Tsuki::Choice_Options::Default_Visible_Choices
  end
  
  def clear_choice_map
    
  end
  
  # Hardcode...
  def clear_choice_options
    @choice_options = {}
    @choice_options[:condition] = {}
    @choice_options[:hidden] = {}
    @choice_options[:color] = {}
    @choice_options[:text] = {}
  end
  
  # Just hardcode. Refactor later.
  def set_choice_option(type, num, arg)
    case type
    when :condition
      @choice_options[type][num] = eval(arg)
    when :hidden
      @choice_options[type][num] = eval(arg)
    when :color
      @choice_options[type][num] = arg.to_i
    when :text
      @choice_options[type][num] = arg.gsub("\n", "")
    else
      return
    end
  end
  
  def get_choice_option(type, num)
    return @choice_options[type][num]
  end
  
  def choice_hidden?(num)
    return @choice_options[:hidden][num]
  end
end

class Game_Interpreter
  
  alias :th_choice_options_setup_choices :setup_choices
  def setup_choices(params)
    # start with our original choices
    th_choice_options_setup_choices(params)
    replace_choice_texts
    setup_choice_map
  end
  
  def replace_choice_texts
    $game_message.choices.size.times do |i|
      str = $game_message.get_choice_option(:text, i+1)
      $game_message.choices[i] = str if str
    end
  end
  
  #-----------------------------------------------------------------------------
  # New. Go through hidden choices and map the indices appropriately.
  # The list of choices should only contain the list of visible choices
  # since other classes probably don't expect to have to check whether
  # a choice is hidden or not
  #-----------------------------------------------------------------------------
  def setup_choice_map
    $game_message.orig_choices = $game_message.choices.clone
    ($game_message.choices.size).times{|i|
      if choice_hidden?(i+1)
        $game_message.choices.delete_at(i)
      else
        $game_message.choice_map.push(i)
      end
    }
    # redefine the choice proc
    $game_message.choice_proc = Proc.new {|n| @branch[@indent] = $game_message.choice_map[n] }
  end
  
  # Return true if the choice is hidden
  def choice_hidden?(n)
    $game_message.get_choice_option(:hidden, n)
  end
  
  # add a choice option
  def choice_option(type, choice_num, arg)
    $game_message.set_choice_option(type.to_sym, choice_num, arg)
  end
  
  def hide_choice(choice_num, condition)
    $game_message.set_choice_option(:hidden, choice_num, condition)
  end
  
  def disable_choice(choice_num, condition)
    $game_message.set_choice_option(:condition, choice_num, condition)
  end
  
  def color_choice(choice_num, value)
    $game_message.set_choice_option(:color, choice_num, value)
  end
  
  def text_choice(choice_num, text)
    $game_message.set_choice_option(:text, choice_num, text)
  end
end

class Window_ChoiceList < Window_Command
  
  #-----------------------------------------------------------------------------
  # Enelvon's scrolled choices
  #-----------------------------------------------------------------------------
  if Tsuki::Choice_Options::Scroll_Choices
    def update_placement
      self.width = [max_choice_width + 12, 96].max + padding * 2
      self.width = [width, Graphics.width].min
      self.height = fitting_height([$game_message.choices.size, $game_message.num_visible_choices].min)
      self.x = Graphics.width - width
      if @message_window.y >= Graphics.height / 2
        self.y = @message_window.y - height
      else
        self.y = @message_window.y + @message_window.height
      end
    end
  end

  # Overwrite. Apply choice options when making text
  def make_command_list
    $game_message.orig_choices.each_with_index do |choice, i|
      next if $game_message.choice_hidden?(i+1)
      condition = $game_message.get_choice_option(:condition, i+1)
      condition_met = condition.nil? ? true : !condition
      add_command(choice, :choice, condition_met)
    end
  end
  
  # Apply font-related choice options when drawing choices
  alias :th_multiple_choice_draw_item :draw_item
  def draw_item(index)
    set_choice_color(index)
    th_multiple_choice_draw_item(index)
  end

  # I have my own font settings for each option so don't need the default
  def reset_font_settings
  end
  
  # New. Apply font settings
  def set_choice_color(index)
    if color = $game_message.get_choice_option(:color, $game_message.choice_map[index+1])
      change_color(text_color(color), command_enabled?(index))
    else
      change_color(normal_color, command_enabled?(index))
    end
  end
end

ĐÃ TEST!
Nhớ bấm REP+ nhá!

Comments

Sign In or Register to comment.