Equipment Set Bonuses
Version: 1.0
Author: modern algebra
Date: May 24, 2010
Version History
- <Version 1.0> 05.24.2010 - Original Release
Description
This script allows you to set bonuses to stats if an actor is wearing equipment of the same set, such as in Diablo II or Dragon Age: Origins. With this script, for instance, you could make a sword with ATK 10 and a Shield with DEF 10, but if you have both that sword and shield equipped you would get an additional 5 ATK and DEF, so that you would get 15 ATK and 15 DEF. By default, you can make sets that can give bonuses to maxhp, maxmp, atk, def, spi, and agi, as well as apply states. As well, the
Global Text Codes script is recommended if you wish to colour code sets.
Features
- Allows you to give bonuses to stats if an actor is wearing all the items of a set
- Can see what set the item belongs to by pressing a button (SHIFT by default) while hovering over it
- Can create sets that will give smaller bonuses if they are only partially completed
Screenshots Instructions
Please see the header and Editable regions for instructions on configuring the script.
Script
#==============================================================================
# Equipment Set Bonuses
# Version: 1.0
# Author: modern algebra (rmrk.net)
# Date: May 24, 2010
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Description:
#
# This script allows you to set bonuses to stats if an actor is wearing
# equipment of the same set, such as in Diablo II or Dragon Age: Origins.
# With this script, for instance, you could make a sword with ATK 10 and
# a Shield with DEF 10, but if you have both that sword and shield equipped
# you would get an additional 5 ATK and DEF, so that you would get 15 ATK and
# 15 DEF. By default, you can make sets that can give bonuses to maxhp, maxmp,
# atk, def, spi, and agi, as well as apply states.
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Instructions:
#
# Place this script in its own slot in the Script Editor (F11), somewhere
# below Materials but above Main.
#
# To setup sets and the bonuses they will give, go to line x38 and read the
# instructions located there.
#
# To assign an equipment to a set, simply put the following code in its
# notebox:
# \SET[set_id]
# set_id : the ID of the set this equipment belongs to, as per the
# setup at line 48.
# Note that you can assign the same piece of equipment to multiple sets by
# placing a comma and writing the next set_id, like so:
# \SET[set_id_1, set_id_2, ..., set_id_n]
#==============================================================================
ESB_SET_BONUSES = { # <- Do not touch this line
#\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
# EDITABLE REGION
#||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# ESB_SET_BONUSES -
# This is where you set up the sets, give them a name, and determine what
# bonuses they give if an actor is wearing a complete set. The format for
# setting it up is:
#
# set_id => {
# :name => "name",
# :states => [state_ids],
# :maxhp => maxhp_bonus,
# :maxmp => maxmp_bonus,
# :atk => atk_bonus,
# :def => def_bonus,
# :spi => spi_bonus,
# :agi => agi_bonus
# }
#
# where:
# set_id - the ID of the set. This is used to identify which equipment
# belongs to which set, which you do in the note field of the equipment.
# See line 27 for details. Note that this must be an integer, but beyond
# that can be anything. Whatever you do though, this must be unique, so
# don't make more than one set with this ID.
# "name" - the name of the set. This is what will show up in the help box
# when you press the Display button (see line yy to set) on a set item.
# It can be used for more than one set, if you want to create bonuses
# for partial sets.
# [state_ids] - this is an array of states that should be applied if an
# actor has completed this set. So, if you want an actor who wears a
# complete set to have a state applied, put the ID of that state in this
# array, like so: [10] - that would apply state 10 (by default, DEF UP)
# for as long as the complete set is equipped. [9, 10] would apply both
# states 9 and 10 (by default, ATK UP and DEF UP).
# stat_bonus - the rest of them are the value of whatever bonus you want
# applied to that stat. So, if you want a complete set to give a bonus
# of 10 to DEF and a bonus of 5 to agi, you would have:
# :def => 10,
# :agi => 5
# If you do not set a stat, it will default to 0, meaning it won't give
# a bonus to that particular stat.
# EXAMPLES:
#
# 1 => {
# :name => "Leopold's Outfit",
# :atk => 5,
# :def => 15,
# :agi => 3
# },
#
# That code creates a set with ID 1, meaning that all items that have the code
# \set[1] in their note field must be equipped for these bonuses to be active.
# The name that shows up when hovering over an item of that script and pressing
# the display button is Leopold's Outfit. When all items of that set are
# equipped, the actor gets a bonus of 5 to his/her attack, 15 to his/her
# defence, and 3 to his/her agility.
#
# 3 => {
# :name => "Heaven's Wrath",
# :states => [9]
# :maxhp => 250,
# :maxmp => -250,
# :spi => -25
# },
#
# That code creates a set with ID 3, meaning that all items that have the code
# \set[3] in their note field must be equipped for these bonuses to be active.
# The name that shows up when hovering over an item of that script and pressing
# the display button is Heaven's Wrath. When all items of that set are equipped,
# the actor has the state with ID 9 applied (ATK UP by default), gets an extra
# 250 MaxHP, loses 250 MaxMP, and loses 25 Spirit
#
# Note that you can potentially add more stats via ESB_STAT_MODS at line zz,
# but only if you are using some script that gives more stats to actors and it
# follows the same format as the atk, def, spi, and agi methods. Read the
# instructions at line zz for more details.
#||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1 => {
:name => "",
:states => [],
:maxhp => 0,
:maxmp => 0,
:atk => 0,
:def => 0,
:spi => 0,
:agi => 0
},
2 => { # EXAMPLE
:name => "Leopold's Haven",
:def => 10
}
} # <- do not touch the } on this line
#||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# ESB_SET_DISPLAY_BUTTON -
# This allows you to set a button, that, when pressed while hovering over a set
# item in the item or equip scenes, will show the name of the set(s) it belongs
# to. Note that it requires a button, which doesn't necessarily correspond to
# that key on the keyboard. Press F1 during testplay to see a list of the
# buttons and what key they correspond to.
ESB_SET_DISPLAY_BUTTON = Input::SHIFT
#||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# ESB_SET_DISPLAY_VOCAB -
# This is the text that will appear directly before the list of names of the
# sets the item belongs to when pressing ESB_SET_DISPLAY_BUTTON while hovering
# over a set item.
ESB_SET_DISPLAY_VOCAB = "Set Item: "
#||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# ESB_STAT_MODS -
# You probably shouldn't touch this. It is simply a way to add other
# possibilities for stat bonuses, where those stats are set up more or less in
# the same way that the default atk, def, spi, and agi stats are. For example,
# if you are using YEM New Battler Stats, you could add them to this array as
# :res, :dex
# Then, where you set up the set bonuses at line 38, you could use the codes:
# :res => x,
# :dex => y
# and those bonuses would be granted when you complete the set. But you need to
# add them to the below array if you want to be able to do it, so:
# ESB_STAT_MODS = [:maxhp, :maxmp, :atk, :def, :spi, :agi, :res, :dex]
#
# NB: that's only if you have YEM New Battler Stats, and if you do, you will
# need to put the New Battler Stats script above this one in the editor, and you
# would need to get the compatibility patch located in the main topic thread
ESB_STAT_MODS = [:maxhp, :maxmp, :atk, :def, :spi, :agi]
#||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# END EDITABLE REGION
#//////////////////////////////////////////////////////////////////////////////
ESB_SET_BONUSES.each_value { |set|
set[:name] = "" if !set[:name]
set[:states] = [] if !set[:states]
set.default = 0
}
#==============================================================================
# ** Data_EquipmentSet
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# This struct holds all relevant data on an Equipment Set
#==============================================================================
Data_EquipmentSet = Struct.new (:id, :name, :equips, :states, *ESB_STAT_MODS)
#==============================================================================
# ** Data_EquipmentSets
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# This class is a wrapper for an array of Data_EquipmentSet objects
#==============================================================================
class Data_EquipmentSets
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Object Initialization
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def initialize
@data = []
@equips = {}
for i in 1...$data_weapons.size
$data_weapons[i].set_ids.each { |set_id|
@equips[set_id] = [] if !@equips[set_id]
@equips[set_id].push ([1, i])
}
end
for i in 1...$data_armors.size
$data_armors[i].set_ids.each { |set_id|
@equips[set_id] = [] if !@equips[set_id]
@equips[set_id].push ([2, i])
}
end
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Get Set
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def [] (id)
if !@data[id]
name = ESB_SET_BONUSES[id][:name].to_s
states = ESB_SET_BONUSES[id][:states]
stats = []
ESB_STAT_MODS.each { |sym| stats.push (ESB_SET_BONUSES[id][sym]) }
@data[id] = Data_EquipmentSet.new (id, name, @equips[id], states, *stats)
end
return @data[id]
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Get Equips
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def get_equips (id)
equips = []
@equips[id].each { |type, item_id|
equip = case type
when 1 then $data_weapons[item_id]
when 2 then $data_armors[item_id]
end
equips.push (equip)
}
return equips
end
end
#==============================================================================
# ** RPG::BaseItem
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Summary of Changes:
# new method - set_ids
#==============================================================================
class RPG::BaseItem
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Set IDs
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def set_ids
set_ids = []
self.note.scan (/\\SET\[[\d,\s]+\]/i).each { |string|
string.scan (/\d+/).each { |id| set_ids.push (id.to_i) }
}
return set_ids
end
end
#==============================================================================
# ** Game_Actor
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Summary of Changes:
# aliased methods - initialize, change_equip, (+ ESB_STAT_MODS)
# new methods - calculate_set_bonuses
#==============================================================================
class Game_Actor
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * ESB_STATS aliases
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(ESB_STAT_MODS).each { |sym|
attr_accessor "set_#{sym}".to_sym
next if [:maxhp, :maxmp].include? (sym)
EQPSET_ALIAS = <<__END__
alias malg_eqpsets_#{sym} #{sym}
def #{sym} (*args)
@#{sym}_plus = 0 if !@#{sym}_plus
@#{sym}_plus += @set_#{sym}
value = malg_eqpsets_#{sym} (*args)
@#{sym}_plus -= @set_#{sym}
return value
end
__END__
eval (EQPSET_ALIAS)
}
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * MaxHP, MaxMP
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias modalgb_esbmaxhp_8i3k maxhp
def maxhp (*args)
@maxhp_plus += @set_maxhp
value = modalgb_esbmaxhp_8i3k (*args)
@maxhp_plus -= @set_maxhp
@hp = [@hp, value].min
return value
end
alias modrn_esb_mxmp_5sc2 maxmp
def maxmp (*args)
@maxmp_plus += @set_maxmp
value = modrn_esb_mxmp_5sc2 (*args)
@maxmp_plus -= @set_maxmp
@mp = [@mp, value].min
return value
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Object Initialization
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias monalb_esb_intze_6yj2 initialize
def initialize (*args)
ESB_STAT_MODS.each { |sym| self.send ("set_#{sym}=".to_sym, 0) }
@set_states = []
monalb_esb_intze_6yj2 (*args) # Run Original Method
calculate_set_bonuses
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Calculate Set Bonuses
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def calculate_set_bonuses
ESB_STAT_MODS.each { |sym| self.send ("set_#{sym}=".to_sym, 0) }
@set_states = []
sets_to_check = []
equips.each { |equip|
next unless equip
sets_to_check.push (*equip.set_ids)
}
sets_to_check.uniq.each { |set_id|
set_equips = $data_equipmentsets.get_equips (set_id)
if (set_equips & equips).size == set_equips.size
eqpset = $data_equipmentsets[set_id]
ESB_STAT_MODS.each { |sym|
self.send ( "set_#{sym}=".to_sym, self.send ("set_#{sym}".to_sym) + eqpset.send (sym) )
}
@set_states += eqpset.states
end
}
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Change Equipment
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias monab_eqsetbon_chngeqp_1ax3 change_equip
def change_equip (*args)
monab_eqsetbon_chngeqp_1ax3 (*args) # Run Original Method
calculate_set_bonuses
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * States
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias monabra_equps_states_1dc4 states
def states (*args)
result = monabra_equps_states_1dc4 (*args) # Run Original Method
for state_id in @set_states
state = $data_states[state_id]
next if result.include? (state)
skip = false
result.each { |state2|
if state2.state_set.include? (state.id)
skip = true
break
end
}
next if skip
state.state_set.each { |state_id|
result.delete ($data_states[state_id])
remove_state (state_id)
@removed_states.delete (state_id) # Don't report its removal
}
result.push (state)
end
return result
end
end
#==============================================================================
# ** Window_Selectable
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Summary of Changes:
# new method - esb_help_display_check
#==============================================================================
class Window_Selectable
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * ESB Help Display Check
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def esb_help_display_check
if Input.press? (ESB_SET_DISPLAY_BUTTON)
return true if @esb_item_check == item
@esb_item_check = item
if item && !item.set_ids.empty?
set_names = []
item.set_ids.each { |id|
name = $data_equipmentsets[id].name
set_names.push (name) if !set_names.include? (name) && !name.empty?
}
if !set_names.empty?
string = ESB_SET_DISPLAY_VOCAB
set_names.each { |name| string += "#{name}; " }
string.slice! (-2, 2)
@help_window.set_text (string)
return true
end
end
else
@esb_item_check = nil
end
return false
end
end
#==============================================================================
# ** Window_Item
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Summary of Changes:
# aliased method - update_help
#==============================================================================
class Window_Item
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Update Help
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias mdrnab_esb_updhlp_7ux4 update_help
def update_help (*args)
# Run Original Method if not showing set
mdrnab_esb_updhlp_7ux4 (*args) unless esb_help_display_check
end
end
#==============================================================================
# ** Window_Equip
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Summary of Changes:
# aliased method - update_help
#==============================================================================
class Window_Equip
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Update Help
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias modlg_esbonus_hlpupte_6yh2 update_help
def update_help (*args)
# Run Original Method if not showing set
modlg_esbonus_hlpupte_6yh2 (*args) unless esb_help_display_check
end
end
#==============================================================================
# ** Scene_Title
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Summary of Changes:
# aliased methods - load_database; load_bt_database
#==============================================================================
class Scene_Title
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Load Database
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias modalb_eqpsets_loddata_8ik4 load_database
def load_database (*args)
modalb_eqpsets_loddata_8ik4 (*args) # Run Original Method
$data_equipmentsets = Data_EquipmentSets.new
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Load Battle Test Database
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias morn_ests_btdatald_3ez2 load_bt_database
def load_bt_database (*args)
morn_ests_btdatald_3ez2 (*args) # Run Original Method
$data_equipmentsets = Data_EquipmentSets.new
end
end
Credit
Thanks
- Zeriab, for the countless aid he's given me over the years, and in particular for a few tricks that came in handy for this script.
Support
Please post in this thread at RMRK if you have any bugs or incompatibilities to report, or if you have ideas for a new version.
Known Compatibility Issues
No currently known compatibility errors. While the script allows you to set up other scripts within it, such as the YEM New Battler Stats, they will only work if those stats abide by the same structure that the default stats do, meaning that they need to have a method in Game_Battler that returns the value, and they need to have an instance variable: @plus_<> that allows to give bonuses. If you are unsure if a script will work with this, then please post in this topic and I will tell you.
Demo
Demo Link. Please note, however, that this is only meant to be a sample of what the script can do. It is better for you if you retrieve the script from this post, rather than the demo, as the demo is setup for use with Global Text Codes.