#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
# 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
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
#
# 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://www.chaosproject.co.nr
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
module BlizzCFG
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# START Configuration
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
STARTING_POINTS = 20
POINTS_PER_LEVEL = 10
DISPLAY_ICON = true
ICON_DATA = [612, 452, 192]
OWN_ICON = false
EVASION = 'EVA'
STR_LIMIT = 999
DEX_LIMIT = 999
AGI_LIMIT = 999
INT_LIMIT = 999
WINDOW_MODE = true
AUTOMATIC_CALL = true
AUTOMATIC_MAP_CALL = false
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# 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, 10, 44)
draw_actor_state(@actor, 4, 96)
self.contents.font.color = system_color
self.contents.draw_text(4, 64, 80, 32, 'Lv')
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, '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, 'DP 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