Submit Your Article


 
RPG Maker

Welcome Guest ( Log In | Register )


  Games Resources RPG Maker VX RPG Maker XP Scripts Tutorials Downloads

 
Closed TopicStart new topic
> Exp distribution system
Tsukihime
post Nov 3 2011, 03:52 PM
Post #1


Level 25
Group Icon

Group: Revolutionary
Posts: 565
Type: None
RM Skill: Undisclosed
Rev Points: 25




Version 1.02
By Tsukihime
Released Nov 8, 2011

Introduction

This system allows you to increase your stats using exp obtained. This gives the player greater customization over the character's growth during the game.

Features

*Increase stats using exp
*Resetting (all) stats
*Level up when you spend exp

Script

Script

CODE
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
# Exp Distribution System by Tsukihime
# Adapted from Blizzard's DP Distribution system
# Version: 1.02
# Nov 8, 2011
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
#
# Change log
#
# v1.00 Nov 2, 2011 - initial release
# v1.01 Nov 6, 2011 - stat reset added, leveling removed
# v1.02 Nov 8, 2011 - leveling re-added, fixed bugs related to exp and level
#
# Features:
#
#   - distribute exp between different stats
#   - extra scene for point distribution with confirmation window at the end
#   - calls the "caller scene" automatically when finished
#   - add points by easily pressing RIGHT/LEFT
#   - hold Q to add 10 points at once
#   - hold W to add 100 points at once
#   - a Stat Distribution System
#
# Configuration (needs to be updated):
#
#   Set up the configuration below.
#
#   HP_EXP_COST    - how much EXP does 1 HP cost
#   SP_EXP_COST    - how much EXP does 1 SP cost
#   STR_EXP_COST   - how much EXP does 1 STR cost
#   DEX_EXP_COST   - how much EXP does 1 DEX cost
#   AGI_EXP_COST   - how much EXP does 1 AGI cost
#   INT_EXP_COST   - how much EXP does 1 INT cost
#   AUTO_CALL     - set to true to have the scene called automatically after
#                   battles if at least one character got leveled up
#   AUTO_MAP_CALL - set to true to have the scene called automatically on the
#                   map if at least one character got leveled up (this works
#                   for Blizz-ABS as well), also note that this will cause the
#                   scene to called over and over as long as not all points
#                   were distributed
#   DISPLAY_ICON  - displays an icon on the map if ANY character in the
#                   party has any points to distribute
#   OWN_ICON      - use an own icon for display, false for no or filename of
#                   your own icon (the icon has to be in the Icons folder)
#   ICON_X        - icon X coordinate
#   ICON_Y        - icon Y coordinate
#   ICON_OPACITY  - icon Y opacity
#   WINDOW_MODE   - set to true to have the command windows at the bottom, set
#                   to false to have them to at the top
#
#   This system replaces the default leveling system. You will only level up
#   when you have allocated a certain amount of exp (based on the exp tables
#   that you define).
#
#   You can call the Scene by using a "Call script" event command. Type into
#   the editor window this text:
#
#     $scene = Scene_Points.new
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=

module BlizzCFG

#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# START Configuration
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  HP_EXP_COST = 1
  SP_EXP_COST = 1
  STR_EXP_COST = 10
  DEX_EXP_COST = 10
  AGI_EXP_COST = 10
  INT_EXP_COST = 10
  ALLOW_RESET = true #TO-DO. Enable/disable stat resetting
  AUTO_CALL = false
  AUTO_MAP_CALL = false
  DISPLAY_ICON = true
  OWN_ICON = false
  ICON_X = 612
  ICON_Y = 452
  ICON_OPACITY = 192
  WINDOW_MODE = true
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# END Configuration
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  # constants
  HPLimit = 9999
  SPLimit = 9999
  STRLimit = 999
  DEXLimit = 999
  AGILimit = 999
  INTLimit = 999
  DPName = 'EXP'
  EXPText = 'EXP'
  NextText = 'next'
  EquipmentText = 'Equipment'
  AreYouSure = 'Are you sure?'
  DistroCommands = ['Distribute EXP', '« Character »', 'Restore to Defaults', 'Finish']
  AreYouSureCommands = ['Cancel', 'Accept Changes', 'Discard Changes']
  AttrLimits = [HPLimit, SPLimit, STRLimit, DEXLimit, AGILimit, INTLimit]
  ExchangeRates = [HP_EXP_COST, SP_EXP_COST, STR_EXP_COST,
      DEX_EXP_COST, AGI_EXP_COST, INT_EXP_COST]
  ColorWhite = Color.new(255, 255, 255)
  ColorBlack = Color.new(0, 0, 0)
  ColorIcon = Color.new(0, 128, 255)
  ColorIncreased = Color.new(0, 255, 0)
  # ensures compatibility
  $stat_system = 2.01
end

#==============================================================================
# Array
#==============================================================================

class Array
  
  def sum
    result = 0
    self.each {|i| result += i if i.is_a?(Numeric)}
    return result
  end
  
end

#==============================================================================
# Window_Base
#==============================================================================

class Window_Base
  
  def draw_actor_exp(actor, x, y)
    self.contents.font.color = system_color
    self.contents.draw_text(x, y, 120, 32, "EXP to spend:")
    self.contents.font.color = normal_color
    self.contents.draw_text(x + 120, y, 84, 32, actor.exp_s)
  end
end

#==============================================================================
# Window_Status
#==============================================================================

class Window_Status
  
  def refresh
    self.contents.clear
    draw_actor_graphic(@actor, 40, 112)
    draw_actor_name(@actor, 4, 0)
    draw_actor_class(@actor, 4 + 144, 0)
    draw_actor_level(@actor, 96, 32)
    draw_actor_state(@actor, 96, 64)
    draw_actor_hp(@actor, 96, 112, 172)
    draw_actor_sp(@actor, 96, 144, 172)
    draw_actor_parameter(@actor, 96, 192, 0)
    draw_actor_parameter(@actor, 96, 224, 1)
    draw_actor_parameter(@actor, 96, 256, 2)
    draw_actor_parameter(@actor, 96, 304, 3)
    draw_actor_parameter(@actor, 96, 336, 4)
    draw_actor_parameter(@actor, 96, 368, 5)
    draw_actor_parameter(@actor, 96, 400, 6)
    self.contents.font.color = system_color
    self.contents.draw_text(320, 48, 120, 32, "EXP to Spend")
    self.contents.font.color = normal_color
    self.contents.draw_text(320 + 120, 48, 84, 32, @actor.exp_s, 2)
    self.contents.font.color = system_color
    self.contents.draw_text(320, 160, 96, 32, "equipment")
    draw_item_name($data_weapons[@actor.weapon_id], 320 + 16, 208)
    draw_item_name($data_armors[@actor.armor1_id], 320 + 16, 256)
    draw_item_name($data_armors[@actor.armor2_id], 320 + 16, 304)
    draw_item_name($data_armors[@actor.armor3_id], 320 + 16, 352)
    draw_item_name($data_armors[@actor.armor4_id], 320 + 16, 400)
  end
end

#==============================================================================
# Game_Actor
#==============================================================================

class Game_Actor < Game_Battler
  
  attr_reader :exp_spent
  
  alias setup_sds_later setup
  def setup(actor_id)
    @exp_spent = 0
    @init_level = $data_actors[actor_id].initial_level
    setup_sds_later(actor_id)
    
    #always start with 0 exp
    @exp = 0
  end
  
  def exp=(exp)
    @exp = [[exp, 9999999].min, 0].max
    
  end
  
  def level=(level)
    # Check up and down limits
    level = [[level, $data_actors[@actor_id].final_level].min, 1].max
    # Don't change EXP
    ##self.exp = @exp_list[level]
  end
  
  def exp_spent=(exp)
    @exp_spent = [[exp, 999999].min, 0].max
    while @exp_spent >= @exp_list[@level+1] and @exp_list[@level+1] > 0
      @level += 1
      # Learn skill
      for j in $data_classes[@class_id].learnings
        if j.level == @level
          learn_skill(j.skill_id)
        end
      end
    end
    # Level down
    while @exp_spent < @exp_list[@init_level] - @exp_list[@level]
      @level -= 1
    end
    # Correction if exceeding current max HP and max SP
    @hp = [@hp, self.maxhp].min
    @sp = [@sp, self.maxsp].min
  end
  
  #The following methods override stat increases when leveling
  #--------------------------------------------------------------------------
  # * Get Basic Maximum HP
  #--------------------------------------------------------------------------
  def base_maxhp
    return $data_actors[@actor_id].parameters[0, @init_level]
  end
  #--------------------------------------------------------------------------
  # * Get Basic Maximum SP
  #--------------------------------------------------------------------------
  def base_maxsp
    return $data_actors[@actor_id].parameters[1, @init_level]
  end
  #--------------------------------------------------------------------------
  # * Get Basic Strength
  #--------------------------------------------------------------------------
  def base_str
    n = $data_actors[@actor_id].parameters[2, @init_level]
    weapon = $data_weapons[@weapon_id]
    armor1 = $data_armors[@armor1_id]
    armor2 = $data_armors[@armor2_id]
    armor3 = $data_armors[@armor3_id]
    armor4 = $data_armors[@armor4_id]
    n += weapon != nil ? weapon.str_plus : 0
    n += armor1 != nil ? armor1.str_plus : 0
    n += armor2 != nil ? armor2.str_plus : 0
    n += armor3 != nil ? armor3.str_plus : 0
    n += armor4 != nil ? armor4.str_plus : 0
    return [[n, 1].max, 999].min
  end
  #--------------------------------------------------------------------------
  # * Get Basic Dexterity
  #--------------------------------------------------------------------------
  def base_dex
    n = $data_actors[@actor_id].parameters[3, @init_level]
    weapon = $data_weapons[@weapon_id]
    armor1 = $data_armors[@armor1_id]
    armor2 = $data_armors[@armor2_id]
    armor3 = $data_armors[@armor3_id]
    armor4 = $data_armors[@armor4_id]
    n += weapon != nil ? weapon.dex_plus : 0
    n += armor1 != nil ? armor1.dex_plus : 0
    n += armor2 != nil ? armor2.dex_plus : 0
    n += armor3 != nil ? armor3.dex_plus : 0
    n += armor4 != nil ? armor4.dex_plus : 0
    return [[n, 1].max, 999].min
  end
  #--------------------------------------------------------------------------
  # * Get Basic Agility
  #--------------------------------------------------------------------------
  def base_agi
    n = $data_actors[@actor_id].parameters[4, @init_level]
    weapon = $data_weapons[@weapon_id]
    armor1 = $data_armors[@armor1_id]
    armor2 = $data_armors[@armor2_id]
    armor3 = $data_armors[@armor3_id]
    armor4 = $data_armors[@armor4_id]
    n += weapon != nil ? weapon.agi_plus : 0
    n += armor1 != nil ? armor1.agi_plus : 0
    n += armor2 != nil ? armor2.agi_plus : 0
    n += armor3 != nil ? armor3.agi_plus : 0
    n += armor4 != nil ? armor4.agi_plus : 0
    return [[n, 1].max, 999].min
  end
  #--------------------------------------------------------------------------
  # * Get Basic Intelligence
  #--------------------------------------------------------------------------
  def base_int
    n = $data_actors[@actor_id].parameters[5, @init_level]
    weapon = $data_weapons[@weapon_id]
    armor1 = $data_armors[@armor1_id]
    armor2 = $data_armors[@armor2_id]
    armor3 = $data_armors[@armor3_id]
    armor4 = $data_armors[@armor4_id]
    n += weapon != nil ? weapon.int_plus : 0
    n += armor1 != nil ? armor1.int_plus : 0
    n += armor2 != nil ? armor2.int_plus : 0
    n += armor3 != nil ? armor3.int_plus : 0
    n += armor4 != nil ? armor4.int_plus : 0
    return [[n, 1].max, 999].min
  end
end

#==============================================================================
# Window_Base
#==============================================================================

class Window_Base < Window
  
  def draw_actor_battler(actor, x, y)
    bitmap = RPG::Cache.battler(actor.battler_name, actor.battler_hue)
    cw, ch = bitmap.width, bitmap.height
    src_rect = Rect.new(0, 0, cw, ch)
    self.contents.blt(x - cw / 2, y - ch / 2, bitmap, src_rect)
  end
  
end

#==============================================================================
# Window_DistributionStatus
#==============================================================================

class Window_DistributionStatus < Window_Base
  
  attr_reader :actor
  
  def initialize(actor)
    super(0, BlizzCFG::WINDOW_MODE ? 0 : 224, 640, 256)
    @actor = actor
    self.contents = Bitmap.new(width - 32, height - 32)
    if $fontface != nil
      self.contents.font.name = $fontface
      self.contents.font.size = $fontsize
    elsif $defaultfonttype != nil
      self.contents.font.name = $defaultfonttype
      self.contents.font.size = $defaultfontsize
    end
    refresh
  end
  
  def actor=(actor)
    @actor = actor
    refresh
  end
  
  def refresh
    self.contents.clear
    unless @actor == nil
      draw_actor_battler(@actor, 256, 120)
      draw_actor_name(@actor, 4, 0)
      draw_actor_class(@actor, 4, 32)
      draw_actor_level(@actor, 4, 64)
      self.contents.font.color = system_color
      self.contents.draw_text(352, 16, 96, 32, BlizzCFG::EquipmentText)
      draw_item_name($data_weapons[@actor.weapon_id], 352, 64)
      draw_item_name($data_armors[@actor.armor1_id], 352, 96)
      draw_item_name($data_armors[@actor.armor2_id], 352, 128)
      draw_item_name($data_armors[@actor.armor3_id], 352, 160)
      draw_item_name($data_armors[@actor.armor4_id], 352, 192)
      self.contents.font.color = normal_color
      draw_actor_parameter(@actor, 4, 96, 0)
      draw_actor_parameter(@actor, 4, 128, 1)
      draw_actor_parameter(@actor, 4, 160, 2)
    end
  end
  
end
  
#==============================================================================
# Window_DistributionPoints
#==============================================================================

class Window_DistributionPoints < Window_Base
  
  attr_reader :actor
  attr_reader :EXP_left
  
  def initialize(actor)
    super(0, BlizzCFG::WINDOW_MODE ? 416 : 160, 224, 64)
    self.contents = Bitmap.new(width - 32, height - 32)
    if $fontface != nil
      self.contents.font.name = $fontface
      self.contents.font.size = $fontsize
    elsif $defaultfonttype != nil
      self.contents.font.name = $defaultfonttype
      self.contents.font.size = $defaultfontsize
    end
    self.actor = actor
  end
  
  def actor=(actor)
    @actor, @exp_left = actor, actor.exp
    refresh
  end
  
  def set_dp(value)
    @exp_left = actor.exp - value
    refresh
  end
  
  def refresh
    self.contents.clear
    self.contents.font.color = system_color
    self.contents.draw_text(4, 0, 32, 32, BlizzCFG::DPName)
    self.contents.font.color = normal_color
    self.contents.draw_text(36, 0, 152, 32, "#{@exp_left}", 2)
  end
  
end
  
#==============================================================================
# Window_Distribution
#==============================================================================

class Window_Distribution < Window_Selectable
  
  attr_reader :actor
  attr_reader :spent
  
  def initialize(actor)
    super(224, BlizzCFG::WINDOW_MODE ? 256 : 0, 416, 224)
    self.contents = Bitmap.new(width - 32, height - 32)
    if $fontface != nil
      self.contents.font.name = $fontface
      self.contents.font.size = $fontsize
    elsif $defaultfonttype != nil
      self.contents.font.name = $defaultfonttype
      self.contents.font.size = $defaultfontsize
    end
    @words = ["Max #{$data_system.words.hp}", "Max #{$data_system.words.sp}",
        $data_system.words.str, $data_system.words.dex, $data_system.words.agi,
        $data_system.words.int]
    @item_max = @words.size
    self.actor = actor
    self.active, self.index = false, 0
  end
  
  def actor=(actor)
    @actor = actor
    @current = [@actor.maxhp, @actor.maxsp, @actor.str, @actor.dex, @actor.agi,
        @actor.int]
    @spent = [0, 0, 0, 0, 0, 0]
    refresh
  end
  
  def active=(value)
    super(value)
    update_cursor_rect
  end
  
  def apply_new_attributes
    @actor.maxhp += @spent[0] / BlizzCFG::HP_EXP_COST
    @actor.maxsp += @spent[1] / BlizzCFG::SP_EXP_COST
    @actor.str += @spent[2] / BlizzCFG::STR_EXP_COST
    @actor.dex += @spent[3] / BlizzCFG::DEX_EXP_COST
    @actor.agi += @spent[4] / BlizzCFG::AGI_EXP_COST
    @actor.int += @spent[5] / BlizzCFG::INT_EXP_COST
    @actor.exp -= @spent.sum
    @actor.exp_spent += @spent.sum
  end
  
  def refresh
    self.contents.clear
    (0...@item_max).each {|i| draw_item(i)}
  end
  
  def draw_item(i)
    y = i * 32
    self.contents.fill_rect(0, y, self.contents.width, 32, Color.new(0, 0, 0, 0))
    self.contents.font.color = system_color
    self.contents.draw_text(4, y, 80, 32, @words[i])
    self.contents.draw_text(344, y, 40, 32, BlizzCFG::DPName)
    self.contents.draw_text(180, y, 12, 32, '/', 1)
    self.contents.draw_text(192, y, 64, 32, @current[i].to_s)
    self.contents.font.color = normal_color
    self.contents.draw_text(276, y, 64, 32,
        BlizzCFG::ExchangeRates[i].to_s, 2)
    font, self.contents.font.name = self.contents.font.name, 'Arial'
    size, self.contents.font.size = self.contents.font.size, 32
    bold, self.contents.font.bold = self.contents.font.bold, true
    self.contents.draw_text(104, y - 2, 24, 32, '«')
    self.contents.draw_text(244, y - 2, 24, 32, '»', 2)
    self.contents.font.bold = bold
    self.contents.font.size = size
    self.contents.font.bold = bold
    self.contents.font.color = BlizzCFG::ColorIncreased if @spent[i] > 0
    self.contents.draw_text(116, y, 64, 32,
        (@current[i] + @spent[i] / BlizzCFG::ExchangeRates[i]).to_s, 2)
  end
  
  def add_points(value)
    value *= BlizzCFG::ExchangeRates[index]
    limit = @actor.exp - @spent.sum
    value = limit if value > limit
    value /= BlizzCFG::ExchangeRates[index]
    limit = BlizzCFG::AttrLimits[index] - (@current[index] + @spent[index])
    value = limit if value > limit
    if value > 0
      @spent[index] += value * BlizzCFG::ExchangeRates[index]
      return true
    end
    return false
  end
  
  def remove_points(value)
    value *= BlizzCFG::ExchangeRates[index]
    limit = spent.sum
    value = limit if value > limit
    value = @spent[index] if value > @spent[index]
    value /= BlizzCFG::ExchangeRates[index]
    if value > 0
      @spent[index] -= value * BlizzCFG::ExchangeRates[index]
      return true
    end
    return false
  end
  
  def update
    super
    return unless self.active
    if Input.press?(Input::R)
      if Input.repeat?(Input::RIGHT)
        if add_points(100)
          $game_system.se_play($data_system.cursor_se)
          draw_item(self.index)
        else
          $game_system.se_play($data_system.buzzer_se)
        end
      elsif Input.repeat?(Input::LEFT)
        if remove_points(100)
          $game_system.se_play($data_system.cursor_se)
          draw_item(self.index)
        else
          $game_system.se_play($data_system.buzzer_se)
        end
      end
    elsif Input.press?(Input::L)
      if Input.repeat?(Input::RIGHT)
        if add_points(10)
          $game_system.se_play($data_system.cursor_se)
          draw_item(self.index)
        else
          $game_system.se_play($data_system.buzzer_se)
        end
      elsif Input.repeat?(Input::LEFT)
        if remove_points(10)
          $game_system.se_play($data_system.cursor_se)
          draw_item(self.index)
        else
          $game_system.se_play($data_system.buzzer_se)
        end
      end
    elsif Input.repeat?(Input::RIGHT)
      if add_points(1)
        $game_system.se_play($data_system.cursor_se)
        draw_item(self.index)
      else
        $game_system.se_play($data_system.buzzer_se)
      end
    elsif Input.repeat?(Input::LEFT)
      if remove_points(1)
        $game_system.se_play($data_system.cursor_se)
        draw_item(self.index)
      else
        $game_system.se_play($data_system.buzzer_se)
      end
    end
  end
  
  def update_cursor_rect
    if @index < 0 || !self.active
      self.cursor_rect.empty
    else
      super
    end
  end
  
end
  
#==============================================================================
# Window_Sure
#==============================================================================

class Window_Sure < Window_Command
  
  def initialize(width, commands)
    commands = commands.clone + ['']
    super
    @item_max, self.index = commands.size - 1, 0
    self.x, self.y, self.z = 320 - self.width / 2, 240 - self.height / 2, 10000
    refresh
  end
  
  def refresh
    super
    self.contents.font.color = system_color
    self.contents.draw_text(4, 0, self.contents.width - 8, 32,
        BlizzCFG::AreYouSure, 1)
  end
  
  def draw_item(i, color)
    self.contents.font.color = color
    rect = Rect.new(4, (i + 1) * 32, self.contents.width - 8, 32)
    self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
    self.contents.draw_text(rect, @commands[i], 1)
  end
  
  def update_cursor_rect
    if @index < 0
      self.cursor_rect.empty
    else
      self.cursor_rect.set(32, (@index + 1) * 32, self.contents.width - 64, 32)
    end
  end
  
end
  
#==============================================================================
# Scene_Points
#==============================================================================

class Scene_Points
  
  def initialize(classe = $scene.class)
    @scene = classe
  end
  
  def main
    @command_window = Window_Command.new(224, BlizzCFG::DistroCommands)
    @command_window.y = (BlizzCFG::WINDOW_MODE ? 256 : 0)
    actor = $game_party.actors[0]
    @status_window = Window_DistributionStatus.new(actor)
    @distro_window = Window_Distribution.new(actor)
    @EXP_window = Window_DistributionPoints.new(actor)
    Graphics.transition
    loop do
      Graphics.update
      Input.update
      update
      break if $scene != self
    end
    Graphics.freeze
    @command_window.dispose
    @status_window.dispose
    @distro_window.dispose
    @EXP_window.dispose
  end
  
  def create_confirmation_window
    @sure_window = Window_Sure.new(256, BlizzCFG::AreYouSureCommands)
  end
  
  def update
    if @command_window.active
      @command_window.update
      update_main_command
    elsif @sure_window != nil
      @sure_window.update
      update_confirmation
    elsif @confirm_reset != nil
      @confirm_reset.update
      update_confirm_reset
    elsif @distro_window.active
      @distro_window.update
      update_distro
    end
  end
  
  def update_main_command
    @next_actor_dir = Input.trigger?(Input::LEFT)  ? -1 :
                      Input.trigger?(Input::RIGHT) ?  1 : 0
    if Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      $scene = @scene.new
    elsif Input.trigger?(Input::C) or (@command_window.index == 1 and @next_actor_dir != 0)
      $game_system.se_play($data_system.decision_se)
      if @command_window.index == 0
        @command_window.active, @distro_window.active = false, true
      elsif @distro_window.spent.sum > 0 and @command_window.index != 2
        @command_window.active = false
        create_confirmation_window
      else
        @distro_window.index = 0
        check_command_window
      end
    end
  end
  
  def update_confirmation
    if Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      @sure_window.dispose
      @sure_window, @command_window.active = nil, true
    elsif Input.trigger?(Input::C)
      $game_system.se_play($data_system.decision_se)
      if @sure_window.index > 0
        @distro_window.apply_new_attributes if @sure_window.index == 1
        check_command_window
      end
      @sure_window.dispose
      @sure_window, @command_window.active = nil, true
        
    end
  end
  
  def check_command_window
    case @command_window.index
    when 1 # Switch Actors
      i = @status_window.actor.index + @next_actor_dir
      i = (i + $game_party.actors.size) % $game_party.actors.size
      @status_window.actor = @distro_window.actor =
          @EXP_window.actor = $game_party.actors[i]
    when 2 # Reset Stats
      commands = ["Keep Stats", "Reset to original stats"]
      @confirm_reset = Window_Sure.new(320, commands)
      @confirm_reset.visible = @confirm_reset.active = true
      @confirm_reset.z += 5000
      @command_window.active = false
    when 3
      $scene = @scene.new
    end
  end
  
  def update_confirm_reset
    if Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      @command_window.active = true
      @confirm_reset.dispose; @confirm_reset = nil
    elsif Input.trigger?(Input::C)
      $game_system.se_play($data_system.decision_se)
      # Run processing to reset if appropriate
      if @confirm_reset.index == 1
        # Backup the actor in its current form
        bef_actor = @status_window.actor.clone
        # Reset the actor
        @status_window.actor.setup(bef_actor.id)
        aft_actor = @status_window.actor
        # Get the stat changes
        d_hp = (bef_actor.maxhp - aft_actor.maxhp) * BlizzCFG::HP_EXP_COST
        d_sp = (bef_actor.maxsp - aft_actor.maxsp) * BlizzCFG::SP_EXP_COST
        d_str = (bef_actor.str - aft_actor.str) * BlizzCFG::STR_EXP_COST
        d_dex = (bef_actor.dex - aft_actor.dex) * BlizzCFG::DEX_EXP_COST
        d_agi = (bef_actor.agi - aft_actor.agi) * BlizzCFG::AGI_EXP_COST
        d_int = (bef_actor.int - aft_actor.int) * BlizzCFG::INT_EXP_COST
        # Give back the EXP
        aft_actor.exp = bef_actor.exp + d_hp + d_sp + d_str + d_dex +
                        d_agi + d_int
        @status_window.actor = @distro_window.actor =
            @EXP_window.actor = aft_actor
      end
      @command_window.active = true
      @confirm_reset.dispose; @confirm_reset = nil
    end
  end
    
  
  def update_distro
    if Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      @command_window.active, @distro_window.active = true, false
    elsif Input.trigger?(Input::C)
      $game_system.se_play($data_system.decision_se)
      @command_window.active, @distro_window.active = true, false
    elsif Input.repeat?(Input::LEFT) || Input.repeat?(Input::RIGHT)
      @EXP_window.set_dp(@distro_window.spent.sum)
    end
  end
end



Demo

http://www.mediafire.com/?qpee3aushh9qcbo

Customization

Edit the constants under the "START CONFIGURATION" section.

compatibility

The menu was modified based on the default menu. You will have to modify the appropriate sections if you want to use a custom menu system (just the status window)

May not be compatible with any scripts that change the game actor class, or the exp system, or the leveling system

Bugs

When resetting stats, HP/SP is set to the previous maximum. I know why it happens, but not sure how to fix it.

Installation

Copy script above main.

Credits

Blizzard, for writing the DP system that this script was adapted from.
Night_Runner, for adding features like reset and updating the menu to make more sense

This post has been edited by Tsukihime: Nov 8 2011, 06:38 PM


__________________________
My Scripts
Go to the top of the page
 
+Quote Post
   
Night_Runner
post Nov 6 2011, 02:49 AM
Post #2


Level 50
Group Icon

Group: +Gold Member
Posts: 1,529
Type: Scripter
RM Skill: Undisclosed




Would you like me to move this over to script submissions?

And also, I've tweaked the code, I've removed levelling up, it caused bugs ( I received 200 exp, spent about 40 (going from 741 - 780) on increasing max HP, and when I close and return I would have levelled up, causing my MaxHP to jump to 880 or so ), which means you have to manually learn skills, which isn't such a big deal.

I've also removed the 'exp until next level' from the menu and status menu, although the status menu isn't as elegant and will probably not work well with any oterh scripts that change class Window_MenuStatus.

And I think the last thing I changed, you mentioned reverting to default stats, I've added an option for it happy.gif

code
CODE
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
# Exp Distribution System by Tsukihime
# Adapted from Blizzard's DP Distribution system
# Version: 1.00
# Nov 2, 2011
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
#
# Features:
#
#   - distribute exp between different stats
#   - extra scene for point distribution with confirmation window at the end
#   - calls the "caller scene" automatically when finished
#   - add points by easily pressing RIGHT/LEFT
#   - hold Q to add 10 points at once
#   - hold W to add 100 points at once
#   - a Stat Distribution System
#
# Configuration (needs to be updated):
#
#   Set up the configuration below.
#
#   HP_DP_COST    - how many DP does 1 HP cost
#   SP_DP_COST    - how many DP does 1 SP cost
#   STR_DP_COST   - how many DP does 1 STR cost
#   DEX_DP_COST   - how many DP does 1 DEX cost
#   AGI_DP_COST   - how many DP does 1 AGI cost
#   INT_DP_COST   - how many DP does 1 INT cost
#   AUTO_CALL     - set to true to have the scene called automatically after
#                   battles if at least one character got leveled up
#   AUTO_MAP_CALL - set to true to have the scene called automatically on the
#                   map if at least one character got leveled up (this works
#                   for Blizz-ABS as well), also note that this will cause the
#                   scene to called over and over as long as not all points
#                   were distributed
#   DISPLAY_ICON  - displays an icon on the map if ANY character in the
#                   party has any points to distribute
#   OWN_ICON      - use an own icon for display, false for no or filename of
#                   your own icon (the icon has to be in the Icons folder)
#   ICON_X        - icon X coordinate
#   ICON_Y        - icon Y coordinate
#   ICON_OPACITY  - icon Y opacity
#   WINDOW_MODE   - set to true to have the command windows at the bottom, set
#                   to false to have them to at the top
#
#   This system replaces the default leveling system. You will only level up
#   when you have allocated a certain amount of exp (based on the exp tables
#   that you define).
#
#   You can call the Scene by using a "Call script" event command. Type into
#   the editor window this text:
#
#     $scene = Scene_Points.new
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=

module BlizzCFG

#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# START Configuration
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  HP_DP_COST = 1
  SP_DP_COST = 1
  STR_DP_COST = 10
  DEX_DP_COST = 10
  AGI_DP_COST = 10
  INT_DP_COST = 10
  AUTO_CALL = false
  AUTO_MAP_CALL = false
  DISPLAY_ICON = true
  OWN_ICON = false
  ICON_X = 612
  ICON_Y = 452
  ICON_OPACITY = 192
  WINDOW_MODE = true
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# END Configuration
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  # constants
  HPLimit = 9999
  SPLimit = 9999
  STRLimit = 999
  DEXLimit = 999
  AGILimit = 999
  INTLimit = 999
  DPName = 'EXP'
  EXPText = 'EXP'
  NextText = 'next'
  EquipmentText = 'Equipment'
  AreYouSure = 'Are you sure?'
  DistroCommands = ['Distribute EXP', '« Character »', 'Restore to Defaults', 'Finish']
  AreYouSureCommands = ['Cancel', 'Accept Changes', 'Discard Changes']
  AttrLimits = [HPLimit, SPLimit, STRLimit, DEXLimit, AGILimit, INTLimit]
  ExchangeRates = [HP_DP_COST, SP_DP_COST, STR_DP_COST,
      DEX_DP_COST, AGI_DP_COST, INT_DP_COST]
  ColorWhite = Color.new(255, 255, 255)
  ColorBlack = Color.new(0, 0, 0)
  ColorIcon = Color.new(0, 128, 255)
  ColorIncreased = Color.new(0, 255, 0)
  # ensures compatibility
  $stat_system = 2.01
  
end

#==============================================================================
# Array
#==============================================================================

class Array
  
  def sum
    result = 0
    self.each {|i| result += i if i.is_a?(Numeric)}
    return result
  end
  
end

#==============================================================================
# Window_Base
#==============================================================================

class Window_Base
  
  def draw_actor_level(*args)
    return
  end
  
  def draw_actor_exp(actor, x, y)
    self.contents.font.color = system_color
    self.contents.draw_text(x, y, 120, 32, "EXP to spend:")
    self.contents.font.color = normal_color
    self.contents.draw_text(x + 120, y, 84, 32, actor.exp_s)
  end
end

#==============================================================================
# Window_Status
#==============================================================================

class Window_Status
  
  def refresh
    self.contents.clear
    draw_actor_graphic(@actor, 40, 112)
    draw_actor_name(@actor, 4, 0)
    draw_actor_class(@actor, 4 + 144, 0)
    draw_actor_level(@actor, 96, 32)
    draw_actor_state(@actor, 96, 64)
    draw_actor_hp(@actor, 96, 112, 172)
    draw_actor_sp(@actor, 96, 144, 172)
    draw_actor_parameter(@actor, 96, 192, 0)
    draw_actor_parameter(@actor, 96, 224, 1)
    draw_actor_parameter(@actor, 96, 256, 2)
    draw_actor_parameter(@actor, 96, 304, 3)
    draw_actor_parameter(@actor, 96, 336, 4)
    draw_actor_parameter(@actor, 96, 368, 5)
    draw_actor_parameter(@actor, 96, 400, 6)
    self.contents.font.color = system_color
    self.contents.draw_text(320, 48, 120, 32, "EXP to Spend")
    self.contents.font.color = normal_color
    self.contents.draw_text(320 + 120, 48, 84, 32, @actor.exp_s, 2)
    self.contents.font.color = system_color
    self.contents.draw_text(320, 160, 96, 32, "equipment")
    draw_item_name($data_weapons[@actor.weapon_id], 320 + 16, 208)
    draw_item_name($data_armors[@actor.armor1_id], 320 + 16, 256)
    draw_item_name($data_armors[@actor.armor2_id], 320 + 16, 304)
    draw_item_name($data_armors[@actor.armor3_id], 320 + 16, 352)
    draw_item_name($data_armors[@actor.armor4_id], 320 + 16, 400)
  end
end

#==============================================================================
# Game_Actor
#==============================================================================

class Game_Actor < Game_Battler
  
  attr_reader :exp_spent
  
  alias setup_sds_later setup
  def setup(actor_id)
    @exp_spent = 0
    setup_sds_later(actor_id)
  end
  
  def exp=(exp)
    @exp = [[exp, 9999999].min, 0].max
    
  end
  
  def exp_spent=(exp)
    @exp_spent = [[exp, 999999].min, 0].max
    # Correction if exceeding current max HP and max SP
    @hp = [@hp, self.maxhp].min
    @sp = [@sp, self.maxsp].min
  end
end

#==============================================================================
# Window_Base
#==============================================================================

class Window_Base < Window
  
  def draw_actor_battler(actor, x, y)
    bitmap = RPG::Cache.battler(actor.battler_name, actor.battler_hue)
    cw, ch = bitmap.width, bitmap.height
    src_rect = Rect.new(0, 0, cw, ch)
    self.contents.blt(x - cw / 2, y - ch / 2, bitmap, src_rect)
  end
  
end

#==============================================================================
# Window_DistributionStatus
#==============================================================================

class Window_DistributionStatus < Window_Base
  
  attr_reader :actor
  
  def initialize(actor)
    super(0, BlizzCFG::WINDOW_MODE ? 0 : 224, 640, 256)
    @actor = actor
    self.contents = Bitmap.new(width - 32, height - 32)
    if $fontface != nil
      self.contents.font.name = $fontface
      self.contents.font.size = $fontsize
    elsif $defaultfonttype != nil
      self.contents.font.name = $defaultfonttype
      self.contents.font.size = $defaultfontsize
    end
    refresh
  end
  
  def actor=(actor)
    @actor = actor
    refresh
  end
  
  def refresh
    self.contents.clear
    unless @actor == nil
      draw_actor_battler(@actor, 256, 120)
      draw_actor_name(@actor, 4, 0)
      draw_actor_class(@actor, 4, 32)
      draw_actor_level(@actor, 4, 64)
      self.contents.font.color = system_color
      self.contents.draw_text(352, 16, 96, 32, BlizzCFG::EquipmentText)
      draw_item_name($data_weapons[@actor.weapon_id], 352, 64)
      draw_item_name($data_armors[@actor.armor1_id], 352, 96)
      draw_item_name($data_armors[@actor.armor2_id], 352, 128)
      draw_item_name($data_armors[@actor.armor3_id], 352, 160)
      draw_item_name($data_armors[@actor.armor4_id], 352, 192)
      self.contents.font.color = normal_color
      draw_actor_parameter(@actor, 4, 96, 0)
      draw_actor_parameter(@actor, 4, 128, 1)
      draw_actor_parameter(@actor, 4, 160, 2)
    end
  end
  
end
  
#==============================================================================
# Window_DistributionPoints
#==============================================================================

class Window_DistributionPoints < Window_Base
  
  attr_reader :actor
  attr_reader :dp_left
  
  def initialize(actor)
    super(0, BlizzCFG::WINDOW_MODE ? 416 : 160, 224, 64)
    self.contents = Bitmap.new(width - 32, height - 32)
    if $fontface != nil
      self.contents.font.name = $fontface
      self.contents.font.size = $fontsize
    elsif $defaultfonttype != nil
      self.contents.font.name = $defaultfonttype
      self.contents.font.size = $defaultfontsize
    end
    self.actor = actor
  end
  
  def actor=(actor)
    @actor, @exp_left = actor, actor.exp
    refresh
  end
  
  def set_dp(value)
    @exp_left = actor.exp - value
    refresh
  end
  
  def refresh
    self.contents.clear
    self.contents.font.color = system_color
    self.contents.draw_text(4, 0, 32, 32, BlizzCFG::DPName)
    self.contents.font.color = normal_color
    self.contents.draw_text(36, 0, 152, 32, "#{@exp_left} / #{@actor.exp}", 2)
  end
  
end
  
#==============================================================================
# Window_Distribution
#==============================================================================

class Window_Distribution < Window_Selectable
  
  attr_reader :actor
  attr_reader :spent
  
  def initialize(actor)
    super(224, BlizzCFG::WINDOW_MODE ? 256 : 0, 416, 224)
    self.contents = Bitmap.new(width - 32, height - 32)
    if $fontface != nil
      self.contents.font.name = $fontface
      self.contents.font.size = $fontsize
    elsif $defaultfonttype != nil
      self.contents.font.name = $defaultfonttype
      self.contents.font.size = $defaultfontsize
    end
    @words = ["Max #{$data_system.words.hp}", "Max #{$data_system.words.sp}",
        $data_system.words.str, $data_system.words.dex, $data_system.words.agi,
        $data_system.words.int]
    @item_max = @words.size
    self.actor = actor
    self.active, self.index = false, 0
  end
  
  def actor=(actor)
    @actor = actor
    @current = [@actor.maxhp, @actor.maxsp, @actor.str, @actor.dex, @actor.agi,
        @actor.int]
    @spent = [0, 0, 0, 0, 0, 0]
    refresh
  end
  
  def active=(value)
    super(value)
    update_cursor_rect
  end
  
  def apply_new_attributes
    @actor.maxhp += @spent[0] / BlizzCFG::HP_DP_COST
    @actor.maxsp += @spent[1] / BlizzCFG::SP_DP_COST
    @actor.str += @spent[2] / BlizzCFG::STR_DP_COST
    @actor.dex += @spent[3] / BlizzCFG::DEX_DP_COST
    @actor.agi += @spent[4] / BlizzCFG::AGI_DP_COST
    @actor.int += @spent[5] / BlizzCFG::INT_DP_COST
    @actor.exp -= @spent.sum
    @actor.exp_spent += @spent.sum
  end
  
  def refresh
    self.contents.clear
    (0...@item_max).each {|i| draw_item(i)}
  end
  
  def draw_item(i)
    y = i * 32
    self.contents.fill_rect(0, y, self.contents.width, 32, Color.new(0, 0, 0, 0))
    self.contents.font.color = system_color
    self.contents.draw_text(4, y, 80, 32, @words[i])
    self.contents.draw_text(344, y, 40, 32, BlizzCFG::DPName)
    self.contents.draw_text(180, y, 12, 32, '/', 1)
    self.contents.draw_text(192, y, 64, 32, @current[i].to_s)
    self.contents.font.color = normal_color
    self.contents.draw_text(276, y, 64, 32,
        BlizzCFG::ExchangeRates[i].to_s, 2)
    font, self.contents.font.name = self.contents.font.name, 'Arial'
    size, self.contents.font.size = self.contents.font.size, 32
    bold, self.contents.font.bold = self.contents.font.bold, true
    self.contents.draw_text(104, y - 2, 24, 32, '«')
    self.contents.draw_text(244, y - 2, 24, 32, '»', 2)
    self.contents.font.bold = bold
    self.contents.font.size = size
    self.contents.font.bold = bold
    self.contents.font.color = BlizzCFG::ColorIncreased if @spent[i] > 0
    self.contents.draw_text(116, y, 64, 32,
        (@current[i] + @spent[i] / BlizzCFG::ExchangeRates[i]).to_s, 2)
  end
  
  def add_points(value)
    value *= BlizzCFG::ExchangeRates[index]
    limit = @actor.exp - @spent.sum
    value = limit if value > limit
    value /= BlizzCFG::ExchangeRates[index]
    limit = BlizzCFG::AttrLimits[index] - (@current[index] + @spent[index])
    value = limit if value > limit
    if value > 0
      @spent[index] += value * BlizzCFG::ExchangeRates[index]
      return true
    end
    return false
  end
  
  def remove_points(value)
    value *= BlizzCFG::ExchangeRates[index]
    limit = spent.sum
    value = limit if value > limit
    value = @spent[index] if value > @spent[index]
    value /= BlizzCFG::ExchangeRates[index]
    if value > 0
      @spent[index] -= value * BlizzCFG::ExchangeRates[index]
      return true
    end
    return false
  end
  
  def update
    super
    return unless self.active
    if Input.press?(Input::R)
      if Input.repeat?(Input::RIGHT)
        if add_points(100)
          $game_system.se_play($data_system.cursor_se)
          draw_item(self.index)
        else
          $game_system.se_play($data_system.buzzer_se)
        end
      elsif Input.repeat?(Input::LEFT)
        if remove_points(100)
          $game_system.se_play($data_system.cursor_se)
          draw_item(self.index)
        else
          $game_system.se_play($data_system.buzzer_se)
        end
      end
    elsif Input.press?(Input::L)
      if Input.repeat?(Input::RIGHT)
        if add_points(10)
          $game_system.se_play($data_system.cursor_se)
          draw_item(self.index)
        else
          $game_system.se_play($data_system.buzzer_se)
        end
      elsif Input.repeat?(Input::LEFT)
        if remove_points(10)
          $game_system.se_play($data_system.cursor_se)
          draw_item(self.index)
        else
          $game_system.se_play($data_system.buzzer_se)
        end
      end
    elsif Input.repeat?(Input::RIGHT)
      if add_points(1)
        $game_system.se_play($data_system.cursor_se)
        draw_item(self.index)
      else
        $game_system.se_play($data_system.buzzer_se)
      end
    elsif Input.repeat?(Input::LEFT)
      if remove_points(1)
        $game_system.se_play($data_system.cursor_se)
        draw_item(self.index)
      else
        $game_system.se_play($data_system.buzzer_se)
      end
    end
  end
  
  def update_cursor_rect
    if @index < 0 || !self.active
      self.cursor_rect.empty
    else
      super
    end
  end
  
end
  
#==============================================================================
# Window_Sure
#==============================================================================

class Window_Sure < Window_Command
  
  def initialize(width, commands)
    commands = commands.clone + ['']
    super
    @item_max, self.index = commands.size - 1, 0
    self.x, self.y, self.z = 320 - self.width / 2, 240 - self.height / 2, 10000
    refresh
  end
  
  def refresh
    super
    self.contents.font.color = system_color
    self.contents.draw_text(4, 0, self.contents.width - 8, 32,
        BlizzCFG::AreYouSure, 1)
  end
  
  def draw_item(i, color)
    self.contents.font.color = color
    rect = Rect.new(4, (i + 1) * 32, self.contents.width - 8, 32)
    self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
    self.contents.draw_text(rect, @commands[i], 1)
  end
  
  def update_cursor_rect
    if @index < 0
      self.cursor_rect.empty
    else
      self.cursor_rect.set(32, (@index + 1) * 32, self.contents.width - 64, 32)
    end
  end
  
end
  
#==============================================================================
# Scene_Points
#==============================================================================

class Scene_Points
  
  def initialize(classe = $scene.class)
    @scene = classe
  end
  
  def main
    @command_window = Window_Command.new(224, BlizzCFG::DistroCommands)
    @command_window.y = (BlizzCFG::WINDOW_MODE ? 256 : 0)
    actor = $game_party.actors[0]
    @status_window = Window_DistributionStatus.new(actor)
    @distro_window = Window_Distribution.new(actor)
    @dp_window = Window_DistributionPoints.new(actor)
    Graphics.transition
    loop do
      Graphics.update
      Input.update
      update
      break if $scene != self
    end
    Graphics.freeze
    @command_window.dispose
    @status_window.dispose
    @distro_window.dispose
    @dp_window.dispose
  end
  
  def create_confirmation_window
    @sure_window = Window_Sure.new(256, BlizzCFG::AreYouSureCommands)
  end
  
  def update
    if @command_window.active
      @command_window.update
      update_main_command
    elsif @sure_window != nil
      @sure_window.update
      update_confirmation
    elsif @confirm_reset != nil
      @confirm_reset.update
      update_confirm_reset
    elsif @distro_window.active
      @distro_window.update
      update_distro
    end
  end
  
  def update_main_command
    @next_actor_dir = Input.trigger?(Input::LEFT)  ? -1 :
                      Input.trigger?(Input::RIGHT) ?  1 : 0
    if Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      $scene = @scene.new
    elsif Input.trigger?(Input::C) or (@command_window.index == 1 and @next_actor_dir != 0)
      $game_system.se_play($data_system.decision_se)
      if @command_window.index == 0
        @command_window.active, @distro_window.active = false, true
      elsif @distro_window.spent.sum > 0 and @command_window.index != 2
        @command_window.active = false
        create_confirmation_window
      else
        @distro_window.index = 0
        check_command_window
      end
    end
  end
  
  def update_confirmation
    if Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      @sure_window.dispose
      @sure_window, @command_window.active = nil, true
    elsif Input.trigger?(Input::C)
      $game_system.se_play($data_system.decision_se)
      if @sure_window.index > 0
        @distro_window.apply_new_attributes if @sure_window.index == 1
        check_command_window
      end
      @sure_window.dispose
      @sure_window, @command_window.active = nil, true
        
    end
  end
  
  def check_command_window
    case @command_window.index
    when 1 # Switch Actors
      i = @status_window.actor.index + @next_actor_dir
      i = (i + $game_party.actors.size) % $game_party.actors.size
      @status_window.actor = @distro_window.actor =
          @dp_window.actor = $game_party.actors[i]
    when 2 # Reset Stats
      commands = ["Keep Stats", "Reset to original stats"]
      @confirm_reset = Window_Sure.new(320, commands)
      @confirm_reset.visible = @confirm_reset.active = true
      @confirm_reset.z += 5000
      @command_window.active = false
    when 3
      $scene = @scene.new
    end
  end
  
  def update_confirm_reset
    if Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      @command_window.active = true
      @confirm_reset.dispose; @confirm_reset = nil
    elsif Input.trigger?(Input::C)
      $game_system.se_play($data_system.decision_se)
      # Run processing to reset if appropriate
      if @confirm_reset.index == 1
        # Backup the actor in its current form
        bef_actor = @status_window.actor.clone
        # Reset the actor
        @status_window.actor.setup(bef_actor.id)
        aft_actor = @status_window.actor
        # Get the stat changes
        d_hp = (bef_actor.maxhp - aft_actor.maxhp) * BlizzCFG::HP_DP_COST
        d_sp = (bef_actor.maxsp - aft_actor.maxsp) * BlizzCFG::SP_DP_COST
        d_str = (bef_actor.str - aft_actor.str) * BlizzCFG::STR_DP_COST
        d_dex = (bef_actor.dex - aft_actor.dex) * BlizzCFG::DEX_DP_COST
        d_agi = (bef_actor.agi - aft_actor.agi) * BlizzCFG::AGI_DP_COST
        d_int = (bef_actor.int - aft_actor.int) * BlizzCFG::INT_DP_COST
        # Give back the EXP
        aft_actor.exp = bef_actor.exp + d_hp + d_sp + d_str + d_dex +
                        d_agi + d_int
        @status_window.actor = @distro_window.actor =
            @dp_window.actor = aft_actor
      end
      @command_window.active = true
      @confirm_reset.dispose; @confirm_reset = nil
    end
  end
    
  
  def update_distro
    if Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      @command_window.active, @distro_window.active = true, false
    elsif Input.trigger?(Input::C)
      $game_system.se_play($data_system.decision_se)
      @command_window.active, @distro_window.active = true, false
    elsif Input.repeat?(Input::LEFT) || Input.repeat?(Input::RIGHT)
      @dp_window.set_dp(@distro_window.spent.sum)
    end
  end
  
end

#==============================================================================
# Scene_Battle
#==============================================================================

class Scene_Battle
  
  alias main_sds_later main
  def main
    main_sds_later
    if BlizzCFG::AUTO_CALL &&
        $game_party.actors.any? {|actor| actor.exp > 0}
      $scene = Scene_Points.new
    end
  end
  
end

#==============================================================================
# Scene_Map
#==============================================================================

class Scene_Map
  
  alias main_sds_later main
  def main
    main_sds_later
    @notify.dispose if @notify != nil
  end
  
  alias upd_sds_later update
  def update
    check_icon if BlizzCFG::DISPLAY_ICON
    upd_sds_later
    if BlizzCFG::AUTO_MAP_CALL &&
        $game_party.actors.any? {|actor| actor.exp > 0}
      $scene = Scene_Points.new
    end
  end
  
  def check_icon
    if $game_party.actors.any? {|actor| actor.exp > 0}
      if @notify == nil
        @notify = RPG::Sprite.new
        if BlizzCFG::OWN_ICON
          @notify.bitmap = RPG::Cache.icon(BlizzCFG::OWN_ICON)
        else
          @notify.bitmap = Bitmap.new(24, 24)
          @notify.bitmap.fill_rect(0, 0, 24, 24, BlizzCFG::ColorWhite)
          @notify.bitmap.fill_rect(22, 1, 2, 23, BlizzCFG::ColorBlack)
          @notify.bitmap.fill_rect(1, 22, 23, 2, BlizzCFG::ColorBlack)
          @notify.bitmap.set_pixel(23, 0, BlizzCFG::ColorBlack)
          @notify.bitmap.set_pixel(0, 23, BlizzCFG::ColorBlack)
          @notify.bitmap.fill_rect(2, 2, 20, 20, BlizzCFG::ColorIcon)
          @notify.bitmap.fill_rect(4, 10, 16, 4, BlizzCFG::ColorWhite)
          @notify.bitmap.fill_rect(10, 4, 4, 16, BlizzCFG::ColorWhite)
          @notify.opacity = BlizzCFG::ICON_OPACITY
        end
        @notify.x, @notify.y = BlizzCFG::ICON_X, BlizzCFG::ICON_Y
        @notify.z = 5000
        @notify.blink_on
      end
      @notify.update
    elsif @notify != nil
      @notify.dispose
      @notify = nil
    end
  end
end


Oh, and there was an etra skill from Blizz's other scripts that most people wouldn't have, so I removed it.



So, Script Submission?


__________________________
K.I.S.S.
Want help with your scripting problems? Upload a demo! Or at the very least; provide links to the scripts in question.

Most important guide ever: Newbie's Guide to Switches
Go to the top of the page
 
+Quote Post
   
Tsukihime
post Nov 7 2011, 10:15 AM
Post #3


Level 25
Group Icon

Group: Revolutionary
Posts: 565
Type: None
RM Skill: Undisclosed
Rev Points: 25




I'll change the opening post at some point to make it more formal.
I'll have to update the script as well since I've left in things that won't be needed.

I'll PM when that is done.

This post has been edited by Tsukihime: Nov 7 2011, 10:30 AM


__________________________
My Scripts
Go to the top of the page
 
+Quote Post
   
Tsukihime
post Nov 8 2011, 06:01 PM
Post #4


Level 25
Group Icon

Group: Revolutionary
Posts: 565
Type: None
RM Skill: Undisclosed
Rev Points: 25




Leveling up has been re-added and the issue with stat increases has been addressed somewhat.
I over-rid the methods in Game_Actor that returned the "basic" stat like base HP and base str so that they return the initial level rather than the character's current level

What if a character is supposed to start at a fixed level? He'll have a bunch of exp available to distribute based on the exp table, but his stats are all level 1 stats.

This doesn't really work if you're in a game where you have NPC characters join you temporarily, which is pretty common.

There was a bug where if the player's initial level > 1, you're given a bunch of exp, but if you decided to spend only some of it, it'll lower your level just because the amount of exp you spent is lower than what you're "supposed" to have.

I've added a new attribute called "init_level" which stores the actor's initial level.
The lower-bound for exp has simply been changed from your current level to your initial level.

So if you started at lv 50 and didn't spend any exp, you're not going to level down just because you didn't spend any exp.

Storing the initial level also allows me to initialize a character at level 50 with the specified level 50 stats.
Of course, this means you won't be able to customize 50 levels worth of exp, but I decided to compromise between full customizability and a headache when trying to deal with initializing level 50 NPC characters that join you temporarily in the middle of the battle.

I have changed the exp so that the character is initialized with 0 exp rather than the amount of exp required at each level.
So a level 50 character will have no exp to distribute.

This may cause problems because if you make it so that it does not cost a lot to increase your stats, the character that you started with might be many times stronger than a level 50 character that you recruited in the middle of the game.

I am not sure how to balance this. Perhaps the character should be initialized with "initial level" stats and also be given all of the exp for that level?

Code in initial post has been changed to reflect updates.

Night_Runner - Moved as per request

This post has been edited by Night_Runner: Nov 9 2011, 01:11 AM


__________________________
My Scripts
Go to the top of the page
 
+Quote Post
   

Closed TopicStart new topic
1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members:

 

Lo-Fi Version Time is now: 19th June 2013 - 01:46 AM
RPG RPG Revolution is an Privacy Policy and Legal
eXTReMe Tracker