################################################################################# ## Abilities System V1 ## June 28, 2015 ## By Paramecium13 ## ##################################################################################===============================================================================# This is my abilities script. It allows you to define custom abilities that # actors can learn.# # #-------------------------------------------------------------------------------# To do-list:# *Write better descriptions# *Better formatting of said descriptions# *Better Windows and scenes# *More items on the to-do list#===============================================================================($imported ||= {})["Paramecium-Abilities"] = trueclass Game_Actor < Game_Battler attr_accessor :abilitiesendmodule AbilitiesSystem#-------------------------------------------------------------------------------# The following method needs to be called once at the start of a new game,# before any methods dealing with abilities are called.#------------------------------------------------------------------------------- #def self.initializeAbilities # for i in 1..(25) #$game_actors.length # $game_actors.abilities = {} if $game_actors # end #end#===============================================================================# This is the list of abilities. Add more abilities by using the same format as# the abilities presented as examples. A levelled ability is just what it sounds# like, it has levels (e.g. at level 72 smithing you can craft mithril stuff,# or at level 25 divination you have a 50% chance of detecting if a chest is a# trap or not). # The symbol ':id' must point to the same symbol that the list# (which is a hash) uses to access that ability.# The symbol ':name' points to a string that contains the in game name of that# ability.# The symbol ':desc' points to a string containing the in game description of# the ability.# The symbol ':levelled' points to the boolean that says if it is a levelled # ability, the following symbols for levelled abilities will be ignored if it is# false.# The symbols ':min' and ':max' point to the minimum and maximum levels of that# ability, respectively. You cannot make its level higher than the max or lower# than the min. I would like to implement "soft" minimums and maximums, which# can only be exceeded by temporary boosts or equipment.## WARNING: Don't forget the commas!!!!##=============================================================================== AbilityList = { :reading => { :id => :reading, :name => "Reading", :desc => "Can read", :levelled => false }, :smithing => { :id => :smithing, :name => "Smithing", :desc => "The ability to shape metals into tools, weapons, and armours", :levelled => true, :crafting => true, :recipes => [ ], :min => 1, :max => 100, :σ => 2*3.14159265359 }, rettyLights => { :id => rettyLights, :name => "Lights", :desc => "Makes pretty magic lights", :levelled => false, :cost => { # Yay, another hash :mp => 5 } }, :fireworks => { :id => :fireworks, :name => "Fireworks", :desc => "Makes fireworks", :levelled => false, :cost => { :items => [[20,1]] # ItemId,amount } } } recipeList = { :recipe1 => { :id => :club, :name => "Wooden Club", :requiredLevel => 10, :doAbCheck => false, :used =>{ :items => [[17,1]], :weapons => [], :armors => [] }, :needed => { :items => [], :weapons => [], :armors => [] }, :made => { :items => [], :weapons => [], :armors => [] } } }#===============================================================================# Methods for Use in Events#-------------------------------------------------------------------------------# To use one of these methods in a script call enter# AbilitiesSystem.method(param1,param2,...)# where method is the name of the method you want to use and param1,param2 are# the parameters for the method, as given in its description or definition#-------------------------------------------------------------------------------#===============================================================================# Controls#-------------------------------------------------------------------------------# These methods allow you to add, remove, and modify an actor's abilities. If# try to use one of these methods to modify an ability an actor doesn't have,# nothing will happen (and the game will not crash).#===============================================================================# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -## These add and remove an ability to an actor # Parameters:# actorId: The id of the actor whom you want to learn the ability# abilityId: The id of the ability you want the actor to learn# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# def self.addAbility(actorId,abilityId) return false if hasAbility?(actorId,abilityId) if not AbilityList[abilityId][:levelled] $game_actors[actorId].abilities[abilityId] = Ability.new(AbilityList[abilityId],actorId) elsif AbilityList[abilityId][:crafting] $game_actors[actorId].abilities[abilityId] = CraftingAbility.new(AbilityList[abilityId],actorId) else $game_actors[actorId].abilities[abilityId] = LevelledAbility.new(AbilityList[abilityId],actorId) end end def self.removeAbility(actorId,abilityId) $game_actors[actorId].abilities.delete(abilityId) if $game_actors[actorId].abilities end# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -## These enable, disable, and toggle whether or not an actor's ability is enabled.# Parameters:# actorId: The id of the actor whose ability you want to enable/disable/toggle# abilityId: The ability you want to enable/disable/toggle# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# def self.enableAbility(actorId,abilityId) ab = $game_actors[actorId].abilities[abilityId] ab.enable end def self.disableAbility(actorId,abilityId) ab = $game_actors[actorId].abilities[abilityId] ab.disable end def self.toggleAbility(actorId,abilityId) ab = $game_actors[actorId].abilities[abilityId] if ab.enabled ab.disable else ab.enable end end # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -## This increases the level of an actor's ability# ()# Parameters:# actorId: The id of the actor whose ability level you want to change# abilityId: The ability whose level you want to change# n: The ammount you want to change the level by, to decrease it, make 'n' # negative# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# def self.increaseLevel(actorId, abilityId,n) if AbilityList[abilityId][:levelled] && hasAbility?(actorId,abilityId) ab = $game_actors[actorId].abilities[abilityId] ab.increase(n) end end#===============================================================================# Individual Checks#-------------------------------------------------------------------------------# These methods allow you to #-------------------------------------------------------------------------------# This returns the level of the ability# Parameters:# actorId: The id of the actor whose ability you want to enable/disable/toggle# abilityId: The ability you want to enable/disable/toggle# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# def self.getLevel(actorId, abilityId) return false unless hasAbility?(actorId,abilityId) $game_actors[actorId].abilities[abilityId].getLevel end # This checks if an actor has a specified ability. def self.hasAbility?(actorId,abilityId) $game_actors[actorId].abilities = {} unless $game_actors[actorId].abilities return $game_actors[actorId].abilities.include?(abilityId) end # This checks if an actor has a specified ability and if it is enabled. def self.hasAbilityE?(actorId,abilityId) return false unless hasAbility?(actorId,abilityId) $game_actors[actorId].abilities[abilityId].enabled end # Performs an 'ability check' on the ability, using a normal distribution. def self.check(abilityId,actorId,difficulty,s=0) return false unless hasAbilityE?(actorId,abilityId) ab = $game_actors[actorId].abilities[abilityId] s = ab.σ if s = 0 return ab.check(difficulty,s) end # Checks if the ability level is >= the difficulty level. def self.simpleCheck(abilityId,actorId,difficulty) return false unless hasAbilityE?(actorId,abilityId) level = $game_actors[actorId].abilities[abilityId].level return level >= difficulty end#-------------------------------------------------------------------------------# Party Checks#-------------------------------------------------------------------------------# Checks if anyone in the party has that ability, returns an array of ids of# actors who have it. def self.p_hasAbility?(abilityId) r = [] actors = $game_party.members for i in 0..(actors.length-1) j = actors.id if hasAbility?(j,abilityId) r.push(j) end end r.empty? ? false : r end # Checks if anyone in the party has the ability enabled def self.p_hasAbilityE?(abilityId) r = [] actors = $game_party.members for i in 0..(actors.length-1) j = actors.id if hasAbilityE?(j,abilityId) r.push(j) end end r.empty? ? false : r end # Returns an array whose first entry is the id of the actor with the highest # level in the ability and whose second entry is their level in that ability. def self.p_highestLevel(abilityId) abilityRanking(abilityId).max end # These two methods perform the same 'checks' as 'check' and 'simpleCheck'# except they use the highest level of the skill in the party def self.p_check(abilityId,difficulty,s=0) x = p_highestLevel(abilityId) s = $game_actors[x[0]].abilities[abilityId].σ if s == 0 return Paramecium.abilityCheck(x[1], difficulty, s) end def self.p_simpleCheck(abilityId,difficulty) mLevel = p_highestLevel(abilityId) return mLevel >= difficulty end # Creates the levelled ability Ranking for the levelled ability 'abilityId' def self.abilityRanking(abilityId) ids = $game_party.members.collect {|actor| actor.id} arr = Array.new for i in 0..(ids.length-1) arr = [ids,getLevel(ids, abilityId)] end return Paramecium::Ranking.new(arr) end#-------------------------------------------------------------------------------# Ability Class#------------------------------------------------------------------------------- class Ability attr_reader wnerId attr_reader :id attr_accessor :name attr_accessor :iconId attr_accessor :description attr_accessor :enabled attr_accessor :mpCost attr_accessor :SE attr_accessor :SE_pass attr_accessor :SE_fail def initialize(hash,actorId) #@h = hash @name = hash[:name] ? hash[:name] : hash[:id] @description = hash[:desc] @iconId = hash[:iconId] @id = hash[:id] @enabled = true @ownerId = actorId @SE = hash[:SE] @SE_pass = hash[:SE_pass] @SE_fail = hash[:SE_fail] if hash[:cost] @mpCost = hash[:cost][:mp] ? hash[:cost][:mp] : 0 @itemCost = hash[:cost][:items] ? hash[:cost][:items] : [] @weaponCost = hash[:cost][:weapon] ? hash[:cost][:weapon] : [] @armorCost = hash[:cost][:armor] ? hash[:cost][:armor] : [] end end def getLevel; return 1; end # Plays the sound effect for the ability (if it has one) def playSound if @SE Audio.se_play(@SE) end end def canAfford? return false unless $game_actors[@ownerId].mp >= @costHash[:mp] return false unless Paramecium.invContains?(@itemCost,"ice") return false unless Paramecium.invContains?(@weaponCost,"wet") return false unless Paramecium.invContains?(@armorCost,"Arctic") return true end def useCost $game_actors[@ownerId].mp -= @costHash[:mp] if @costHash[:mp] Paramecium.changeInv(Paramecium.negatePos(@itemCost,1),"i") Paramecium.changeInv(Paramecium.negatePos(@weaponCost,1),"w") Paramecium.changeInv(Paramecium.negatePos(@armorCost,1),"a") end def use # Returns true if it was used successfully playSound if canAfford? && @enabled if @SE_pass Audio.se_play(@SE_pass) end useCost return true else if @SE_fail Audio.se_play(@SE_fail) end return false end end end#-------------------------------------------------------------------------------# Levelled Ability Class#------------------------------------------------------------------------------- class LevelledAbility < Ability attr_accessor :max attr_accessor :min attr_accessor :σ def initialize(hash,actorId) super(hash,actorId) @min = hash[:min] # The minimum allowed level @max = hash[:max] # The maximum allowed level @σ = hash[:σ] ? hash[:σ] : 2.5 # The default standard deviation @level = self.min end # Gets the level of this ability without applying bonuses def getRawLevel; return @level; end def getLevel; return @level + bonuses; end # Increases the level of the ability within the range [min,max] def increase(n) if @max && @level + n >= @max @level = max else if @min && @level + n <= @min @level = @min else @level += n end end end # Scales the level of the ability within the range [min,max] def scale(n) if @max && @level * n >= @max @level = max else if @min && @level * n <= @min @level = @min else @level *= n end end end def reset; @level = @min; end def set(n); @level = n; end def armBonus(armorID) $sub = @id.to_s $data_armors[armorID].note[/<AbilityBonus:\s*#{$sub},([0-9]+)>/i] if $1 && $1 != "" val = $1.to_i return val else return 0 end end def armorBonus b = 0 armors = $game_actors[@ownerId].armors armorIds = armors.collect {|a| a.id} for i in 0..(armorIds.length-1) b += armBonus(armorIds) end return b end def wBonus(weaponID) $sub = @id.to_s $data_weapons[weaponID].note[/<AbilityBonus:\s*#{$sub},([0-9]+)>/i] if $1 && $1 != "" val = $1.to_i return val else return 0 end end def weaponBonus b = 0 weapons = $game_actors[@ownerId].weapons weaponIds = weapons.collect {|a| a.id} for i in 0..(weaponIds.length-1) b += wBonus(weaponIds) end return b end def sBonus(stateID) $sub = @id.to_s $data_weapons[stateID].note[/<AbilityBonus:\s*#{$sub},([0-9]+)>/i] if $1 && $1 != "" val = $1.to_i return val else return 0 end end def stateBonus b = 0 states = $game_actors[@ownerId].states stateIds = states.collect {|a| a.id} for i in 0..(stateIds.length-1) b += sBonus(stateIds,abilityId) end return b end def bonuses return armorBonus + weaponBonus + stateBonus end def check(difficulty,s = @σ) lvl = @level + bonuses return Paramecium.abilityCheck(lvl, difficulty,s) end def use(difficulty,s = @σ) # Returns true if it was used successfully if canAfford? && @enabled if check(difficulty,s) Audio.se_play(@SE_pass) if @SE_pass true else Audio.se_play(@SE_fail) if @SE_fail false end else if @SE_fail Audio.se_play(@SE_fail) end false end end end#-------------------------------------------------------------------------------# Recipe Class#------------------------------------------------------------------------------- class Recipe attr_reader :name attr_reader :usedItems attr_reader :usedWeapons attr_reader :usedArmors attr_reader :neededItems attr_reader :neededWeapons attr_reader :neededArmors attr_reader :madeItems attr_reader :madeWeapons attr_reader :madeArmors def initialize(hash,actorId,abilityId) @id = hash[:id].to_s @name = hash[:name] ? hash[:name] : hash[:id] @requiredLevel = hash[:level] ? hash[:level] : 1 @doAbCheck = hash[:doAbCheck] @usedItems = hash[:used][:items] || [] @usedWeapons = hash[:used][:Weapons] || [] @usedArmors = hash[:used][:Armors] || [] @neededItems = hash[:needed][:items] || [] @neededWeapons = hash[:needed][:Weapons] || [] @neededArmors = hash[:needed][:Armors] || [] @madeItems = hash[:made][:items] || [] @madeWeapons = hash[:made][:Weapons] || [] @madeArmors = hash[:made][:Armors] || [] end # Does the player have the required materials? def hasMaterials? return false unless Paramecium.invContains?(@usedItems,"ice") return false unless Paramecium.invContains?(@usedWeapons,"wet") return false unless Paramecium.invContains?(@usedArmors,"Arctic") return false unless Paramecium.invContains?(@neededItems,"Insect") return false unless Paramecium.invContains?(@neededWeapons,"Waterloo") return false unless Paramecium.invContains?(@neededArmors,"Arthropod") end # Can the player craft this? def canCraft? abilityLevel = $game_actors[@actorId].abilities[@abilityId].getLevel abilityLevel >= @requiredLevel && hasMaterials? end def craft Paramecium.changeInv(@madeItems,"i") Paramecium.changeInv(@madeWeapons,"w") Paramecium.changeInv(@madeArmors,"a") Paramecium.changeInv(Paramecium.negatePos(@usedItems,1),"i") Paramecium.changeInv(Paramecium.negatePos(@usedWeapons,1),"w") Paramecium.changeInv(Paramecium.negatePos(@usedArmors,1),"a") end end #-------------------------------------------------------------------------------# Crafting Ability Class#------------------------------------------------------------------------------- class CraftingAbility < LevelledAbility attr_reader :recipes def initialize(hash,actorId) super(hash,actorId) @recipes = [] hash[:recipes].each {|r| addRecipe(r)} if hash[:recipes] end def addRecipe(r) h = recipeList[r] ? recipeList[r] : r @recipes.push(Recipe.new(h,actorId,@id)) end # Returns the description of the selected recipe def showAll c = [] @recipes.each{|recipe| c.push([recipe.name,recipe.description]) } Paramecium.selection(c) end def getCraftable # With names craftable = [] @recipes.each_index{|i| craftable.push(@recipes.name,i) if @recipes.canCraft? } craftable end # Returns the description of the selected recipe def showCraftable @recipes[Paramecium.selection(getCraftable)].description end def chooseCraftable @recipes[Paramecium.selection(getCraftable)].craft end endend# Ability Scene and Windowclass Scene_Menu < Scene_MenuBase alias abilitySystem_create_command_window create_command_window def create_command_window abilitySystem_create_command_window @command_window.set_handlerabilities, methodcommand_personal)) end def ccw_abilities msgbox_p("Abilities menu is under construction") SceneManager.call(Scene_Menu) end alias paramecium_personal_ok on_personal_ok def on_personal_ok return SceneManager.call(Scene_Abilites) if @command_window.current_symbol == :abilities paramecium_personal_ok endendclass Window_MenuCommand < Window_Command alias abilitySystem_add_original_commands add_original_commands def add_original_commands abilitySystem_add_original_commands add_command("Abilities",:abilities) end endclass Scene_Abilites < Scene_MenuBase def start super @ability_window = Window_Abilities.new(@actor) @ability_window.set_handlercancel, methodreturn_scene)) @ability_window.set_handlerpagedown, methodnext_actor)) @ability_window.set_handlerpageup, methodprev_actor)) end def on_actor_change @ability_window.actor = @actor @ability_window.activate endendclass Window_Abilities < Window_Selectable def initialize(actor) super(0, 0, Graphics.width, Graphics.height) @actor = actor refresh activate end def actor=(actor) return if @actor == actor @actor = actor refresh end def refresh contents.clear draw_abilities(10,10) end def draw_abilities(x,y) msgbox_p("hi") abs = @actor.abilities.values abs.each_with_index do |ability, i| draw_ability_name(ability, x, y + line_height * i) end end def draw_ability_name(ability, x, y, enabled = true, width = 172) return unless ability msgbox_p("Hello") if ability.iconId draw_icon(ability.iconId, x, y, enabled) end change_color(normal_color, enabled) draw_text(x + 34, y, width, line_height, ability.name) if ability.is_a?(LevelledAbility) draw_text(x + 200, y, width, line_height, ability.level) end endend