Hime-Works / Requests

Bug reports and requests that may require longer discussions and is not suitable to leave on the blog
http://himeworks.com/
GNU General Public License v2.0
7 stars 9 forks source link

Character Creator #279

Open KeishiiNeko opened 9 years ago

KeishiiNeko commented 9 years ago

I'm using your character creator and for some reason it is displaying the wrong character even though I'm using all the default sheets. When the character is made it sets the correct character. Is there a way to remove the character window and just have it set the character to the corresponding face graphic?

rubydragon44 commented 9 years ago

Isn't that script unsupported now?

HimeWorks commented 9 years ago

I did this at some point since someone else asked about it

=begin
==============================================================================
 ** Actor Creation System
 Author: Hime
 Date: Apr 25, 2013
------------------------------------------------------------------------------
 ** Change log
 Apr 25, 2013
   -updated to custom database's new API
 Dec 14, 2012
   -refreshed the player character after updating character sprite
   -add_bonus_stats method added to Scene_ActorCreate
   -fixed bug where wrong face/char is shown when scene begins
 Nov 28
   -fixed issue where actor fields are empty or null
   -removed name processing. Use normal name processing command for that
 May 26
   -fixed issue where actor didn't have a face, or the sheet containing
    the face was not loaded
 May 25
   -fixed equip stats bug
   -fixed bonus stats bug
   -added option to add specific actor to party by preparing the scene
 May 22
   -Added field locking
   -Can update existing actor information
   -Serves as stat distribution feature
 May 21, 2012
   -Initial release
------------------------------------------------------------------------------
 Create new actors during the game!
 Access the scene using the script call

   SceneManager.call(Scene_ActorCreate)

 If you want to modify an existing actor, you must
 prepare the scene with an extra call

   SceneManager.scene.prepare(actor_id, class_fixed?, face_fixed?, char_fixed?)

 The actor ID must be one of the actors that are currently in the game.
 The rest of the arguments are for locking fields from editing

 If you want to add bonus stats when the scene has been accessed, you can use

   SceneManager.scene.add_bonus_stats(n)

 For some integer n.

 You can lock or unlock classes with the following script calls

   $game_system.lock_class(n)
   $game_system.unlock_class(n)

 Where n is the class ID.

 You can choose your actor face and character sprite, 
 as well as class ID. You can distribute bonus stats
 as well.

 Once you have completed your selection, press OK and
 you will be asked to choose a name for your new 
 actor.

 After you've chosen a name the actor will be added
 to your party ready to explore.

 At the top of the script there is some configuration.
 In particular, if you want to add more faces and character
 sprites, you just have to add the filenames to the lists.
 Note that I'm assuming you're using Ace's 4x2 sprite sheets.
==============================================================================
=end
$imported = {} if $imported.nil?
$imported["Tsuki_ActorCreation"] = true
#==============================================================================
# ** Configuration. 
#==============================================================================

module Tsuki
  module Actor_Creation

    # show the change command in party menu
    Show_Change_Command = false

    # Keep exp when changing classes?
    Keep_Exp = true

    # Enter the filenames of all of the faces you would like to choose
    # Note that they must be the Ace standard 8 face sheets
    Faces = ["Actor1","Actor2","Actor3","Actor4","Actor5"]

    # Filenames of all character sprites you would like to choose
    # Note that they must be the Ace standard 8 character sheets
    Chars = ["Actor1","Actor2","Actor3","Actor4","Actor5"]

    # max character name length
    Max_Chars = 6

    # How much of that stat is given per stat point allocated
    #   mhp, mmp, atk, def, mat, mdf, agi, luk
    Param_Rate = [10, 5, 1, 1, 1, 1, 1, 1]

    # Minimum that you can have of a particular stat
    Min_Params = [1, 0, 0, 0, 0, 0, 0, 0]
  end
end

module RPG
  class Actor < BaseItem
    attr_accessor :bonus_params
    attr_accessor :bonus_stats

    alias :tsuki_actor_create_initialize_rpg_actor :initialize
    def initialize
      tsuki_actor_create_initialize_rpg_actor
      load_notetags_actor_creation
    end

    def load_notetags_actor_creation
      @bonus_params = [0] * 8
      @bonus_stats = 0
    end
  end
end

module DataManager

  class << self
    alias actor_creation_load_database load_database
    alias actor_creation_init init
  end

  def self.init
    actor_creation_init
    load_notetags_actor_creation
  end

  def self.load_database
    actor_creation_load_database
    if $BTEST
      load_notetags_actor_creation
    end
  end

  def self.load_notetags_actor_creation
    groups = [$data_actors]
    for group in groups
      for obj in group
        next if obj.nil?
        obj.load_notetags_actor_creation
      end
    end
  end
end

class Game_System

  attr_reader :locked_classes
  alias th_actor_create_initialize initialize
  def initialize
    th_actor_create_initialize
    @locked_classes = []
  end

  def lock_class(class_id)
    @locked_classes << class_id
  end

  def unlock_class(class_id)
    @locked_classes.delete(class_id)
  end
end

class Game_Actor

  attr_accessor :bonus_params
  attr_accessor :bonus_stats
  alias th_actor_create_setup_actor setup
  def setup(actor_id)
    th_actor_create_setup_actor(actor_id)
    @bonus_params = actor.bonus_params
    @bonus_stats = actor.bonus_stats
  end

  alias :th_actor_create_clear_param_plus :clear_param_plus
  def clear_param_plus
    @bonus_params = [0] * 8
    th_actor_create_clear_param_plus
  end

  alias :th_actor_create_param_plus :param_plus
  def param_plus(param_id)
    @bonus_params[param_id] + th_actor_create_param_plus(param_id)
  end

  def add_bonus_stats(amount)
    @bonus_stats = [0, @bonus_stats + amount].max
  end
end

class Game_Actors

  def size
    @data.size
  end

  def add_actor(actor)
    @data << actor
  end
end

class Game_Party < Game_Unit

  def has_actor?(actor_id)
    @actors.include?(actor_id)
  end
end

class Window_MenuCommand < Window_Command
  include Tsuki::Actor_Creation
  #--------------------------------------------------------------------------
  # * Add arena command to List
  #--------------------------------------------------------------------------
  alias :th_actor_create_commands :add_main_commands
  def add_main_commands
    th_actor_create_commands
    add_command("Change", :change )if Show_Change_Command
  end
end

class Scene_Menu < Scene_MenuBase
  include Tsuki::Actor_Creation
  #--------------------------------------------------------------------------
  # * Add arena handler
  #--------------------------------------------------------------------------
  alias :th_actor_create_command_window :create_command_window
  def create_command_window
    th_actor_create_command_window
    @command_window.set_handler(:change, method(:command_personal)) if Show_Change_Command
  end

  alias :th_actor_create_personal_ok :on_personal_ok
  def on_personal_ok
    th_actor_create_personal_ok
    case @command_window.current_symbol
    when :change
      command_change
    end
  end

  def command_change
    SceneManager.call(Scene_ActorCreate)
    actor_id = $game_party.members[@status_window.index].id
    SceneManager.scene.prepare(actor_id, false)
  end
end

#==============================================================================
# ** Actor creation scene
#==============================================================================
class Scene_ActorCreate < Scene_Base
  include Tsuki::Actor_Creation

  def start
    super
    create_all_windows
    @face_fix = false
    @char_fix = false
    @class_fix = false
    @face_window.activate
  end

  def prepare(actor_id, class_fix=true, face_fix=true, char_fix=true)
    @actor = $game_actors[actor_id] if actor_id && actor_id > 0
    @face_fix = face_fix
    @char_fix = char_fix
    @class_fix = class_fix
  end

  def create_all_windows
    create_background_window
    create_face_status_window
    #create_char_status_window
    create_face_window
    #create_character_window
    create_class_window
    create_stats_window
    create_confirm_window
  end

  def create_confirm_window
    wx = Graphics.width / 2
    wy = Graphics.height / 2
    @confirm_window = Window_Confirm.new(wx, wy)
    @confirm_window.set_handler(:ok, method(:on_confirm_ok))
    @confirm_window.set_handler(:cancel, method(:on_confirm_cancel))
  end

  def create_background_window
    @status_window = Window_ActorCreateStatus.new
  end

  def create_face_status_window
    @face_status_window = Window_ActorCreateFaceStatus.new(20, 20)
  end

  def create_char_status_window
    wx = @face_status_window.x + @face_status_window.width - 10
    wy = @face_status_window.y
    @char_status_window = Window_ActorCreateCharStatus.new(wx, wy)
  end

  def create_face_window
    wx = 180
    @face_window = Window_ActorCreateFace.new(wx, 20)
    @face_window.set_handler(:ok, method(:on_confirm))
    @face_window.set_handler(:cancel, method(:return_scene))
    @face_window.set_handler(:DOWN, method(:on_face_next))
    @face_window.status_window = @face_status_window
    @face_window.actor = @actor
    @face_window.fixed = @face_fix
  end

  def create_character_window
    wx = @face_window.x
    wy = @face_window.y + @face_window.height - 20
    @char_window = Window_ActorCreateChar.new(wx, wy)
    @char_window.set_handler(:ok, method(:on_confirm))
    @char_window.set_handler(:cancel, method(:return_scene))
    @char_window.set_handler(:UP, method(:on_char_prev))
    @char_window.set_handler(:DOWN, method(:on_char_next))
    @char_window.status_window = @char_status_window
    @char_window.actor = @actor
    @char_window.fixed = @char_fix
  end

  def create_class_window
    wx = @face_window.x
    wy = @face_window.y + @face_window.height - 20
    @class_window = Window_ActorCreateClass.new(wx, wy)
    @class_window.set_handler(:ok, method(:on_confirm))
    @class_window.set_handler(:cancel, method(:return_scene))
    @class_window.set_handler(:UP, method(:on_class_prev))
    @class_window.set_handler(:DOWN, method(:on_class_next))
    @class_window.actor = @actor
    @class_window.fixed = @class_fix
  end

  def create_stats_window
    wx = 0
    wy = @class_window.y + @class_window.height + 24
    width = 300
    height = Graphics.height - wy
    @stats_window = Window_ActorCreateStats.new(wx, wy, width, height)
    @stats_window.set_handler(:UP, method(:on_stats_prev))
    @stats_window.set_handler(:ok, method(:on_confirm))
    @stats_window.set_handler(:cancel, method(:return_scene))
    @stats_window.actor = @actor
    @class_window.stats_window = @stats_window
  end

  def on_face_next
    @face_window.deactivate
    @class_window.activate
  end

  def on_class_prev
    @class_window.deactivate
    @face_window.activate
  end

  def on_char_prev
    @char_window.deactivate
    @face_window.activate
  end

  def on_char_next
    @char_window.deactivate
    @class_window.activate
  end

  def on_class_next
    @stats_window.activate
    @class_window.deactivate
  end

  def on_stats_prev
    @stats_window.deactivate
    @class_window.activate
  end

  def on_confirm
    @face_window.deactivate
    @char_window.deactivate
    @class_window.deactivate
    @stats_window.deactivate
    @confirm_window.activate.show
  end

  def on_confirm_ok
    if @actor
      if $game_party.has_actor?(@actor.id)
        update_actor(@actor.id)
        return_scene
      else
        update_actor(@actor.id) # update the actor and add to party
        $game_party.add_actor(@actor.id)
        return_scene
#~         SceneManager.call(Scene_Name)
#~         SceneManager.scene.prepare(@actor.id, Max_Chars)
      end
    else
      actor_id = create_actor
      return_scene
    end
    $game_player.refresh
  end

  def on_confirm_cancel
    @confirm_window.deactivate.hide
    @face_window.activate
  end

  def create_actor
    actor_id = $data_actors.size
    actor = make_new_actor(actor_id)
    update_data(actor)
    add_actor(actor_id)
    return actor_id
  end

  def update_actor(actor_id)
    game_actor = $game_actors[actor_id]
    game_actor.change_class(@class_window.index + 1, Keep_Exp)

    char_name = @char_status_window.character_name
    char_index = @char_status_window.character_index
    face_name = @face_status_window.face_name
    face_index = @face_status_window.face_index
    game_actor.set_graphic(char_name, char_index, face_name, face_index)
    game_actor.bonus_params = @stats_window.bonus_params
    game_actor.bonus_stats = @stats_window.bonus
  end

  def make_new_actor(actor_id)
    actor = RPG::Actor.new
    actor.id = actor_id
    actor.class_id = @class_window.index + 1
    actor.character_name = @char_status_window.character_name
    actor.character_index = @char_status_window.character_index
    actor.face_name = @face_status_window.face_name
    actor.face_index = @face_status_window.face_index
    actor.bonus_params = @stats_window.bonus_params
    actor.bonus_stats = @stats_window.bonus
    setup_extra(actor)
    return actor
  end

  def setup_extra(actor)
    # need extensions?
  end

  def update_data(actor)
    CustomData.add_actor(actor)
  end

  def add_actor(actor_id)
    game_actor = Game_Actor.new(actor_id)
    $game_actors.add_actor(game_actor)
    $game_party.add_actor(actor_id)
  end

  def add_bonus_stats(amount)
    @actor.add_bonus_stats(amount) if @actor
  end
end

#==============================================================================
# ** Actor Creation windows
#==============================================================================
class Window_ActorHorzCommand < Window_HorzCommand
  include Tsuki::Actor_Creation

  attr_accessor :fixed
  def initialize(x, y)
    super
    self.index = 0
    self.back_opacity = 0
    self.opacity = 0
    @last_index = 0
    @actor = nil
    @fixed = false
  end

  def actor=(actor)
    return if @actor == actor
    @actor = actor
    refresh
  end

  def cursor_right(wrap = false)
    if !@fixed && (index < item_max - 1 || (wrap && horizontal?))
      select((index + 1) % item_max)
    end
  end

  def cursor_left(wrap = false)
    if !@fixed && (index > 0 || (wrap && horizontal?))
      select((index - 1 + item_max) % item_max)
    end
  end

  def top_col=(col)
    col = 0 if col < 0
    self.ox = col * (item_width + spacing)
  end

  def unselect
    @last_index = self.index
  end

  def select_last
    select(@last_index)
  end

  def cursor_down(wrap = false)
    call_handler(:DOWN)
    Sound.play_cursor
    Input.update
  end

  def cursor_up(wrap = false)
    call_handler(:UP)
    Sound.play_cursor
    Input.update
  end

  def col_max
    1
  end

  def deactivate
    unselect
    super
  end

  def activate
    select_last
    super
  end
end

class Window_ActorCreateFace < Window_ActorHorzCommand

  def make_command_list
    n = 1
    Faces.each do |filename|
      8.times do |i|
        name = "Face %d" %n
        add_command(name, name.to_sym)
        n += 1
      end
    end
  end

  def update
    super
    @status_window.face = index
  end

  def status_window=(window)
    @status_window = window
  end

  def refresh
    super
    return unless @actor
    @sheet = Faces.index(@actor.face_name)
    @last_index = @sheet ? @sheet * 8 + @actor.face_index : 0
    select(@last_index)
  end
end

class Window_ActorCreateClass < Window_ActorHorzCommand

  def initialize(x, y)
    super
    deactivate
  end

  def make_command_list
    $data_classes.each do |cls|
      next if cls.nil? || $game_system.locked_classes.include?(cls.id)
      add_command(cls.name, cls.name.to_sym)
    end
  end

  def update
    super
    refresh_stats if @stats_window
  end

  def refresh
    super
    return unless @actor
    @last_index = @actor.class_id - 1
    select(@last_index)
  end

  def refresh_stats
    @stats_window.class = index + 1
  end

  def stats_window=(window)
    return unless window
    @stats_window = window
    refresh
  end
end

class Window_ActorCreateChar < Window_ActorHorzCommand

  def initialize(x, y)
    super
    deactivate
  end

  def make_command_list
    n = 1
    Chars.each do |filename|
      8.times do |i|
        name = "Character %d" %n
        add_command(name, name.to_sym)
        n += 1
      end
    end
  end

  def update
    super
    @status_window.char = index
  end

  def status_window=(window)
    @status_window = window
  end

  def refresh
    super
    return unless @actor
    return 0 if @actor.character_name.nil? || @actor.character_name.empty?
    @sheet = Chars.index(@actor.character_name)
    @last_index = @sheet * 8 + @actor.character_index
    select(@last_index)
  end
end

class Window_ActorCreateStats < Window_Selectable
  include Tsuki::Actor_Creation

  attr_reader :bonus_params
  attr_reader :bonus
  def initialize(x, y, width, height)
    super
    deactivate
    self.back_opacity = 0
    self.opacity = 0
    @bonus = 0
    @actor = nil
    @curr_class = $data_classes[1]
    @param_rate = Param_Rate.clone
    @param_min = Min_Params.clone
    @params = [0]*8
    @bonus_params = [0]*8
    refresh_params
    refresh
  end

  def make_item_list
    @data = $data_system.terms.params
  end

  def item_max
    @data ? @data.size : 1
  end

  def draw_bonus
    draw_text(0, 200, 100, line_height, "Bonus", 1)
    draw_text(100, 200, 100, line_height, @bonus, 1)
  end

  def draw_item(index)
    item = @data[index]
    if item
      rect = item_rect(index)
      rect.width -= 4
      change_color(normal_color)
      draw_text(rect.x, rect.y, 100, line_height, item, 1)
      draw_text(rect.x + 100, rect.y, 100, line_height, @params[index], 1)
      draw_bonus_param(@bonus_params[index], rect.x+140, rect.y)
    end
  end

  def draw_bonus_param(param, x, y)
    if param >= 0
      change_color(text_color(16))
      draw_text(x, y, 100, line_height, "+ %d" %param, 2)
    else
      change_color(text_color(9))
      draw_text(x, y, 100, line_height, "- %d" %param.abs, 2)
    end
  end

  def refresh
    make_item_list
    create_contents
    draw_bonus
    draw_all_items
  end

  def refresh_actor
    8.times do |i|
      @params[i] = @actor.param(i) - @actor.bonus_params[i]
    end
    @bonus_params = @actor.bonus_params
    @bonus = @actor.bonus_stats
  end

  def refresh_class
    level = @actor ? @actor.level : 1
    8.times do |i|
      @params[i] = @curr_class.params[i, level]
    end
  end

  def refresh_params
    refresh_actor if @actor
    refresh_class if @curr_class
  end

  def cursor_right(wrap = false)
    if @bonus > 0
      @bonus_params[index] += @param_rate[index]
      @bonus -= 1
      Sound.play_ok
    else
      Sound.play_buzzer
    end
    refresh
  end

  def cursor_left(wrap = false)
    if @bonus_params[index] > @param_min[index]
      @bonus_params[index] -= @param_rate[index]
      @bonus += 1
      Sound.play_ok
    else
      Sound.play_buzzer
    end
    refresh
  end

  def cursor_up(wrap = false)
    if index == 0
      call_handler(:UP)
      Input.update
    else
      super
    end
  end

  def activate
    select(0)
    super
  end

  def deactivate
    unselect
    super
  end

  def actor=(actor)
    return if @actor == actor
    @actor = actor
    refresh_actor
    refresh
  end

  def class=(new_class)
    return if @curr_class.id == new_class
    @curr_class = $data_classes[new_class]
    refresh_class
    refresh
  end
end

class Window_ActorCreateStatus < Window_Base

  def initialize
    super(0, 0, Graphics.width, Graphics.height)
  end
end

class Window_ActorCreateFaceStatus < Window_Base
  include Tsuki::Actor_Creation

  attr_reader :face_name
  attr_reader :face_index
  def initialize(x, y)
    super(x, y, window_width, window_height)
    @f_index = -1
    @face_name = ""
    @face_index = -1
    self.opacity = 0
    refresh
  end

  def window_width
    120
  end

  def window_height
    120
  end

  def face=(index)
    return if @f_index == index
    @f_index = index
    refresh
  end

  def redraw_face
    if @f_index >= 0
      @face_name = Faces[@f_index / 8]
      @face_index = @f_index % 8
      draw_face(@face_name, @face_index, 0, 0)
    end
  end

  def refresh
    contents.clear
    redraw_face
  end
end

class Window_ActorCreateCharStatus < Window_Base
  include Tsuki::Actor_Creation

  attr_reader :character_name
  attr_reader :character_index
  def initialize(x, y)
    super(x, y, window_width, window_height)
    @c_index = -1
    self.opacity = 0
    @character_name = ""
    @character_index = -1
    refresh
  end

  def window_width
    56
  end

  def window_height
    56
  end

  def char=(index)
    return if @c_index == index
    @c_index = index
    refresh
  end

  def redraw_char
    if @c_index >= 0
      @character_name = Chars[@c_index / 8]
      @character_index = @c_index % 8
      draw_character(@character_name, @character_index, 16, 32)
    end
  end

  def refresh
    contents.clear
    redraw_char
  end
end

class Window_Confirm < Window_Command

  attr_accessor :mode
  def initialize(x, y)
    super
    self.openness = 0
    @mode = nil
  end
  #--------------------------------------------------------------------------
  # * Get Window Width
  #--------------------------------------------------------------------------
  def window_width
    return 160
  end
  #--------------------------------------------------------------------------
  # * Get Window Height
  #--------------------------------------------------------------------------
  def window_height
    fitting_height(visible_line_number)
  end

  def make_command_list
    add_command("Yes", :ok, true)
    add_command("No", :cancel, true)
  end

  def show
    self.openness = 255
  end

  def hide
    self.openness = 0
  end
end