#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
# Stat Distribution System by Blizzard
# Version: 1.33b
# Type: Actor Attribute Modifier
# Date: 25.3.2007
# Date v1.1b: 6.4.2007
# Date v1.2b: 22.8.2007
# Date v1.3b: 12.9.2007
# Date v1.33b: 5.11.2007
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
#Â
#Â This work is protected by the following license:
# #----------------------------------------------------------------------------
# #Â
# #Â Creative Commons - Attribution-NonCommercial-ShareAlike 3.0 Unported
# #Â ( http://creativecommons.org/licenses/by-nc-sa/3.0/ )
# #Â
# #Â You are free:
# #Â
# #Â to Share - to copy, distribute and transmit the work
# #Â to Remix - to adapt the work
# #Â
# #Â Under the following conditions:
# #Â
# #Â Attribution. You must attribute the work in the manner specified by the
# #Â author or licensor (but not in any way that suggests that they endorse you
# #Â or your use of the work).
# #Â
# #Â Noncommercial. You may not use this work for commercial purposes.
# #Â
# #Â Share alike. If you alter, transform, or build upon this work, you may
# #Â distribute the resulting work only under the same or similar license to
# #Â this one.
# #Â
# #Â - For any reuse or distribution, you must make clear to others the license
# #Â Â terms of this work. The best way to do this is with a link to this web
# #Â Â page.
# #Â
# #Â - Any of the above conditions can be waived if you get permission from the
# #Â Â copyright holder.
# #Â
# #Â - Nothing in this license impairs or restricts the author's moral rights.
# #Â
# #----------------------------------------------------------------------------
#
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
#
# Compatibility:
#
#Â 99% compatible with SDK v1.x. 80% compatible with SDK 2.x. WILL corrupt
#Â your old savegames. Might cause problems with custom leveling up systems.
#Â 99% compatibility with everything else.
#
#
# Features:
#
#Â - distribute points 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 that actually works like it should...
#
# new in v1.1b:
#Â - added option to call the Points Scene after a fight with level ups
#Â - customizable icon position and opacity
#
# new in v1.2b:
#Â - improved coding and made code shorter
#Â - rewritten conditions using classic syntax to avoid RGSS conditioning bug
#
# new in v1.3b:
#Â - improved coding
#Â - fixed bug with AUTOMATIC_CALL after battle
#Â - new AUTOMATIC_MAP_CALL works on the map as well (that means it's fully
#Â Â compatible with Blizz-ABS)
#
# new in v1.33b:
#Â - improved coding
#Â - improved compatibility
#Â - fixed a little glitch
#
#
# Configuration:
#
#Â Set up the configuration below.
#
#Â STARTING_POINTSÂ Â - how many points should the actor have initially at
#Â Â Â Â Â Â Â Â Â Â Â Â level 1
#Â POINTS_PER_LEVELÂ - how many points should the actor gain per level
#Â DISPLAY_ICONÂ Â Â - displays an icon on the map if ANY character in the
#Â Â Â Â Â Â Â Â Â Â Â Â party has any points to distribute
#Â ICON_DATAÂ Â Â Â Â - some custom options for your icon: [X, Y, OPACITY]
#Â Â Â Â Â Â Â Â Â Â Â Â the default values are [612, 452, 192]
#Â OWN_ICONÂ Â Â Â Â - use an own icon for display (the icon has to be in the
#Â Â Â Â Â Â Â Â Â Â Â Â Icons folder and must be named "point_notify")
#Â EVASIONÂ Â Â Â Â Â - the name that should be displayed for "Evasion"
#Â STR_LIMITÂ Â Â Â Â - max possible STR
#Â DEX_LIMITÂ Â Â Â Â - max possible DEX
#Â AGI_LIMITÂ Â Â Â Â - max possible AGI
#Â INT_LIMITÂ Â Â Â Â - max possible INT
#Â WINDOW_MODEÂ Â Â Â - set to true to have the windows at the left, set to
#Â Â Â Â Â Â Â Â Â Â Â Â false to have them to at the right
#Â AUTOMATIC_CALLÂ Â - set to true to have the scene called automatically
#Â Â Â Â Â Â Â Â Â Â Â Â after battles if at least one character got leveled up
#Â AUTOMATIC_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
#
#
#Â You can always add stat points yourself by using following syntax:
#
#Â Â $game_party.actors[X].add_stat_points(Z)
#Â Â $game_actors[Y].add_stat_points(Z)
#
#Â Or you can remove them (how much sense it does is up to you...):
#
#Â Â $game_party.actors[X].remove_stat_points(Z)
#Â Â $game_actors[Y].remove_stat_points(Z)
#
#Â X - position of actor in the party (STARTS FROM ZERO!)
#Â Y - ID of actor in the database
#Â Z - value
#
#Â You can call the Scene by using a "Call script" event command. Type into
#Â the editor window this text:
#
#Â Â $scene = Scene_Points.new
#
#
# Side Note:
#
#Â Decreasing the level of an actor won't remove his gained stat points. You
#Â MUST do it manually.
#
#
# If you find any bugs, please report them here:
# http://forum.chaos-project.com
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
module BlizzCFG
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# START Configuration
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 STARTING_POINTS = 0
 POINTS_PER_LEVEL = 5
 DISPLAY_ICON = false
 ICON_DATA = [612, 452, 192]
 OWN_ICON = false
 EVASION = 'Evasion'
 STR_LIMIT = 999
 DEX_LIMIT = 999
 AGI_LIMIT = 999
 INT_LIMIT = 999
 WINDOW_MODE = true
 AUTOMATIC_CALL = false
 AUTOMATIC_MAP_CALL = true
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# END Configuration
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 ATTR_LIMITS = [STR_LIMIT, DEX_LIMIT, AGI_LIMIT, INT_LIMIT]
 # ensures compatibility
 $stat_system = 1.33
Â
end
#==============================================================================
# Array
#==============================================================================
class Array
Â
 def sum
  result = 0
  self.each {|i| result += i if i.is_a?(Numeric)}
  return result
 end
Â
end
Â
#==============================================================================
# Game_Actor
#==============================================================================
class Game_Actor < Game_Battler
Â
 attr_reader :points
Â
 alias setup_sds_later setup
 def setup(actor_id)
  @points = BlizzCFG::STARTING_POINTS
  setup_sds_later(actor_id)
 end
Â
 alias exp_sds_later exp=
 def exp=(exp)
  old_level = @level
  exp_sds_later(exp)
  add_stat_points((@level - old_level) * BlizzCFG::POINTS_PER_LEVEL)
 end
Â
 def add_stat_points(val)
  @points += val if val > 0
 end
Â
 def remove_stat_points(val)
  @points = [@points-val, 0].max
 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
Â
 alias draw_actor_parameter_sds_later draw_actor_parameter
 def draw_actor_parameter(actor, x, y, type)
  if type == 7
   self.contents.font.color = system_color
   self.contents.draw_text(x, y, 120, 32, BlizzCFG::EVASION)
   self.contents.font.color = normal_color
   self.contents.draw_text(x + 120, y, 36, 32, actor.eva.to_s, 2)
  else
   draw_actor_parameter_sds_later(actor, x, y, type)
  end
 end
Â
end
#==============================================================================
# Window_Distribution_Status
#==============================================================================
class Window_Distribution_Status < Window_Base
Â
 attr_accessor :actor
Â
 def initialize(actor)
  super(BlizzCFG::WINDOW_MODE ? 160 : 0, 0, 480, 480)
  @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 refresh
  self.contents.clear
  unless @actor == nil
   draw_actor_battler(@actor, 280, 120)
   draw_actor_name(@actor, 4, 0)
   draw_actor_class(@actor, 4, 32)
   draw_actor_level(@actor, 4, 64)
   draw_actor_state(@actor, 4, 96)
   self.contents.font.color = system_color
   self.contents.draw_text(4, 128, 80, 32, 'EXP')
   self.contents.draw_text(4, 160, 80, 32, 'next')
   self.contents.font.color = normal_color
   self.contents.draw_text(4, 128, 156, 32, @actor.exp_s, 2)
   self.contents.draw_text(4, 160, 156, 32, @actor.next_rest_exp_s, 2)
   draw_actor_hp(@actor, 4, 224, 172)
   draw_actor_sp(@actor, 4, 256, 172)
   draw_actor_parameter(@actor, 4, 320, 0)
   draw_actor_parameter(@actor, 4, 352, 1)
   draw_actor_parameter(@actor, 4, 384, 2)
   draw_actor_parameter(@actor, 4, 416, 7)
   self.contents.font.color = system_color
   self.contents.draw_text(240, 240, 96, 32, 'Main Equipment')
   draw_item_name($data_weapons[@actor.weapon_id], 240, 288)
   draw_item_name($data_armors[@actor.armor1_id], 240, 320)
   draw_item_name($data_armors[@actor.armor2_id], 240, 352)
   draw_item_name($data_armors[@actor.armor3_id], 240, 384)
   draw_item_name($data_armors[@actor.armor4_id], 240, 416)
  end
 end
Â
end
Â
#==============================================================================
# Window_Distribution
#==============================================================================
class Window_Distribution < Window_Selectable
Â
 attr_accessor :actor
 attr_reader :points
Â
 def initialize(actor)
  super(BlizzCFG::WINDOW_MODE ? 0 : 480, 160, 160, 320)
  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.active, self.index, = false, 0
  @item_max, @actor, @att, @points = 4, actor, [0, 0, 0, 0], 0
  refresh
 end
Â
 def set_new_attributes
  @actor.str += @att[0]
  @actor.dex += @att[1]
  @actor.agi += @att[2]
  @actor.int += @att[3]
  @actor.remove_stat_points(@points)
 end
Â
 def actor=(actor)
  @actor = actor
  @att[0] = @att[1] = @att[2] = @att[3] = @points = 0
 end
Â
 def refresh
  self.contents.clear
  unless @actor == nil
   self.contents.font.color = system_color
   self.contents.draw_text(52, 0, 72, 32, 'AP left', 2)
   self.contents.draw_text(4, 32, 120, 32, $data_system.words.str)
   self.contents.draw_text(4, 96, 120, 32, $data_system.words.dex)
   self.contents.draw_text(4, 160, 120, 32, $data_system.words.agi)
   self.contents.draw_text(4, 224, 120, 32, $data_system.words.int)
   self.contents.font.color = normal_color
   self.contents.draw_text(4, 0, 48, 32, "#{actor.points-@points}", 2)
   self.contents.draw_text(36, 64, 56, 32, "#{@actor.str+@att[0]}", 2)
   self.contents.draw_text(36, 128, 56, 32, "#{@actor.dex+@att[1]}", 2)
   self.contents.draw_text(36, 192, 56, 32, "#{@actor.agi+@att[2]}", 2)
   self.contents.draw_text(36, 256, 56, 32, "#{@actor.int+@att[3]}", 2)
   self.contents.font.size += 8
   self.contents.font.bold = true
   (0...4).each {|i|
     self.contents.draw_text(0, (i + 1) * 64 - 8, 32, 42, '«', 2)
     self.contents.draw_text(96, (i + 1) * 64 - 8, 32, 42, '»')}
   self.contents.font.bold = false
   self.contents.font.size -= 8
  end
 end
Â
 def add_points(num)
  attr = [@actor.str, @actor.dex, @actor.agi, @actor.int]
  if @points < @actor.points &&
    attr[index]+@att[index] < BlizzCFG::ATTR_LIMITS[index]
   @points = [@points + num, @actor.points].min
   @att[index] = [@att[index]+num, @points+@att[index]-@att.sum].min
   return true
  end
  return false
 end
Â
 def remove_points(num)
  if @points > 0 && @att[index] > 0
   @points = [@points - num, 0].max
   @att[index] = [@att[index] - num, 0].max
   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)
     refresh
    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)
     refresh
    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)
     refresh
    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)
     refresh
    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)
    refresh
   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)
    refresh
   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
   self.cursor_rect.set(32, (@index+1)*64, 64, 32)
  end
 end
Â
end
Â
#==============================================================================
# Window_Sure
#==============================================================================
class Window_Sure < Window_Command
Â
 attr_accessor :actor
Â
 def initialize(width, commands)
  commands.push('')
  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, 'Are you sure?', 1)
 end
Â
 def draw_item(index, color)
  self.contents.font.color = color
  rect = Rect.new(4, 32 * (index+1), self.contents.width - 8, 32)
  self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
  self.contents.draw_text(rect, @commands[index], 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
  @actor, @scene = $game_party.actors[0], $scene.class
 end
Â
 def main
  commands = ['Distribute', 'Next', 'Previous', 'Finish']
  @command_window = Window_Command.new(160, commands)
  @command_window.x = (BlizzCFG::WINDOW_MODE ? 0 : 480)
  @status_window = Window_Distribution_Status.new(@actor)
  @distro_window = Window_Distribution.new(@actor)
  Graphics.transition
  loop do
   Graphics.update
   Input.update
   update
   break if $scene != self
  end
  Graphics.freeze
  [@command_window, @status_window, @distro_window].each {|win| win.dispose}
 end
Â
 def make_sure_window
  commands = ['Cancel', 'Accept changes', 'Discard changes']
  @sure_window = Window_Sure.new(256, commands)
 end
Â
 def update
  if @command_window.active
   @command_window.update
   update_main_command
  elsif @sure_window != nil
   @sure_window.update
   update_sure
  elsif @distro_window.active
   @distro_window.update
   if Input.trigger?(Input::B)
    $game_system.se_play($data_system.cancel_se)
    @command_window.active, @distro_window.active = true, false
   end
  end
 end
Â
 def update_main_command
  if Input.trigger?(Input::B)
   $game_system.se_play($data_system.cancel_se)
   if @distro_window.points != 0
    @command_window.index, @command_window.active = 3, false
    make_sure_window
   else
    $scene = @scene.new
   end
  elsif Input.trigger?(Input::C)
   $game_system.se_play($data_system.decision_se)
   case @command_window.index
   when 0 then @command_window.active, @distro_window.active = false, true
   when 1
    if @distro_window.points != 0
     @command_window.active = false
     make_sure_window
    else
     i = (@actor.index+1) % $game_party.actors.size
     @actor = @status_window.actor = @distro_window.actor = $game_party.actors[i]
     [@status_window, @distro_window].each {|win| win.refresh}
     @distro_window.index = 0
    end
   when 2
    if @distro_window.points != 0
     @command_window.active = false
     make_sure_window
    else
     i = (@actor.index+$game_party.actors.size-1) % $game_party.actors.size
     @actor = @status_window.actor = @distro_window.actor = $game_party.actors[i]
     [@status_window, @distro_window].each {|win| win.refresh}
     @distro_window.index = 0
    end
   when 3
    if @distro_window.points != 0
     @command_window.active = false
     make_sure_window
    else
     $scene = @scene.new
    end
   end
  end
 end
Â
 def update_sure
  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)
   case @command_window.index
   when 1
    if @sure_window.index > 0
     @distro_window.set_new_attributes if @sure_window.index == 1
     i = (@actor.index+1) % $game_party.actors.size
     @actor = @status_window.actor = @distro_window.actor = $game_party.actors[i]
     [@status_window, @distro_window].each {|win| win.refresh}
    end
    @sure_window.dispose
    @sure_window, @command_window.active = nil, true
   when 2
    if @sure_window.index > 0
     @distro_window.set_new_attributes if @sure_window.index == 1
     i = (@actor.index+$game_party.actors.size-1) % $game_party.actors.size
     @actor = @status_window.actor = @distro_window.actor = $game_party.actors[i]
     [@status_window, @distro_window].each {|win| win.refresh}
    end
    @sure_window.dispose
    @sure_window, @command_window.active = nil, true
   when 3
    if @sure_window.index > 0
     @distro_window.set_new_attributes if @sure_window.index == 1
     $scene = @scene.new
    end
    @sure_window.dispose
    @sure_window, @command_window.active = nil, true
   end
  end
 end
Â
end
#==============================================================================
# Scene_Battle
#==============================================================================
class Scene_Battle
Â
 alias main_sds_later main
 def main
  main_sds_later
  if BlizzCFG::AUTOMATIC_CALL &&
    $game_party.actors.any? {|actor| actor.points > 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::AUTOMATIC_MAP_CALL &&
    $game_party.actors.any? {|actor| actor.points > 0}
   $scene = Scene_Points.new
  end
 end
Â
 def check_icon
  if $game_party.actors.any? {|actor| actor.points > 0}
   if @notify == nil
    @notify = RPG::Sprite.new
    if BlizzCFG::OWN_ICON
     @notify.bitmap = RPG::Cache.icon('point_notify')
    else
     @notify.bitmap = Bitmap.new(24, 24)
     @notify.bitmap.fill_rect(0, 0, 24, 24, Color.new(255, 255, 255))
     @notify.bitmap.fill_rect(22, 1, 2, 23, Color.new(0, 0, 0))
     @notify.bitmap.fill_rect(1, 22, 23, 2, Color.new(0, 0, 0))
     @notify.bitmap.set_pixel(23, 0, Color.new(0, 0, 0))
     @notify.bitmap.set_pixel(0, 23, Color.new(0, 0, 0))
     @notify.bitmap.fill_rect(2, 2, 20, 20, Color.new(0, 0, 224))
     @notify.bitmap.fill_rect(4, 10, 16, 4, Color.new(255, 255, 255))
     @notify.bitmap.fill_rect(10, 4, 4, 16, Color.new(255, 255, 255))
     @notify.opacity = BlizzCFG::ICON_DATA[2]
    end
    @notify.x, @notify.y = BlizzCFG::ICON_DATA[0, 2]
    @notify.z = 5000
    @notify.blink_on
   end
   @notify.update
  elsif @notify != nil
   @notify.dispose
   @notify = nil
  end
 end
Â
end