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 #:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
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
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
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
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