#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:= # Stat Distribution System by Blizzard # Version: 2.1 # 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 # Date v2.0: 18.10.2009 # Date v2.01: 28.7.2010 # Date v2.1: 16.12.2011 #:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:= # # 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 AUTO_CALL after battle # - new AUTO_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 # # new in v2.0: # - improved coding and overworked system (corrupts old savegames with older # version of this system!) # - new design # - new support for HP and SP # - now possible to configure multiple points for one stat # # new in v2.01: # - fixed bug with display of remaining DP # # new in v2.1: # - fixed bug with calculation of DP allowance # # # Configuration: # # Set up the configuration below. # # STARTING_DP - how many points should the actor have initially at level 1 # DP_PER_LEVEL - how many points should the actor gain per level # 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 # # # You can always add change DP yourself by using following syntax: # # $game_party.actors[POSITION].dp = VALUE # $game_actors[ID].dp = VALUE # # POSITION - position of actor in the party (STARTS FROM ZERO!) # ID - ID of actor in the database # VALUE - 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 DP. You MUST do it # manually. # # # If you find any bugs, please report them here: # http://www.chaosproject.co.nr #:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:= module BlizzCFG #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: # START Configuration #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: STARTING_DP = 200 DP_PER_LEVEL = 100 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 = 'DP' EvasionName = 'EVA' EXPText = 'EXP' NextText = 'next' EquipmentText = 'Equipment' AreYouSure = 'Are you sure?' DistroCommands = ['Distribute DP', 'Next Character', 'Previous Character', '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.1 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 :dp alias setup_sds_later setup def setup(actor_id) @dp = BlizzCFG::STARTING_DP setup_sds_later(actor_id) end alias exp_sds_later exp= def exp=(exp) old_level = @level exp_sds_later(exp) value = (@level - old_level) * BlizzCFG::DP_PER_LEVEL self.dp += value if value > 0 end def dp=(value) @dp = (value < 0 ? 0 : value) 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::EvasionName) 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_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) draw_actor_parameter(@actor, 4, 192, 7) 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, @dp_left = actor, actor.dp refresh end def set_dp(value) @dp_left = actor.dp - 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, "#{@dp_left} / #{@actor.dp}", 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.dp -= @spent.sum self.actor = @actor 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) limit = BlizzCFG::AttrLimits[index] - (@current[index] + @spent[index] / BlizzCFG::ExchangeRates[index]) remaining = (@actor.dp - @spent.sum) / BlizzCFG::ExchangeRates[index] limit = remaining if limit > remaining value = limit if value > limit if value > 0 @spent[index] += value * BlizzCFG::ExchangeRates[index] return true end return false end def remove_points(value) limit = @spent[index] / BlizzCFG::ExchangeRates[index] value = limit if value > limit 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 @distro_window.active @distro_window.update update_distro end end def update_main_command if Input.trigger?(Input::B) $game_system.se_play($data_system.cancel_se) $scene = @scene.new elsif Input.trigger?(Input::C) $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 @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 i = @status_window.actor.index + 1 i %= $game_party.actors.size @status_window.actor = @distro_window.actor = @dp_window.actor = $game_party.actors[i] when 2 i = @status_window.actor.index + $game_party.actors.size - 1 i %= $game_party.actors.size @status_window.actor = @distro_window.actor = @dp_window.actor = $game_party.actors[i] when 3 $scene = @scene.new 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.dp > 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.dp > 0} $scene = Scene_Points.new end end def check_icon if $game_party.actors.any? {|actor| actor.dp > 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