Advertisement
Guest User

error

a guest
Mar 31st, 2015
260
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 36.95 KB | None | 0 0
  1. ##----------------------------------------------------------------------------##
  2. ## Composite Character v2.1
  3. ## Created by Neon Black
  4. ##
  5. ## Only for non-commercial use.  See full terms of use and contact info at:
  6. ## http://cphouseset.wordpress.com/liscense-and-terms-of-use/
  7. ##----------------------------------------------------------------------------##
  8.                                                                               ##
  9. ##----------------------------------------------------------------------------##
  10. ##    Revision Info:
  11. ## V2.1 - 2.12.2013
  12. ##  Added new script calls
  13. ## V2.0 - 1.24.2013
  14. ##  Rewrote entire script from scratch
  15. ## V1.0 - 10.17.2012
  16. ##  Wrote and debugged main script
  17. ##----------------------------------------------------------------------------##
  18.                                                                               ##
  19. $imported = {} if $imported.nil?                                              ##
  20. $imported["COMPOSITE"] = 2.1                                                  ##
  21.                                                                               ##
  22. ##----------------------------------------------------------------------------##
  23. ##    Instructions:
  24. ## Place this script in the "Materials" section of the scripts above "Main".
  25. ## To use this script you must have additional composite graphics in a folder
  26. ## for characters and a folder for faces.  Charactersets will use composites
  27. ## based on their names in the NAMES setting.  Some layers of the composite
  28. ## may also change based on the equipped items on the actor associated with
  29. ## file name.  There are several tags that work with both actors and equips.
  30. ##
  31. ##    Tags:
  32. ## tag init[Handler, hue]
  33. ##  - Can only be tagged in actors.  Changes composite layer :tag to handler
  34. ##    "Handler" with the defined hue.  Do not use colons for layer names or
  35. ##    quotes for file handler names.
  36. ## gender[male]
  37. ##  - Sets the character's initial gender to "male" or "female" depending on
  38. ##    which you place in the brackets.  This can only tag actors.
  39. ## alt name[Christopher]
  40. ##  - Sets the character's name for the opposite gender.  If the player changes
  41. ##    the gender in the GUI and has not changed the name, the new name will be
  42. ##    displayed.  The name "Christopher" here can be any name you desire.
  43. ## tag image[Handler, hue]
  44. ##  - Changes the default images for layer :tag to file handler "Handler".
  45. ##
  46. ##    Script Calls:
  47. ## The character creation screen can be called with either of these two script
  48. ## calls from an event.  Other script calls also exist.
  49. ##
  50. ## creation(id)  -or-  creation(id, array)
  51. ##  - The value "id" can be either the actor's ID or the name of the character
  52. ##    set to modify.  The "array" value does not need to be used ever.  This is
  53. ##    the array of handlers from "GUI_LISTS" to use.  If no array is defined,
  54. ##    "BASE_GUI" is used instead.
  55. ## composite_custom(id, handler, name, hue)
  56. ##  - Changes composite "id"'s layer "handler" into file "name" with a hue of
  57. ##    "hue".  This occurs on the same priority level as the character creation
  58. ##    screen, so it is covered by armour and can be modified by the player.
  59. ##    "id" must be a value from NAMES, "handler" a layer from COMPOSITE, "name"
  60. ##    a file from FILE_HANDLERS, and "hue" a number from 0 to 255.
  61. ## composite_force(id, handler, name, hue)
  62. ##  - Similar to the command above, but this takes the highest priority when
  63. ##    being drawn and cannot be changed by the player.
  64. ## composite_reset(id)
  65. ##  - Removes all layers added using the "composite_force" script call.
  66. ##
  67. ##    Special Layers:
  68. ## In order to allow a slight bit more customization, there are 3 types of
  69. ## special layers that link directly to other layers.  These layers end with
  70. ## "Back", "Hueless", and "All".
  71. ##
  72. ## Back Layers
  73. ##  - These layers do not actually need to be behind the normal layer.  They
  74. ##    are simply a second layer with all the same properties of the parent
  75. ##    layer.  An example would be :hairRear which would be a rear layer of
  76. ##    :hair.
  77. ## Hueless Layers
  78. ##  - These layers ignore the changed hue values.  The main use of these would
  79. ##    be objects with skin tone or perhaps objects that you only want to change
  80. ##    part of the colour on.  The only object that uses this in the example
  81. ##    is :eyesHueless which is a hueless layer of :eyes.
  82. ## All Layers
  83. ##  - These are special layers on the character.  They are a layer that appears
  84. ##    on the character no matter what the player does.  The file that appears
  85. ##    is still linked to the file part it is attatched to for the sake of hue.
  86. ##    The file that appears for one of these layers is defined in the hash
  87. ##    GUI_OPTIONS.
  88. ##----------------------------------------------------------------------------##
  89.                                                                               ##
  90. module CP        # Do not touch                                               ##
  91. module COMPOSITE #  these lines.                                              ##
  92.                                                                               ##
  93. ##----------------------------------------------------------------------------##
  94. ##    Config:
  95. ## The config options are below.  You can set these depending on the flavour of
  96. ## your game.  Each option is explained in a bit more detail above it.
  97. ##
  98. ##------
  99.  
  100. # The folders containing the composite parts for characters and for facesets.
  101. CHAR_FOLDER = "Graphics/Composite/Charas/"
  102. FACE_FOLDER = "Graphics/Composite/Faces/"
  103.  
  104. # Determines if the creation screen uses face sets are not.  Set to false if
  105. # you do not want a faceset displayed.
  106. USE_FACESETS = true
  107.  
  108. # The width and height of the character window in the creation screen.  The
  109. # character in the screen is zoomed in to 200%.
  110. WINDOW_WIDTH = 90
  111. WINDOW_HEIGHT = 112
  112.  
  113. # The text options for the character selection GUI.  EMPTY_TEXT refers to an
  114. # option which is blank for some reason.
  115. GUI_CLOSE = "Finish Editing"
  116. EMPTY_TEXT = "None"
  117.  
  118. # The number of allowed character spaces for names when input from the editor.
  119. CHARACTERS = 6
  120.  
  121. # Names for the male and female genders.
  122. GENDER_NAMES = ["Male", "Female"]
  123.  
  124. # Determines if male undefined characters start out as male characters.
  125. MALE_DEFAULT = true
  126.  
  127. ##------
  128.  
  129. # Determine the files that are recognized as composite images and the actor
  130. # they are linked to, for the sake of armour, storage, etc.
  131. NAMES ={
  132.   "$Hero1" => 1,
  133. }
  134.  
  135. # The switches related to characters.  A switch is turned ON when the character
  136. # is male and OFF when the character is female.
  137. SWITCHES ={
  138.   1 => 72,
  139. }
  140.  
  141. # The order for composite layers.  The first layer is the lowest layer.
  142. COMPOSITE =[
  143.   :hairRear,
  144.   :cape,
  145.   :armorRear,
  146.   :headAll,
  147.   :head,
  148.   :eyes,
  149.   :eyesAll,
  150.   :eyesHueless,
  151.   :armor,
  152.   :hair,
  153.   :glasses,
  154.   :helmet,
  155. ]
  156.  
  157. # These are the handlers for all files in the composite folders.  Actor and
  158. # equip tags as well as GUI options point to a handler and the handler
  159. # determines the male and female files to look up.  Make sure every handler
  160. # has a different name.
  161. FILE_HANDLERS ={
  162. # "Handler"       => ["Male_File", "Female_File"],
  163.   "Shaggy"        => ["Hair1M", nil],
  164.   "Slick"         => ["Hair2M", nil],
  165.   "Spiked"        => ["Hair3M", nil],
  166.   "Fancy"         => ["Hair4M", nil],
  167.   "Stylish"       => [nil, "Hair1F"],
  168.   "Waist Length"  => [nil, "Hair2F"],
  169.   "Curled"        => [nil, "Hair3F"],
  170.   "Pigtails"      => [nil, "Hair4F"],
  171.   "Short"         => ["Hair1U", "Hair1U"],
  172.   "Long"          => ["Hair2U", "Hair2U"],
  173.   "Observant"     => ["Eye1M", "Eye1F"],
  174.   "Closed"        => ["Eye2M", "Eye2F"],
  175.   "Intent"        => ["Eye3M", "Eye3F"],
  176.  
  177.   "HeadBase"      => ["HeadAll", "HeadAll"],
  178.   "FaceBase"      => ["FaceM", "FaceF"],
  179.   "BodyBase"      => ["BaseM", "BaseF"],
  180.  
  181.   "Clothes"       => ["ClothesM", "ClothesF"],
  182.   "Cloth"         => ["ClothM", "ClothF"],
  183.   "Armor"         => ["ArmourM", "ArmourF"],
  184.   "Glasses"       => ["Glasses", "Glasses"],
  185.   "Sunglasses"    => ["Sunglasses", "Sunglasses"],
  186.   "Goggles"       => ["Goggles", "Goggles"],
  187. }
  188.  
  189. # Standard handlers.  These are default handlers of certain layers.
  190. STANDARD ={
  191.   :headAll  => "HeadBase",
  192.   :head     => "FaceBase",
  193.   :armor    => "BodyBase",
  194. }
  195.  
  196. # The GUI options that may be called from an array.  If the "Name" field is set
  197. # to a :symbol like the :barber example, it will point back to another option
  198. # and use that option's name and layer.  The point is simply to link different
  199. # handlers to it as well as giving it different colour options.  The colorize?
  200. # option can be set to a value of 0, 1, or 2 depending on the style of hue bar
  201. # you would like displayed.  If it is set to 0, no bar will be displayed.
  202. GUI_OPTIONS ={
  203. # :handler  => ["Name",   colorize?, "AllFile"],
  204.   :Name     => ["Name",   0,         nil],
  205.   :Gender   => ["Gender", 0,         nil],
  206.   :hair     => ["Hair",   1,         nil],
  207.   :eyes     => ["Eyes",   1,         "EyeAll"],
  208.  
  209.   :barber   => [:hair,    true,      nil],
  210. }
  211.  
  212. # These are the basic options to use in the GUI if no array is defined.
  213. BASE_GUI = [:Name, :Gender, :hair, :eyes]
  214.  
  215. # These are the lists that refer to the options.  Male and Female only options
  216. # are automatically filtered depending on the character's gender.
  217. GUI_LISTS ={
  218.   :hair     => ["Shaggy", "Slick", "Spiked", "Fancy", "Stylish", "Waist Length",
  219.                 "Curled", "Pigtails"],
  220.   :eyes     => ["Observant", "Intent", "Closed"],
  221.  
  222.  
  223.   :barber   => ["Shaggy", "Slick", "Spiked", "Fancy", "Stylish", "Waist Length",
  224.                 "Curled", "Pigtails", "Short", "Long"],
  225. }
  226.  
  227. ##----------------------------------------------------------------------------##
  228.                                                                               ##
  229.                                                                               ##
  230. ##----------------------------------------------------------------------------##
  231. ## The following lines are the actual core code of the script.  While you are
  232. ## certainly invited to look, modifying it may result in undesirable results.
  233. ## Modify at your own risk!
  234. ###----------------------------------------------------------------------------
  235.  
  236.  
  237. end
  238. end
  239.  
  240. module Cache
  241.   class << self  ## Alias for the used methods in this module.
  242.     alias cp_cm_character character
  243.     alias cp_cm_face face
  244.     alias cp_cm_clear clear
  245.   end
  246.  
  247.   def self.character(*args)  ## Checks if the file is a composite.
  248.     return cp_cm_character(*args) unless Composites.include?(args[0])
  249.     create_composite(args[0], "Graphics/Characters/")
  250.     hue = args[1] ? args[1] : 0
  251.     load_bitmap("Graphics/Characters/", args[0], hue)
  252.   end
  253.  
  254.   def self.face(*args)  ## Checks if the face is a composite.
  255.     return cp_cm_face(*args) unless Composites.include?(args[0])
  256.     create_composite(args[0], "Graphics/Faces/")
  257.     hue = args[1] ? args[1] : 0
  258.     load_bitmap("Graphics/Faces/", args[0], hue)
  259.   end
  260.  
  261.   def self.need_comp_ref?(file, path)  ## Checks refresh status.
  262.     return true if Composites.refresh?(file)
  263.     return true if @cache[path].nil? || @cache[path].disposed?
  264.     return false
  265.   end
  266.  
  267.   def self.create_composite(file, folder)  ## Find and create the composite.
  268.     path = "#{folder}#{file}"
  269.     return unless need_comp_ref?(file, path)
  270.     foldrs = ["Graphics/Characters/", "Graphics/Faces/"]
  271.     Composites.constants.each_with_index do |fld, i|
  272.       paths = "#{foldrs[i]}#{file}"
  273.       array = Composites.images(file)
  274.       Composites.layers do |i|
  275.         image = array[i]
  276.         unless @temp
  277.           @temp = Bitmap.new("#{fld}#{image}") rescue next
  278.           @temp.hue_change(Composites.hues(file)[i]) unless Composites.hues(file)[i].nil?
  279.         else
  280.           t = Bitmap.new("#{fld}#{image}") rescue next
  281.           t.hue_change(Composites.hues(file)[i]) unless Composites.hues(file)[i].nil?
  282.           @temp.blt(0, 0, t, t.rect)
  283.           t.dispose; t = nil
  284.         end
  285.       end
  286.       @temp = Bitmap.new unless @temp
  287.       Composites.refreshed(file)
  288.       @cache[paths] = Bitmap.new(@temp.width, @temp.height)
  289.       @cache[paths].blt(0, 0, @temp, @temp.rect)
  290.       @temp.dispose; @temp = nil
  291.     end
  292.     Composites.remove_temp_layers(file)
  293.   end
  294.  
  295.   def self.clear  ## Reset the composite cache.
  296.     cp_cm_clear
  297.     Composites.clear
  298.   end
  299. end
  300.  
  301. module Composites
  302.   def self.include?(file)  ## Checks if a file is a composite.
  303.     return CP::COMPOSITE::NAMES.include?(file)
  304.   end
  305.  
  306.   def self.options  ## Easy access of the options hash.
  307.     return CP::COMPOSITE::GUI_OPTIONS
  308.   end
  309.  
  310.   def self.lists  ## Easy access of the gui lists hash.
  311.     return CP::COMPOSITE::GUI_LISTS
  312.   end
  313.  
  314.   def self.list_by_block(handler, block)  ## Returns a list based on gender.
  315.     return [] unless [0, 1].include?(block) && lists.include?(handler)
  316.     return lists[handler].select {|a| !files[a][block].nil?}
  317.   end
  318.  
  319.   def self.layers  ## Gets each layer key one at a time.
  320.     CP::COMPOSITE::COMPOSITE.each do |key|
  321.       yield key
  322.     end
  323.   end
  324.  
  325.   def self.constants  ## Gets the folder constants.
  326.     if CP::COMPOSITE::USE_FACESETS
  327.       return [CP::COMPOSITE::CHAR_FOLDER, CP::COMPOSITE::FACE_FOLDER]
  328.     else
  329.       return [CP::COMPOSITE::CHAR_FOLDER]
  330.     end
  331.   end
  332.  
  333.   def self.files  ## Gets the file handler hash.
  334.     return CP::COMPOSITE::FILE_HANDLERS
  335.   end
  336.  
  337.   def self.include_block?(block, handler)  ## Checks gender blocks to handlers.
  338.     return false unless files.include?(handler)
  339.     return !files[handler][block].nil?
  340.   end
  341.  
  342.   def self.standard  ## Gets the standard GUI display.
  343.     return CP::COMPOSITE::STANDARD
  344.   end
  345.  
  346.   def self.get_first_handler(block, key)  ## Gets the init files based on block.
  347.     return nil if ![0, 1].include?(block) || !lists.include?(key)
  348.     lists[key].each do |handler|
  349.       next unless files.include?(handler)
  350.       return handler unless files[handler][block].nil?
  351.     end
  352.     return nil
  353.   end
  354.  
  355.   def self.n(file)  ## Returns a number from a file.
  356.     return CP::COMPOSITE::NAMES[file]
  357.   end
  358.  
  359.   def self.refreshed(file)  ## Resets a file's refresh status.
  360.     return unless n(file)
  361.     actor(file).composite_refresh = false
  362.   end
  363.  
  364.   def self.images(file)  ## Get all images of a file.
  365.     return @temp_images[file] if @temp_images && @temp_images[file]
  366.     return actor(file).composite_images
  367.   end
  368.  
  369.   def self.hues(file)  ## Get all hues of a file.
  370.     return @temp_hues[file] if @temp_hues && @temp_hues[file]
  371.     return actor(file).composite_hues
  372.   end
  373.  
  374.   def self.remove_temp_layers(file)  ## Removes temporary (save) layers.
  375.     @temp_images.delete(file) if @temp_images
  376.     @temp_hues.delete(file) if @temp_hues
  377.   end
  378.  
  379.   def self.make_temp_file(file, handlers)  ## Create a new temp of a file.
  380.     @temp_images = {} if @temp_images.nil?; @temp_hues = {} if @temp_hues.nil?
  381.     @temp_images[file] = {}; @temp_hues[file] = {}
  382.     handlers.each do |key, array|
  383.       @temp_images[file][key] = array[0]
  384.       @temp_hues[file][key] = array[1]
  385.     end
  386.   end
  387.  
  388.   def self.refresh?(file)  ## Check if a file needs refreshing.
  389.     return false unless n(file)  ## Includes temp file checking.
  390.     return true if @temp_images && @temp_images.include?(file)
  391.     return actor(file).composite_refresh
  392.   end
  393.  
  394.   def self.actor(file)  ## Gets a game actor from a file name.
  395.     return $game_actors[n(file)]
  396.   end
  397.  
  398.   def self.clear  ## Allows forced reset of each file.
  399.     CP::COMPOSITE::NAMES.keys.each do |file|
  400.       actor(file).composite_refresh = true
  401.     end
  402.   end
  403. end
  404.  
  405. class Game_Actor < Game_Battler
  406.   attr_accessor :composite_refresh
  407.  
  408.   alias cp_cmpst_init initialize
  409.   def initialize(*args)  ## Sets the initial values for composites.
  410.     cp_cmpst_init(*args)
  411.     @composite_refresh = true
  412.     @editor_changes = {}
  413.     @editor_hues = {}
  414.     @forced_composites = {}
  415.   end
  416.  
  417.   def composite_images  ## Returns the composite images for an actor.
  418.     make_composite_lists if @composite_refresh
  419.     return @composite_images
  420.   end
  421.  
  422.   def composite_hues  ## Returns the composite hues.
  423.     make_composite_lists if @composite_refresh
  424.     return @composite_hues
  425.   end
  426.  
  427.   def edd_additions(hueless, rear)  ## Make a new filename based on layers.
  428.     a = ""
  429.     b = hueless ? "#{a}Hueless" : a
  430.     c = rear ? "#{b}Rear" : b
  431.     return c
  432.   end
  433.  
  434.   def get_composite_lists  ## Gets a composite list for save files.
  435.     return {} unless Composites.include?(character_name)
  436.     make_composite_lists
  437.     r = {}
  438.     @composite_images.each {|k, v| r[k] = [v, @composite_hues[k]]}
  439.     return r
  440.   end
  441.  
  442.   def make_composite_lists  ## Makes the list of composites and hues.
  443.     @composite_images = {}
  444.     @composite_hues = {}
  445.     @composite_male = get_base_gender  ## Sets gender.
  446.     if CP::COMPOSITE::SWITCHES.include?(@actor_id)  ## Sets a gender switch.
  447.       $game_switches[CP::COMPOSITE::SWITCHES[@actor_id]] = @composite_male
  448.     end
  449.     block = @composite_male ? 0 : 1
  450.     make_equip_hashes(block)  ## Ensures equips are set up.
  451.     Composites.layers do |key|  ## Check each layer.
  452.       @composite_hues[key] = 0  ## Gets init values for variables.
  453.       name = nil
  454.       string = key.to_s
  455.       hueless = string.include?("Hueless")
  456.       rear = string.include?("Rear")
  457.       all = string.include?("All")
  458.       string.gsub!(/(Hueless|All|Rear)/, '')
  459.       edd = edd_additions(hueless, rear)
  460.       line = CP::COMPOSITE::GUI_OPTIONS[string.to_sym]
  461.       handler = get_composite_handler(key)
  462.       parent = get_composite_handler(string.to_sym)
  463.       hues = get_composite_hue(key)
  464.       if all && !line.nil?  ## Determines the needed value.
  465.         name = line[2]
  466.       elsif handler && Composites.files.include?(handler) &&
  467.             Composites.files[handler][block]
  468.         name = "#{Composites.files[handler][block]}#{edd}"
  469.       elsif parent && Composites.files.include?(parent) &&
  470.             Composites.files[parent][block] && (rear || hueless)
  471.         name = "#{Composites.files[parent][block]}#{edd}"
  472.       elsif Composites.standard.include?(key)
  473.         name = Composites.files[Composites.standard[key]][block]
  474.       end
  475.       next unless name  ## Skips if there is no name.
  476.       @composite_images[key] = name  ## Creates the hashes.
  477.       @composite_hues[key] = hueless ? 0 : hues
  478.     end
  479.   end
  480.  
  481.   def get_base_gender  ## Gets the gender.
  482.     return @editor_changes[:Gender] if @editor_changes.include?(:Gender)
  483.     return actor.gender_base
  484.   end
  485.  
  486.   def get_composite_handler(key)  ## Complex method to find the file handler.
  487.     block = @composite_male ? 0 : 1
  488.     if @forced_composites.include?(key) && Composites.include_block?(block,
  489.        @forced_composites[key][0])
  490.       hues = @forced_composites[key][0]
  491.     elsif @equip_hashes.include?(key) && Composites.include_block?(block,
  492.        @equip_hashes[key][0])
  493.       handler = @equip_hashes[key][0]
  494.     elsif @editor_changes.include?(key) && Composites.include_block?(block,
  495.           @editor_changes[key])
  496.       handler = @editor_changes[key]
  497.     elsif actor.composite_init.include?(key) && Composites.include_block?(block,
  498.           actor.composite_init[key][0])
  499.       handler = actor.composite_init[key][0]
  500.     elsif Composites.get_first_handler(block, key)
  501.       handler = Composites.get_first_handler(block, key)
  502.     else
  503.       handler = nil
  504.     end
  505.     return handler
  506.   end
  507.  
  508.   def get_composite_hue(key)  ## Same as above but for hues.
  509.     block = @composite_male ? 0 : 1
  510.     if @forced_composites.include?(key) && Composites.include_block?(block,
  511.        @forced_composites[key][0])
  512.       hues = @forced_composites[key][1]
  513.     elsif @equip_hashes.include?(key) && Composites.include_block?(block,
  514.        @equip_hashes[key][0])
  515.       hues = @equip_hashes[key][1]
  516.     elsif @editor_changes.include?(key) && Composites.include_block?(block,
  517.           @editor_changes[key])
  518.       hues = @editor_hues[key]
  519.     elsif actor.composite_init.include?(key) && Composites.include_block?(block,
  520.           actor.composite_init[key][0])
  521.       hues = actor.composite_init[key][1]
  522.     else
  523.       hues = 0
  524.     end
  525.     return hues
  526.   end
  527.  
  528.   def make_equip_hashes(block)  ## Makes the handler hash for equips.
  529.     @equip_hashes = {}
  530.     equips.each do |eq|
  531.       next unless eq
  532.       eq.composite_hash.each do |key, array|
  533.         next if Composites.files[array[0]][male? ? 0 : 1].nil?
  534.         @equip_hashes[key] = array
  535.       end
  536.     end
  537.   end
  538.  
  539.   alias cp_composite_change_eq change_equip
  540.   def change_equip(*args)  ## Ensures refreshing on equip change.
  541.     cp_composite_change_eq(*args)
  542.     @composite_refresh = true
  543.   end
  544.  
  545.   def change_composite(hand, value = nil, hue = nil)
  546.     array = ["#{hand}".to_sym, "#{hand}Rear".to_sym, "#{hand}Hueless".to_sym,
  547.              "#{hand}All".to_sym]
  548.     array.each do |handler|  ## Changes values for a layer and sublayers.
  549.       unless value.nil?
  550.         @editor_changes[handler] = value
  551.         @editor_hues[handler] = hue if hue
  552.       else
  553.         @editor_changes.delete(handler)
  554.         @editor_hues.delete(handler)
  555.       end
  556.     end
  557.     @composite_refresh = true
  558.   end
  559.  
  560.   def force_composite(hand, value = nil, hue = nil)
  561.     array = ["#{hand}".to_sym, "#{hand}Rear".to_sym, "#{hand}Hueless".to_sym,
  562.              "#{hand}All".to_sym]
  563.     array.each do |handler|  ## Changes values for a layer and sublayers.
  564.       unless value.nil?
  565.         @forced_composites[handler] = []
  566.         @forced_composites[handler][0] = value
  567.         @forced_composites[handler][1] = hue if hue
  568.       else
  569.         @forced_composites.delete(handler)
  570.       end
  571.     end
  572.     @composite_refresh = true
  573.   end
  574.  
  575.   def reset_composite
  576.     @forced_composites = {}
  577.     @composite_refresh = true
  578.   end
  579.  
  580.   def reset_name  ## Changes the name to a default name.
  581.     return if actor.alt_name.empty?
  582.     @composite_male = get_base_gender
  583.     if @composite_male == actor.gender_base
  584.       @name = actor.name if @name == actor.alt_name
  585.     else
  586.       @name = actor.alt_name if @name == actor.name
  587.     end
  588.   end
  589.  
  590.   def male?  ## Check if the actor is male.
  591.     return @composite_male
  592.   end
  593. end
  594.  
  595. class Window_SaveFile < Window_Base
  596.   def draw_party_characters(x, y)  ## Creates a temp array for the save file.
  597.     header = DataManager.load_header(@file_index)
  598.     return unless header
  599.     header[:characters].each_with_index do |data, i|
  600.       Composites.make_temp_file(data[0], data[2])
  601.       draw_character(data[0], data[1], x + i * 48, y)
  602.     end
  603.   end
  604. end
  605.  
  606. class Game_Party < Game_Unit
  607.   def characters_for_savefile  ## Adds the composite arrays to a save file.
  608.     battle_members.collect do |actor|
  609.       [actor.character_name, actor.character_index, actor.get_composite_lists]
  610.     end
  611.   end
  612. end
  613.  
  614. class Scene_Load < Scene_File  ## Clears the composites on a load.
  615.   alias cp_comp_load_succ on_load_success
  616.   def on_load_success
  617.     Composites.clear
  618.     cp_comp_load_succ
  619.   end
  620. end
  621.  
  622. class Scene_Save < Scene_File  ## Clears the composites on save.
  623.   alias cp_comp_save_ok on_savefile_ok
  624.   def on_savefile_ok
  625.     Composites.clear
  626.     cp_comp_save_ok
  627.   end
  628. end
  629.  
  630. class Bitmap
  631.   def draw_rainbow(*args)  ## Draws a rainbow rectangle.
  632.     case args.size
  633.     when 1
  634.       rect = args[0].clone
  635.     when 4
  636.       rect = Rect.new(args[0], args[1], args[2], args[3])
  637.     end
  638.     ca = rainbow_colours
  639.     6.times do |i|
  640.       wv = rect.width / (6 - i)
  641.       n = i == 5 ? 0 : 1
  642.       r2 = Rect.new(rect.x, rect.y, wv + n, rect.height)
  643.       self.gradient_fill_rect(r2, ca[i], ca[(i + 1) % 6])
  644.       rect.width -= wv
  645.       rect.x += wv
  646.     end
  647.   end
  648.  
  649.   def rainbow_colours  ## Colours for the rectangle.
  650.     c1 = Color.new(255,   0,   0); c2 = Color.new(255, 255,   0)
  651.     c3 = Color.new(  0, 255,   0); c4 = Color.new(  0, 255, 255)
  652.     c5 = Color.new(  0,   0, 255); c6 = Color.new(255,   0, 255)
  653.     return [c1, c2, c3, c4, c5, c6]
  654.   end
  655.  
  656.   @@wheel = Bitmap.new(360, 1)
  657.   @@wheel.draw_rainbow(0, 0, 360, 1)
  658.  
  659.   def self.hue_colour_wheel(hue)  ## Show the new hue colour.
  660.     if @@wheel.disposed?
  661.       @@wheel = Bitmap.new(360, 1)
  662.       @@wheel.draw_rainbow(0, 0, 360, 1)
  663.     end
  664.     return @@wheel.get_pixel(hue % 360, 0)
  665.   end
  666. end
  667.  
  668. ## The core bits of the script scene are below.
  669. class Window_CCFace < Window_Base
  670.   def initialize(actor, input)
  671.     super(0, 0, 120, 120)
  672.     self.visible = CP::COMPOSITE::USE_FACESETS
  673.     @input_window = input
  674.     self.y = @input_window.y
  675.     self.x = @input_window.x - (self.width + 8)
  676.     @actor = $data_actors[actor]
  677.     refresh
  678.   end
  679.  
  680.   def refresh
  681.     contents.clear
  682.     draw_face(@actor.face_name, @actor.face_index, 0, 0)
  683.   end
  684. end
  685.  
  686. class Window_CCCharacter < Window_Base
  687.   def initialize(actor, input)
  688.     super(0, 0, CP::COMPOSITE::WINDOW_WIDTH, CP::COMPOSITE::WINDOW_HEIGHT)
  689.     @input_window = input
  690.     self.y = @input_window.y
  691.     self.x = @input_window.x + @input_window.width + 8
  692.     @actor = $data_actors[actor]
  693.     @ticker = 10
  694.     @last_frame = 1
  695.     @frame = 1
  696.     refresh
  697.   end
  698.  
  699.   def update
  700.     @ticker += 1
  701.     @frame = (@ticker % 40) / 10; @frame = 1 if @frame == 3
  702.     return if @frame == @last_frame
  703.     @last_frame = @frame
  704.     refresh
  705.   end
  706.  
  707.   def refresh
  708.     contents.clear
  709.     x = contents.width / 2
  710.     y = contents.height - 6
  711.     draw_character(@actor.character_name, @actor.character_index, x, y, @frame)
  712.   end
  713.  
  714.   def draw_character(character_name, character_index, x, y, frame = 1)
  715.     return unless character_name
  716.     bitmap = Cache.character(character_name)
  717.     sign = character_name[/^[\!\$]./]
  718.     if sign && sign.include?('$')
  719.       cw = bitmap.width / 3
  720.       ch = bitmap.height / 4
  721.     else
  722.       cw = bitmap.width / 12
  723.       ch = bitmap.height / 8
  724.     end
  725.     n = character_index
  726.     src_rect = Rect.new((n%4*3+frame)*cw, (n/4*4)*ch, cw, ch)
  727.     ret_rect = Rect.new(x - cw, y - cw * 2, cw * 2, ch * 2)
  728.     contents.stretch_blt(ret_rect, bitmap, src_rect)
  729.   end
  730. end
  731.  
  732. class Window_CCGui < Window_Selectable
  733.   def initialize(file, list)
  734.     @list = list
  735.     extra_width = CP::COMPOSITE::WINDOW_WIDTH + 8
  736.     extra_width += 128 if CP::COMPOSITE::USE_FACESETS
  737.     x = (Graphics.width - (180 + extra_width)) / 2
  738.     x += 128 if CP::COMPOSITE::USE_FACESETS
  739.     y = (Graphics.height - window_height) / 2
  740.     h = window_height
  741.     super(x, y, 180, h)
  742.     @file = file
  743.     refresh
  744.   end
  745.  
  746.   def window_height
  747.     [fitting_height(item_max * 2), Graphics.height].min
  748.   end
  749.  
  750.   def item_max
  751.     @list.size + 1
  752.   end
  753.  
  754.   def contents_height
  755.     (item_max * 2) * line_height
  756.   end
  757.  
  758.   def item_height
  759.     line_height * 2
  760.   end
  761.  
  762.   def refresh
  763.     contents.clear
  764.     draw_all_items
  765.   end
  766.  
  767.   def data
  768.     @list[@index]
  769.   end
  770.  
  771.   def adj_data
  772.     if Composites.options[data][0].is_a?(Symbol)
  773.       return Composites.options[data][0]
  774.     else
  775.       return data
  776.     end
  777.   end
  778.  
  779.   def draw_item(index)
  780.     rect = item_rect(index)
  781.     lh = line_height
  782.     if index == @list.size
  783.       text = CP::COMPOSITE::GUI_CLOSE
  784.       change_color(normal_color)
  785.       draw_text(rect.x + 2, rect.y + lh / 2, rect.width - 4, lh, text, 1)
  786.     else
  787.       block = Composites.options[@list[index]]
  788.       if block[0].is_a?(Symbol)
  789.         title = Composites.options[block[0]][0]
  790.       else
  791.         title = block[0]
  792.       end
  793.       value = (CP::COMPOSITE::COMPOSITE.include?(@list[index]) ||
  794.               @list[index] == :Gender || @list[index] == :Name)
  795.       sym = value ? @list[index] : block[0]
  796.       change_color(system_color)
  797.       draw_text(rect.x + 2, rect.y, rect.width - 4, lh, title)
  798.       case sym
  799.       when :Gender
  800.         na = CP::COMPOSITE::GENDER_NAMES
  801.         name = Composites.actor(@file).male? ? na[0] : na[1]
  802.       when :Name
  803.         name = Composites.actor(@file).name
  804.       else
  805.         name = Composites.actor(@file).get_composite_handler(sym)
  806.         name = CP::COMPOSITE::EMPTY_TEXT if name.nil?
  807.         hue = Composites.actor(@file).get_composite_hue(sym)
  808.         if block[1]
  809.           c1 = Bitmap.hue_colour_wheel(hue)
  810.           c2 = Color.new(c1.red, c1.green, c1.blue, 0)
  811.           r2 = contents.text_size(name).width
  812.           hr = Rect.new(contents.width - (r2 + 6), rect.y + lh + 3, r2 + 1, lh - 6)
  813.           contents.gradient_fill_rect(hr, c2, c1)
  814.         end
  815.       end
  816.       change_color(normal_color)
  817.       draw_text(rect.x + 2, rect.y + lh, rect.width - 6, lh, name, 2)
  818.     end
  819.   end
  820. end
  821.  
  822. class Window_CCSelect < Window_Selectable
  823.   attr_reader :hue
  824.  
  825.   def initialize(file, input)
  826.     super(0, 0, 160, 0)
  827.     @input_window = input
  828.     @file = file
  829.     @data = nil
  830.     @hue = 0
  831.   end
  832.  
  833.   def item_max
  834.     return 1 if @data.nil? || @data.empty?
  835.     return @data.size
  836.   end
  837.  
  838.   def refresh
  839.     contents.clear
  840.     draw_all_items
  841.     draw_hue_wheel
  842.   end
  843.  
  844.   def draw_item(index)
  845.     rect = item_rect(index); rect.x += 2; rect.width -= 4
  846.     change_color(normal_color)
  847.     draw_text(rect, @data[index])
  848.   end
  849.  
  850.   def draw_hue_wheel
  851.     rect = item_rect(item_max); contents.clear_rect(rect)
  852.     rect.y += 4; rect.height -= 8; rect.x += 8; rect.width -= 16
  853.     ind = Composites.options[@input_window.data]
  854.     return if !ind || ind[1] == 0
  855.     if ind[1] == 2
  856.       value = @hue >= 180 ? @hue - 360 : @hue
  857.       rect.height /= 2; rect.height -= 1; rect.x -= 60
  858.       contents.draw_rainbow(rect)
  859.       rect.y += (rect.height + 1); rect.x -= value / 3
  860.       contents.draw_rainbow(rect)
  861.       rect.x += 119
  862.       contents.draw_rainbow(rect)
  863.       rect.y -= (rect.height + 1); rect.x += value / 3
  864.       contents.draw_rainbow(rect)
  865.       bitmap2 = Bitmap.new(10, 19)
  866.       bitmap2.fill_rect(0, 0, 10, 19, Color.new(255, 255, 255))
  867.       c1 = Bitmap.hue_colour_wheel(0)
  868.       c2 = Bitmap.hue_colour_wheel(@hue)
  869.       bitmap2.gradient_fill_rect(1, 1, 8, 17, c1, c2, true)
  870.       rect = item_rect(item_max)
  871.       contents.blt((rect.width - 10) / 2, rect.y + 2, bitmap2, bitmap2.rect)
  872.       rect.width = 10
  873.       contents.clear_rect(rect)
  874.       rect.x = contents.width - rect.width
  875.       contents.clear_rect(rect)
  876.     elsif ind[1] == 1
  877.       contents.draw_rainbow(rect)
  878.       bitmap2 = Bitmap.new(7, 20)
  879.       bitmap2.fill_rect(0, 0, 7, 20, Color.new(255, 255, 255))
  880.       bitmap2.fill_rect(1, 2, 5, 16, Bitmap.hue_colour_wheel(@hue))
  881.       off = @hue / 3
  882.       contents.blt(rect.x - 3 + off, rect.y - 2, bitmap2, bitmap2.rect)
  883.     end
  884.   end
  885.  
  886.   def show
  887.     val = @input_window.adj_data
  888.     ind = @input_window.data
  889.     actor = Composites.actor(@file)
  890.     block = Composites.actor(@file).male? ? 0 : 1
  891.     @name = Composites.list_by_block(ind, block).index(actor.get_composite_handler(val))
  892.     @index = val != :Gender ? @name : Composites.actor(@file).male? ? 0 : 1
  893.     @index = 0 if @index.nil?
  894.     @hue = actor.get_composite_hue(val) unless val == :Gender
  895.     cont = Composites.options[ind]
  896.     if val == :Gender
  897.       @data = CP::COMPOSITE::GENDER_NAMES
  898.     else
  899.       @data = Composites.list_by_block(ind, block)
  900.     end
  901.     add = Composites.options[ind][1] ? 1 : 0
  902.     add = 0 if val == :Gender
  903.     self.height = fitting_height(@data.size + add)
  904.     create_contents
  905.     refresh
  906.     self.x = @input_window.x + 16
  907.     iw = @input_window
  908.     self.y = iw.y + iw.standard_padding + (iw.index * (iw.line_height * 2)) - iw.oy + 28
  909.     self.y = Graphics.height - self.height if y + height > Graphics.height
  910.     super
  911.     activate
  912.   end
  913.  
  914.   def cursor_right(wrap)
  915.     return if Composites.options.include?(@input_window.data) &&
  916.               !Composites.options[@input_window.data][1]
  917.     @hue /= 12; @hue *= 12
  918.     @hue += 12; @hue -= 360 if @hue >= 360
  919.     draw_hue_wheel
  920.   end
  921.  
  922.   def cursor_left(wrap)
  923.     return if Composites.options.include?(@input_window.data) &&
  924.               !Composites.options[@input_window.data][1]
  925.     @hue /= 12; @hue *= 12
  926.     @hue -= 12; @hue += 360 if @hue < 0
  927.     draw_hue_wheel
  928.   end
  929. end
  930.  
  931. class Game_Interpreter
  932.   def creation(char, list = nil)  ## Allows for easy calling of the scene.
  933.     return if $game_party.in_battle
  934.     if char.is_a?(Integer)
  935.       return unless CP::COMPOSITE::NAMES.has_value?(char)
  936.       char = CP::COMPOSITE::NAMES.index(char)
  937.     else
  938.       return unless Composites.include?(char)
  939.     end
  940.     list = CP::COMPOSITE::BASE_GUI if list.nil?
  941.     return unless list.is_a?(Array)
  942.     SceneManager.call(Scene_CharacterCreation)
  943.     SceneManager.scene.prepare(char, list)
  944.     Fiber.yield
  945.   end
  946.  
  947.   def composite_force(char, handler, name, hue = 0)
  948.     if char.is_a?(Integer)
  949.       return unless CP::COMPOSITE::NAMES.has_value?(char)
  950.     else
  951.       return unless Composites.include?(char)
  952.       char = CP::COMPOSITE::NAMES[char]
  953.     end
  954.     $game_actors[char].force_composite(handler, name, hue)
  955.   end
  956.  
  957.   def composite_custom(char, handler, name, hue = 0)
  958.     if char.is_a?(Integer)
  959.       return unless CP::COMPOSITE::NAMES.has_value?(char)
  960.     else
  961.       return unless Composites.include?(char)
  962.       char = CP::COMPOSITE::NAMES[char]
  963.     end
  964.     $game_actors[char].change_composite(handler, name, hue)
  965.   end
  966.  
  967.   def composite_reset(char)
  968.     if char.is_a?(Integer)
  969.       return unless CP::COMPOSITE::NAMES.has_value?(char)
  970.     else
  971.       return unless Composites.include?(char)
  972.       char = CP::COMPOSITE::NAMES[char]
  973.     end
  974.     $game_actors[char].reset_composite
  975.   end
  976. end
  977.  
  978. class Scene_CharacterCreation < Scene_MenuBase
  979.   def prepare(file, list)
  980.     @file = file
  981.     @list = list
  982.   end
  983.  
  984.   def start
  985.     super
  986.     @actor = Composites.actor(@file)
  987.     create_windows
  988.   end
  989.  
  990.   def create_windows
  991.     @input_window = Window_CCGui.new(@file, @list)
  992.     @input_window.set_handler(:ok,      method(:gui_ok))
  993.     @input_window.set_handler(:cancel,  method(:gui_cancel))
  994.     @select_window = Window_CCSelect.new(@file, @input_window)
  995.     @select_window.set_handler(:ok,     method(:select_ok))
  996.     @select_window.set_handler(:cancel, method(:select_cancel))
  997.     @chara_window = Window_CCCharacter.new(@actor.id, @input_window)
  998.     @face_window = Window_CCFace.new(@actor.id, @input_window)
  999.     @input_window.activate.select(0)
  1000.     @select_window.hide
  1001.   end
  1002.  
  1003.   def gui_ok
  1004.     val = @input_window.data
  1005.     if val == :Name
  1006.       SceneManager.call(Scene_Name)
  1007.       SceneManager.scene.prepare(Composites.actor(@file).id, CP::COMPOSITE::CHARACTERS)
  1008.       @input_window.refresh
  1009.     elsif val == nil
  1010.       return_scene
  1011.     else
  1012.       @select_window.show
  1013.     end
  1014.   end
  1015.  
  1016.   def gui_cancel
  1017.     @input_window.activate.select(@input_window.item_max - 1)
  1018.   end
  1019.  
  1020.   def select_ok
  1021.     val = @input_window.data
  1022.     adj = @input_window.adj_data
  1023.     id = @select_window.index
  1024.     if adj == :Gender
  1025.       if id == 0
  1026.         Composites.actor(@file).change_composite(:Gender, true)
  1027.         Composites.actor(@file).reset_name
  1028.       elsif id == 1
  1029.         Composites.actor(@file).change_composite(:Gender, false)
  1030.         Composites.actor(@file).reset_name
  1031.       end
  1032.     else
  1033.       block = Composites.actor(@file).male? ? 0 : 1
  1034.       handler = Composites.list_by_block(val, block)[@select_window.index]
  1035.       hue = @select_window.hue
  1036.       Composites.actor(@file).change_composite(adj, handler, hue)
  1037.     end
  1038.     @select_window.hide
  1039.     @chara_window.refresh
  1040.     @face_window.refresh
  1041.     @input_window.activate.refresh
  1042.   end
  1043.  
  1044.   def select_cancel
  1045.     @select_window.hide
  1046.     @input_window.activate
  1047.   end
  1048. end
  1049.  
  1050. class RPG::BaseItem
  1051.   def composite_hash
  1052.     add_composite_data if @composite_hash.nil?
  1053.     return @composite_hash
  1054.   end
  1055.  
  1056.   def composite_init
  1057.     add_composite_data if @composite_init.nil?
  1058.     return @composite_init
  1059.   end
  1060.  
  1061.   def gender_base
  1062.     add_composite_data if @gender_base.nil?
  1063.     return @gender_base
  1064.   end
  1065.  
  1066.   def alt_name
  1067.     add_composite_data if @alt_name.nil?
  1068.     return @alt_name
  1069.   end
  1070.  
  1071.   INITI_RE = /(.+) init\[(.+)[,]\s*(\d+)\]/i
  1072.   IMAGE_RE = /(.+) image\[(.+)[,]\s*(\d+)\]/i
  1073.   GENDER_RE = /gender\[(male|female)\]/i
  1074.   ALT_NAME = /alt name\[(.+)\]/i
  1075.  
  1076.   def add_composite_data
  1077.     @gender_base = CP::COMPOSITE::MALE_DEFAULT
  1078.     @composite_hash = {}; @composite_init = {}; @alt_name = ""
  1079.     self.note.split(/[\r\n]+/).each do |line|
  1080.       case line
  1081.       when INITI_RE
  1082.         @composite_init[$1.to_sym] = [$2.to_s, $3.to_i]
  1083.         @composite_init["#{$1.to_s}Rear".to_sym] = [$2.to_s, $3.to_i]
  1084.         @composite_init["#{$1.to_s}Hueless".to_sym] = [$2.to_s, 0]
  1085.         @composite_init["#{$1.to_s}All".to_sym] = [$2.to_s, $3.to_i]
  1086.       when IMAGE_RE
  1087.         @composite_hash[$1.to_sym] = [$2.to_s, $3.to_i]
  1088.         @composite_hash["#{$1.to_s}Rear".to_sym] = [$2.to_s, $3.to_i]
  1089.         @composite_hash["#{$1.to_s}Hueless".to_sym] = [$2.to_s, 0]
  1090.         @composite_hash["#{$1.to_s}All".to_sym] = [$2.to_s, $3.to_i]
  1091.       when GENDER_RE
  1092.         @gender_base = true if $1.to_s.downcase == "male"
  1093.         @gender_base = false if $1.to_s.downcase == "female"
  1094.       when ALT_NAME
  1095.         @alt_name = $1.to_s
  1096.       end
  1097.     end
  1098.   end
  1099. end
  1100.  
  1101. ###--------------------------------------------------------------------------###
  1102. #  End of script.                                                              #
  1103. ###--------------------------------------------------------------------------###
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement