=begin ============================================================================== Custom Attributes v1.31 by AdiktuzMiko --- Date Created: 10/10/2014 --- Last Date Updated: 06/20/2015 --- Level: Easy ============================================================================== Overview ============================================================================== This script provides the ability to create your own custom attributes for your actors, together with it's own scene which allows you to increase the attributes. It has enough features for a basic attribute system, and can also be used as a base for a more complex attribute sysyem. ============================================================================== Set-Up ============================================================================== Just put this script into a blank slot above main but below materials (see compatibility section) and modify the settings below To increase an actor's attribute points actor_object.add_custom_attribute_points(value) To determine how much attribute points the actor has actor_object.get_custom_attribute_points To get the value of an attribute of an actor (base + bonus) actor_object.custom_attribute(index) To get the base value of an attribute of an actor actor_object.custom_attribute_no_bonus(index) To get the bonus value of an attribute of an actor actor_object.custom_attribute_bonus(index) To increase the base value of an attribute of an actor actor_object.add_custom_attribute(index,value) To increase the bonus value of an attribute of an actor actor_object.add_custom_attribute_bonus(index,value) To get the name of a custom attribute actor_object.custom_attribute_name(index) ---------------------------------------------------- The following is for locking and unlocking attributes. To learn more about lock/unlock, go to the attribute list set-up portion below ---------------------------------------------------- To unlock an attribute actor_object.unlock_custom_attribute(index) To lock a previously unlocked attribute (only works on attributes added via the unlock call) actor_object.lock_custom_attribute(index) ---------------------------------------------------- ---------------------------------------------------- To add a button for the attribute scene to your main menu: make a command that uses this method as a handler :command_attribute To call it from somewhere else SceneManager.call(Scene_CustomParam) ============================================================================== Compatibility ============================================================================== This script aliases Game_Actor's initialize method ============================================================================== Notes ============================================================================== The bonus value means values that won't be included in checking if you can still increase the value of the attribute using the attribtue scene. Using that, you can have equipments for example that gives bonus value to an attribute that can make your attribute go past the limit, assuming you have a script that allows running events or rgss3 methods upon equip/unequip like my equip extension script. Example: If I already have 9/10 of an attribute then I equip an item that adds 1 to that attribute's bonus value, it becomes 10/10. But since the 1 is added as a bonus instead of directly to the base value of the attribute, I can still increase that attribute on the scene so I can have 11/10. The custom attributes do nothing by default. It's all up to you to decide on how to use them. If you want to increase the attribute points per level up of the actor, you would use something like my Level Extension script. If you want to use them as a custom condition for equipments, you can use my Custom Equip Requirements script. If you want them to be used in damage calculation, you can use the damage formula for that. If you want them to increase a certain parameter with every point you use on them, find this method below: def on_custom_attribute_increase(index,value) end def on_custom_attribute_decrease(index,value) end where index is the index of the custom attribute, and value is the added/subtracted amount to it's level and edit it accordingly, use self to denote the actor Example: If I want attribute 2 to increase mhp by 10 def on_custom_attribute_increase(index,value) if index == 2 self.add_param(0,10) end end You can now also set specific methods to be run when a certain attribute is increased/decreased instead of the global one. More info on the following modules below. The global evaluation is done first before the specific ============================================================================== Terms and Conditions ============================================================================== View it here: http://lescripts.wordpress.com/terms-and-conditions/ ============================================================================== =end $imported = {} if $imported.nil? $imported["AdikCustomAttributes"] = 1.31 module ADIK module ATTRIBUTES #Important: Do not remove LIST = [] #List down your custom attributes here #LIST[index] = Attribute Name LIST[0] = "Sniper Rifle" LIST[1] = "Rifle" LIST[2] = "Handgun" LIST[3] = "Energy Sniper Rifle" LIST[4] = "Energy Rifle" LIST[5] = "Energy Handgun" LIST[6] = "Physical Bullets" LIST[7] = "Energy Bullets" LIST[8] = "Strength" LIST[9] = "Speed" #List of custom attributes each actor has access to #This just determines which attributes are shown on the #attributes page for each actor, you can still use the #script calls to modify the attribute of the actor even #if it's not on the actor's specific list #If an actor doesn't have a specific list, he will have all #attributes visible #You could also unlock an attribute using a script call stated on the #notes above. You can also lock a previously unlocked attribute. #ACTOR_LIST[index] = [attribute1,attribute2,...,and so on] ACTOR_LIST = [] ACTOR_LIST[1] = [] #Important: Do not remove #List down the descriptions for your custom attributes here #DESCRIPTION[index] = Description DESCRIPTION = [] DESCRIPTION[0] = "Increases proficiency with physical sniper rifles. Decreases reload speed and shot variance." DESCRIPTION[1] = "Increases proficiency with physical rifles. Decreases reload speed and shot variance." DESCRIPTION[2] = "Increases proficiency with physical handguns. Decreases reload speed and shot variance." DESCRIPTION[3] = "Increases proficiency with energy sniper rifles. Decreases shot variance." DESCRIPTION[4] = "Increases proficiency with energy rifles. Decreases shot variance." DESCRIPTION[5] = "Increases proficiency with energy handguns. Decreases shot variance." DESCRIPTION[6] = "Increases damage dealt with physical guns." DESCRIPTION[7] = "Increases damage dealt with energy guns." DESCRIPTION[8] = "Increases body strength to equip heavy equipment." DESCRIPTION[9] = "Increases speed allowing you to move and reload faster." #Important: Do not remove #List down the maximum points each attributes can reach #MAX[index] = value MAX = [] MAX[0] = 10 MAX[1] = 10 MAX[2] = 10 MAX[3] = 10 MAX[4] = 10 MAX[5] = 10 MAX[6] = 10 MAX[7] = 10 MAX[8] = 10 MAX[9] = 10 #Important: Do not remove #List down methods that will be run if the corresponding #attribute is increased #The methods should be created in the next module #format is: METHODS_INCREASE[index] = :method_name METHODS_INCREASE = {} METHODS_INCREASE[0] = :zero_inc #Important: Do not remove #List down methods that will be run if the corresponding #attribute is decreased #The methods should be created in the next module #format is: METHODS_INCREASE[index] = :method_name METHODS_DECREASE = {} METHODS_DECREASE[0] = :zero_dec #Windowskin for the attribute window MAIN_SKIN = "Window.png" #X position of attribute window MAIN_X = 240 #Y position of attribute window MAIN_Y = 96 #Width of attribute window MAIN_W = 544 #Height of attribute window MAIN_H = 264 #Windowskin for the description window DESCRIPTION_SKIN = "Window.png" #X position of attribute window DESCRIPTION_X = 0 #Y position of attribute window DESCRIPTION_Y = 24 #Width of attribute window DESCRIPTION_W = 1024 #Windowskin of actor window ACTOR_SKIN = "Window.png" #X position of actor window ACTOR_X = 0 #220 #Y position of actor window ACTOR_Y = 408 #Width of actor window ACTOR_W = 1024 #Background image for the scene #Needs to be inside Graphics\System #Set to nil if you want to use the default menu #background BACKGROUND = nil #X position of the value of the attribute #relative to X of attribute window VALUE_X = 24 #X position of the name of the attribute #relative to X of attribute window NAME_X = 96 #Font of the attribute name #[Font name, font size, normal color, disabled color, max color] NAME_FONT = [Font.default_name,18,Color.new(255,255,255),Color.new(100,100,100),Color.new(200,200,50)] #Font of the attribute value #[Font name, font size, normal color, disabled color, max color] VALUE_FONT = [Font.default_name,18,Color.new(0,255,200),Color.new(0,255,200),Color.new(255,0,0)] #Font of the description window #[Font name, font size, normal color] DESC_FONT = [Font.default_name,24,Color.new(255,255,255)] #Font of the actor window #[Font name, font size, normal color] ACTOR_FONT = [Font.default_name,24,Color.new(255,255,255)] #Show max value beside the current value SHOW_MAX = true #Separate the attribute bonus from the total? SEPARATE_BONUS = false end end module ADIK module CA_METHODS #add the methods for specific increase/decrease here #format is: #def self.method_name(actor,index,value) # do things here #end #actor is the actor which increased the attribute #index is the index of the custom attribute modified #value is the added/subtracted amount #example def self.zero_inc(actor,index,value) p "This is a test, it should only appear for attribute 0." end def self.zero_dec(actor,index,value) p "This is a test, it should only appear for attribute 0." end end end class Scene_CustomParam < Scene_Base #Text shown on actor window def actor_text(actor) return actor.name + " The " + actor.nickname + " - Attribute Points: " + actor.get_custom_attribute_points.to_s end end class Game_Actor #Contains the global attribute increase/decrease methods #Edit this to do custom things when an attribute is increased def on_custom_attribute_increase(index,value) p "System Message: Increased " + custom_attribute_name(index) end #Edit this to do custom things when an attribute is decreased def on_custom_attribute_decrease(index,value) end end #================================================================== #DO NOT EDIT BEYOND THIS POINT #================================================================== #================================================================== #I SAID DO NOT EDIT BEYOND THIS POINT #================================================================== class Game_Actor alias initialize_custom_attributes_adik initialize def initialize(actor_id) initialize_custom_attributes_adik(actor_id) load_custom_attributes load_custom_attributes_bonus load_custom_attributes_list(actor_id) @custom_attribute_points = 0 if @custom_attribute_points.nil? end def load_custom_attributes @custom_attribute = [] ADIK::ATTRIBUTES::LIST.each_index do |index| @custom_attribute[index] = [0,ADIK::ATTRIBUTES::LIST[index]] end end def load_custom_attributes_bonus @custom_attribute_bonus = [] ADIK::ATTRIBUTES::LIST.each_index do |index| @custom_attribute_bonus[index] = 0 end end def load_custom_attributes_list(actor_id) @custom_attribute_list = [] if ADIK::ATTRIBUTES::ACTOR_LIST[actor_id].nil? ADIK::ATTRIBUTES::LIST.each_index do |index| @custom_attribute_list.push(index) end else ADIK::ATTRIBUTES::ACTOR_LIST[actor_id].each do |index| @custom_attribute_list.push(index) end end end def get_custom_attribute_list_base load_custom_attributes_list(@actor_id) if @custom_attribute_list.nil? return @custom_attribute_list end def get_custom_attribute_list_unlocked @custom_attribute_list_ul = [] if @custom_attribute_list_ul.nil? return @custom_attribute_list_ul end def get_custom_attribute_list return get_custom_attribute_list_base + get_custom_attribute_list_unlocked end def get_custom_attribute_points @custom_attribute_points = 0 if @custom_attribute_points.nil? return @custom_attribute_points end def add_custom_attribute_points(value) @custom_attribute_points = 0 if @custom_attribute_points.nil? @custom_attribute_points += value end def custom_attributes return @custom_attribute end def custom_attributes_bonus return @custom_attribute_bonus end def custom_attribute(index) load_custom_attributes if @custom_attribute.nil? load_custom_attributes_bonus if @custom_attribute_bonus.nil? return @custom_attribute[index][0] + @custom_attribute_bonus[index] end def custom_attribute_no_bonus(index) load_custom_attributes if @custom_attribute.nil? return @custom_attribute[index][0] end def custom_attribute_bonus(index) load_custom_attributes_bonus if @custom_attribute_bonus.nil? return @custom_attribute_bonus[index] end def add_custom_attribute(index,value) load_custom_attributes if @custom_attribute.nil? @custom_attribute[index][0] += value if value > 0 on_custom_attribute_increase(index,value) if ADIK::ATTRIBUTES::METHODS_INCREASE.keys.include?(index) ADIK::CA_METHODS.method(ADIK::ATTRIBUTES::METHODS_INCREASE[index]).call(self,index,value) end elsif value < 0 on_custom_attribute_decrease(index,value) if ADIK::ATTRIBUTES::METHODS_DECREASE.keys.include?(index) ADIK::CA_METHODS.method(ADIK::ATTRIBUTES::METHODS_DECREASE[index]).call(self,index,value) end end end def add_custom_attribute_bonus(index,value) load_custom_attributes_bonus if @custom_attribute_bonus.nil? @custom_attribute_bonus[index] += value if value > 0 on_custom_attribute_increase(index,value) elsif value < 0 on_custom_attribute_decrease(index,value) end end def custom_attribute_name(index) load_custom_attributes if @custom_attribute.nil? return @custom_attribute[index][1] end def lock_custom_attribute(index) @custom_attribute_list_ul = [] if @custom_attribute_list_ul.nil? @custom_attribute_list_ul.delete(index) if @custom_attribute_list_ul.include?(index) end def unlock_custom_attribute(index) @custom_attribute_list_ul = [] if @custom_attribute_list_ul.nil? @custom_attribute_list_ul.push(index) unless @custom_attribute_list_ul.include?(index) end end class Window_CustomParam < Window_Command def initialize(x,y) super self.windowskin = Cache.system(ADIK::ATTRIBUTES::MAIN_SKIN) @actor = $game_party.members[0] create_help_window refresh update_help end def create_help_window @help_window = Window_CustomParamDesc.new(1) @help_window.x = ADIK::ATTRIBUTES::DESCRIPTION_X @help_window.y = ADIK::ATTRIBUTES::DESCRIPTION_Y @help_window.width = ADIK::ATTRIBUTES::DESCRIPTION_W @actor_window = Window_CustomParamActor.new(1) @actor_window.x = ADIK::ATTRIBUTES::ACTOR_X @actor_window.y = ADIK::ATTRIBUTES::ACTOR_Y @actor_window.width = ADIK::ATTRIBUTES::ACTOR_W end def window_width return ADIK::ATTRIBUTES::MAIN_W end def window_height return ADIK::ATTRIBUTES::MAIN_H end def set_actor(actor) @actor = actor refresh end def actor return @actor end def get_index return current_ext end def can_increase(index,value) return false if @actor.nil? return @actor.get_custom_attribute_points > 0 && (value < ADIK::ATTRIBUTES::MAX[index]) end def make_command_list return if @actor.nil? return if @actor.get_custom_attribute_list.empty? @actor.get_custom_attribute_list.each do |index| cparam = @actor.custom_attributes[index] add_command(cparam[1], cparam[1].to_sym,can_increase(index,cparam[0]), index) end end def refresh super return if @actor.nil? @actor_window.set_text(SceneManager.scene.actor_text(@actor)) end def draw_item(index) change_color(normal_color, command_enabled?(index)) rect = item_rect_for_text(index) rect = Rect.new(rect.x + ADIK::ATTRIBUTES::NAME_X,rect.y,rect.width,rect.height) contents.font.name = ADIK::ATTRIBUTES::NAME_FONT[0] contents.font.size = ADIK::ATTRIBUTES::NAME_FONT[1] if @actor.custom_attribute_no_bonus(index) >= ADIK::ATTRIBUTES::MAX[index] contents.font.color = ADIK::ATTRIBUTES::NAME_FONT[4] elsif @list[index][:enabled] contents.font.color = ADIK::ATTRIBUTES::NAME_FONT[2] else contents.font.color = ADIK::ATTRIBUTES::NAME_FONT[3] end draw_text(rect, command_name(index), alignment) rect = item_rect_for_text(index) rect = Rect.new(rect.x + ADIK::ATTRIBUTES::VALUE_X,rect.y,rect.width,rect.height) contents.font.name = ADIK::ATTRIBUTES::VALUE_FONT[0] contents.font.size = ADIK::ATTRIBUTES::VALUE_FONT[1] if @actor.custom_attribute_no_bonus(index) >= ADIK::ATTRIBUTES::MAX[index] contents.font.color = ADIK::ATTRIBUTES::VALUE_FONT[4] elsif @list[index][:enabled] contents.font.color = ADIK::ATTRIBUTES::VALUE_FONT[2] else contents.font.color = ADIK::ATTRIBUTES::VALUE_FONT[3] end if ADIK::ATTRIBUTES::SHOW_MAX if ADIK::ATTRIBUTES::SEPARATE_BONUS tx1 = @actor.custom_attribute_bonus(index).to_s tx2 = @actor.custom_attribute_no_bonus(index).to_s draw_text(rect, tx1 + " + " + tx2 + " / " + ADIK::ATTRIBUTES::MAX[index].to_s,alignment) else draw_text(rect,@actor.custom_attribute(index).to_s + " / " + ADIK::ATTRIBUTES::MAX[index].to_s,alignment) end else if ADIK::ATTRIBUTES::SEPARATE_BONUS tx1 = @actor.custom_attribute_bonus(index).to_s tx2 = @actor.custom_attribute_no_bonus(index).to_s draw_text(rect, tx1 + " + " + tx2,alignment) else draw_text(rect,@actor.custom_attribute(index),alignment) end end end def update_help if current_ext.nil? @help_window.set_text("") else @help_window.set_text(ADIK::ATTRIBUTES::DESCRIPTION[current_ext]) end end def dispose @actor_window.dispose @help_window.dispose super end end class Window_CustomParamDesc < Window_Help def initialize(line_height=1) super self.windowskin = Cache.system(ADIK::ATTRIBUTES::DESCRIPTION_SKIN) contents.font.name = ADIK::ATTRIBUTES::DESC_FONT[0] contents.font.size = ADIK::ATTRIBUTES::DESC_FONT[1] contents.font.color = ADIK::ATTRIBUTES::DESC_FONT[2] end def draw_text_ex(x, y, text) #reset_font_settings text = convert_escape_characters(text) pos = {:x => x, :y => y, :new_x => x, :height => calc_line_height(text)} process_character(text.slice!(0, 1), text, pos) until text.empty? end end class Window_CustomParamActor < Window_Help def initialize(line_height=1) super self.windowskin = Cache.system(ADIK::ATTRIBUTES::ACTOR_SKIN) contents.font.name = ADIK::ATTRIBUTES::ACTOR_FONT[0] contents.font.size = ADIK::ATTRIBUTES::ACTOR_FONT[1] contents.font.color = ADIK::ATTRIBUTES::ACTOR_FONT[2] end def draw_text_ex(x, y, text) #reset_font_settings text = convert_escape_characters(text) pos = {:x => x, :y => y, :new_x => x, :height => calc_line_height(text)} process_character(text.slice!(0, 1), text, pos) until text.empty? end end class Scene_CustomParam < Scene_Base def start super create_background create_attribute_window end def create_background @background_sprite = Sprite.new @background_sprite.bitmap = Cache.system(ADIK::ATTRIBUTES::BACKGROUND) return unless @background_sprite.bitmap.nil? @background_sprite.bitmap = SceneManager.background_bitmap @background_sprite.color.set(16, 16, 16, 128) end def create_attribute_window @attribute_window = Window_CustomParam.new(ADIK::ATTRIBUTES::MAIN_X,ADIK::ATTRIBUTES::MAIN_Y) @attribute_window.set_handler(:ok, method(:increase_custom_attribute)) @attribute_window.set_handler(:cancel, method(:return_scene)) @attribute_window.set_handler(:pagedown, method(:next_actor)) @attribute_window.set_handler(:pageup, method(:prev_actor)) end def increase_custom_attribute @attribute_window.actor.add_custom_attribute_points(-1) @attribute_window.actor.add_custom_attribute(@attribute_window.get_index,1) @attribute_window.refresh @attribute_window.activate end def next_actor index = $game_party.members.index(@attribute_window.actor) index += 1 if index == $game_party.members.size index = 0 end @attribute_window.set_actor($game_party.members[index]) @attribute_window.activate end def prev_actor index = $game_party.members.index(@attribute_window.actor) index -= 1 if index < 0 index = $game_party.members.size - 1 end @attribute_window.set_actor($game_party.members[index]) @attribute_window.activate end def terminate super @attribute_window.dispose @background_sprite.dispose end end class Scene_Menu def command_attribute SceneManager.call(Scene_CustomParam) end end