#==============================================================================| # ** DoubleX RMVXA Unison Skills/Items v1.01d | #------------------------------------------------------------------------------| # * Changelog | # v1.01d(GMT 0300 21-7-2015): | # - Increased this script's effectiveness, efficiency and flexibility | # v1.01c(GMT 0900 1-6-2014): | # - Fixed unison item not invoking common event bug | # v1.01b(GMT 0030 13-2-2014): | # - Fixed nil @input_actor and @unison_actor bug | # v1.01a(GMT 0700 7-2-2014): | # - Added <unison param: x> notetag | # v1.00e(GMT 0300 26-1-2014): | # - Fixed nil, non-skill and non-item item bug | # v1.00d(GMT 0500 24-1-2014): | # - Fixed Action Times+ Bug | # v1.00c(GMT 0900 16-1-2014): | # - Unison skills and items can only be selected by their unison actors | # v1.00b(GMT 1300 15-1-2014): | # - Fixed $game_actors[actor_id] with actor_id equals nil bug | # v1.00a(GMT 0600 15-1-2014): | # - 1st version of this script finished | #------------------------------------------------------------------------------| # * Author | # DoubleX | #------------------------------------------------------------------------------| # * Terms of use | # None other than not claiming this script as created by anyone except | # DoubleX or his alias | #------------------------------------------------------------------------------| # * Prerequisites | # Scripts: | # - none | # Knowledge: | # - Use of notetags | #------------------------------------------------------------------------------| # * Functions | # - Allows users to create unison skills or items for actors | #------------------------------------------------------------------------------| # * Manual | # To use this script, open the script editor and put this script into an | # open slot between ▼ Materials and ▼ Main. Save to take effect. | #------------------------------------------------------------------------------| # * Compatibility | # Scripts rewriting or aliasing: | # - load_database under DataManager | # - param, inputable? or usable? under Game_BattlerBase | # - make_damage_value or use_item under Game_Battler | # - clear_actions or next_command under Game_Actor | # - enable? under Window_ItemList | # - display_use_item under Window_BattleLog | # - start, next_command, prior_command or turn_start under Scene_Battle | # may have compatibility issues with this script | # Place this script above those aliasing any of these methods if possible | #==============================================================================| ($imported ||= {})["DoubleX RMVXA Unison Item"] = true #------------------------------------------------------------------------------| # * Notetag <unison item: x> for skills and items: | # x is the list of id of actors needed for the skill or item. For instance: | # - <unison item: 1> means actor with id 1 is required to use it | # - <unison item: 4, 2> means actors with id 4 and 2 are needed to use it | # All actors in list x needs to be in the battle, inputable, able to use it | # and pay its cost. They'll all pay the cost after using it. Only actors in | # list x can select it. | #------------------------------------------------------------------------------| # * Notetag <unison rule: x> for skills and items: | # x is the rule of setting parameters used in the damage formula of the | # skill or item. Notetag setting overrides the universal UNISON_PARAM_RULE. | # This notetag doesn't work if <unison item: x> is absent or x is nil. | #------------------------------------------------------------------------------| # * Notetag <unison param: x> for skills and items: | # x is the list of id of actors needed for the skill or item and stat is | # parameters used in its damage formula. For instance: | # - <unison atk: 1> means atk in its damage formula uses atk of actor with | # id 1 | # - <unison mat: 4, 2> means mat in its damage formula uses mat of actors | # with id 4 and 2 under unison rule specified in <unison rule: x> notetag | # param can be hp, mp, tp, level, mhp, mmp, atk, def, mat, mdf, agi or luk. | #------------------------------------------------------------------------------| #==============================================================================| # ** You only need to edit this part as it's about what this script does | #------------------------------------------------------------------------------| module DoubleX_RMVXA module Unison_Item #------------------------------------------------------------------------------| # * SHOW_UNISON_ACTOR, default = true | # The battlelog will show all actors involved in the unison skills or items | # instead of only the one invoking them if SHOW_UNISON_ACTOR is true. | #------------------------------------------------------------------------------| SHOW_UNISON_ACTOR = true #------------------------------------------------------------------------------| # * UNISON_PARAM_RULE, default = 2 | # Each parameter in the damage formula of the unison skills or items used | # will be altered by one of the rules below if there's no working notetag: | # 0 - No changes will take place | # 1 - Its minimum among all actors involved in the unison skills or items | # used will be used in their damage formulae | # 2 - Its average among all actors involved in the unison skills or items | # used will be used in their damage formulae | # 3 - Its maximum among all actors involved in the unison skills or items | # used will be used in their damage formulae | #------------------------------------------------------------------------------| UNISON_PARAM_RULE = 2 #==============================================================================| #==============================================================================| # ** You need not edit this part as it's about how this script works | #------------------------------------------------------------------------------| UNISON_PARAM_0 = /<(?:UNISON_PARAM_0|unison mhp):[ ](\d+(?:\s*,\s*\d+)*)>/i UNISON_PARAM_1 = /<(?:UNISON_PARAM_1|unison mmp):[ ](\d+(?:\s*,\s*\d+)*)>/i UNISON_PARAM_2 = /<(?:UNISON_PARAM_2|unison atk):[ ](\d+(?:\s*,\s*\d+)*)>/i UNISON_PARAM_3 = /<(?:UNISON_PARAM_3|unison def):[ ](\d+(?:\s*,\s*\d+)*)>/i UNISON_PARAM_4 = /<(?:UNISON_PARAM_4|unison mat):[ ](\d+(?:\s*,\s*\d+)*)>/i UNISON_PARAM_5 = /<(?:UNISON_PARAM_5|unison mdf):[ ](\d+(?:\s*,\s*\d+)*)>/i UNISON_PARAM_6 = /<(?:UNISON_PARAM_6|unison agi):[ ](\d+(?:\s*,\s*\d+)*)>/i UNISON_PARAM_7 = /<(?:UNISON_PARAM_7|unison luk):[ ](\d+(?:\s*,\s*\d+)*)>/i UNISON_PARAM_hp = /<(?:UNISON_PARAM_hp|unison hp):[ ](\d+(?:\s*,\s*\d+)*)>/i UNISON_PARAM_mp = /<(?:UNISON_PARAM_mp|unison mp):[ ](\d+(?:\s*,\s*\d+)*)>/i UNISON_PARAM_tp = /<(?:UNISON_PARAM_tp|unison tp):[ ](\d+(?:\s*,\s*\d+)*)>/i UNISON_PARAM_level = /<(?:UNISON_PARAM_level|unison level):[ ](\d+(?:\s*,\s*\d+)*)>/i end # Unison_Item end # DoubleX_RMVXA #------------------------------------------------------------------------------| # * Edit module: DataManager | #------------------------------------------------------------------------------| class << DataManager #----------------------------------------------------------------------------| # Alias method: load_database | #----------------------------------------------------------------------------| alias load_database_unison_item load_database def load_database load_database_unison_item # Added to load unison notetags load_notetags_unison_item # end # load_database #----------------------------------------------------------------------------| # New method: load_notetags_unison_item | #----------------------------------------------------------------------------| def load_notetags_unison_item [$data_skills, $data_items].each { |data| data.each { |obj| obj.load_notetags_unison_item if obj } } end # load_notetags_unison_item end # DataManager #------------------------------------------------------------------------------| # * Edit class: RPG::UsableItem | #------------------------------------------------------------------------------| class RPG::UsableItem < RPG::BaseItem #----------------------------------------------------------------------------| # New public instance variables | #----------------------------------------------------------------------------| attr_accessor :unison_item attr_accessor :unison_actor_id attr_accessor :unison_rule [0, 1, 2, 3, 4, 5, 6, 7, "hp", "mp", "tp", "level"].each { |param| eval("attr_accessor :unison_param_#{param = param.to_s}") eval("attr_accessor :unison_param_#{param}_id") } #----------------------------------------------------------------------------| # New method: load_notetags_unison_item | #----------------------------------------------------------------------------| def load_notetags_unison_item @unison_item = false @unison_actor_id = [] @unison_rule = (ui = DoubleX_RMVXA::Unison_Item)::UNISON_PARAM_RULE [0, 1, 2, 3, 4, 5, 6, 7, "hp", "mp", "tp", "level"].each { |param| eval("@unison_param_#{param = param.to_s} = false") eval("@unison_param_#{param}_id = []") } @note.split(/[\r\n]+/).each { |line| case line when /<(?:UNISON_ITEM|unison item):[ ](\d+(?:\s*,\s*\d+)*)>/i $1.scan(/\d+/).each { |n| @unison_actor_id << n.to_i if n.to_i > 0 } @unison_item ||= @unison_actor_id.size > 0 when /<(?:UNISON_RULE|unison rule):[ ]*(\d+)>/i @unison_rule = $1.to_i if @unison_item else [0, 1, 2, 3, 4, 5, 6, 7, "hp", "mp", "tp", "level"].each { |param| case line when eval("ui::UNISON_PARAM_#{param = param.to_s}") $1.scan(/\d+/).each { |num| eval("@unison_param_#{param}_id.push(num.to_i)") if num.to_i > 0 } eval("@unison_param_#{param} = true") if eval("@unison_param_#{param}_id.size > 0") end } end } end # load_notetags_unison_item end # RPG::UsableItem #------------------------------------------------------------------------------| # * Edit class: Game_BattlerBase | #------------------------------------------------------------------------------| class Game_BattlerBase #----------------------------------------------------------------------------| # Alias method: param | #----------------------------------------------------------------------------| alias param_unison_item param def param(param_id) # Rewritten to return unison param when it's set @unison_param_set ? @unison_param[param_id] : param_unison_item(param_id) # end # param #----------------------------------------------------------------------------| # Alias method: inputable? | #----------------------------------------------------------------------------| alias inputable_unison_item? inputable? def inputable? # Rewritten to check if at least 1 action slot isn't reserved return false unless inputable_unison_item? return true unless SceneManager.scene_is?(Scene_Battle) && actor? @unison_inputs < @actions.size # end # inputable? #----------------------------------------------------------------------------| # Alias method: usable? | #----------------------------------------------------------------------------| alias usable_unison_item? usable? def usable?(item) # Rewritten to check if all unison actors can use the unison skill/item unless actor? && item && item.is_a?(RPG::UsableItem) && item.unison_item return usable_unison_item?(item) end return false unless item.unison_actor_id.include?(id) return false unless usable_unison_item?(item) return unison_skill_usable?(item) if item.is_a?(RPG::Skill) return unison_item_usable?(item) if item.is_a?(RPG::Item) false # end # usable? #----------------------------------------------------------------------------| # New method: unison_skill_usable? | #----------------------------------------------------------------------------| def unison_skill_usable?(item) battle = SceneManager.scene_is?(Scene_Battle) (item.unison_actor_id - [id]).each { |actor_id| actor = $game_actors[actor_id] return false unless actor.battle_member? && actor.inputable? return false if battle && actor.actions.select { |a| a.item }.size >= actor.actions.size - actor.unison_inputs return false unless actor.skill_conditions_met?(item) return false unless actor.skills.any? { |s| s == $data_skills[item.id] } } true end # unison_skill_usable? #----------------------------------------------------------------------------| # New method: unison_item_usable? | #----------------------------------------------------------------------------| def unison_item_usable?(item) return false unless item_conditions_met?(item) (item.unison_actor_id - [id]).each { |actor_id| actor = $game_actors[actor_id] return false unless actor.battle_member? && actor.inputable? } true end # unison_item_usable? #----------------------------------------------------------------------------| # New method: unison_param_set | #----------------------------------------------------------------------------| def unison_param_set(item) @unison_param = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] [0, 1, 2, 3, 4, 5, 6, 7, "hp", "mp", "tp", "level"].each_with_index { |param_id, i| if item.send("unison_param_#{param_id.to_s}".to_sym) unison_param_actor = item.send("unison_param_#{param_id.to_s}_id".to_sym) else unison_param_actor = item.unison_actor_id end unison_param_rule(item, param_id, i, unison_param_actor) } @unison_level = @unison_param[11] @unison_param_set = true end # unison_param_set #----------------------------------------------------------------------------| # New method: unison_param_rule | #----------------------------------------------------------------------------| def unison_param_rule(item, param_id, i, unison_param_actor) case item.unison_rule when 1 if param_id.is_a?(Numeric) @unison_param[i] = param_max(param_id) elsif param_id == "hp" @unison_param[8] = param_max(0) elsif param_id == "mp" @unison_param[9] = param_max(1) elsif param_id == "tp" @unison_param[10] = max_tp else @unison_param[11] = max_level end unison_param_min_max(param_id, i, unison_param_actor, :min) when 2 unison_param_actor.each { |actor_id| if param_id.is_a?(Numeric) @unison_param[i] += $game_actors[actor_id].param(i) else @unison_param[i] += $game_actors[actor_id].send(param_id.to_s.to_sym) end } @unison_param[i] /= unison_param_actor.size when 3 unison_param_min_max(param_id, i, unison_param_actor, :max) else return unison_param_clear end end # unison_param_rule #----------------------------------------------------------------------------| # New method: unison_param_min_max | #----------------------------------------------------------------------------| def unison_param_min_max(param_id, i, unison_param_actor, sym) unison_param_actor.each { |actor_id| if param_id.is_a?(Numeric) @unison_param[i] = [@unison_param[i], $game_actors[actor_id].param(i)].send(sym) else @unison_param[i] = [@unison_param[i], $game_actors[actor_id].send(param_id.to_s.to_sym)].send(sym) end } end # unison_param_min_max #----------------------------------------------------------------------------| # New method: unison_param_clear | #----------------------------------------------------------------------------| def unison_param_clear @unison_level = nil @unison_param_set = false end # unison_param_clear #----------------------------------------------------------------------------| # (v1.01a+)New method: hp | #----------------------------------------------------------------------------| def hp @unison_param_set ? @unison_param[8] : @hp end # hp #----------------------------------------------------------------------------| # (v1.01a+)New method: mp | #----------------------------------------------------------------------------| def mp @unison_param_set ? @unison_param[9] : @mp end # mp #----------------------------------------------------------------------------| # (v1.01a+)New method: tp | #----------------------------------------------------------------------------| def tp @unison_param_set ? @unison_param[10] : @tp end # tp end # Game_BattlerBase #------------------------------------------------------------------------------| # * Edit class: Game_Battler | #------------------------------------------------------------------------------| class Game_Battler < Game_BattlerBase #----------------------------------------------------------------------------| # Alias method: make_damage_value | #----------------------------------------------------------------------------| alias make_damage_value_unison_item make_damage_value def make_damage_value(user, item) # Added to set the params of the user as the unison version unison = user.actor? && item.unison_item && item.unison_rule > 0 user.unison_param_set(item) if unison # make_damage_value_unison_item(user, item) # Added to reset the params of the user to the default user.unison_param_clear if unison # end # make_damage_value #----------------------------------------------------------------------------| # Alias method: use_item | #----------------------------------------------------------------------------| alias use_item_unison_item use_item def use_item(item) # Rewritten to pay unison skill cost unless item.is_a?(RPG::Skill) && item.unison_item return use_item_unison_item(item) end item.unison_actor_id.each { |a_id| $game_actors[a_id].pay_skill_cost(item) } item.effects.each { |effect| item_global_effect_apply(effect) } # end # use_item end # Game_Battler #------------------------------------------------------------------------------| # * Edit class: Game_Actor | #------------------------------------------------------------------------------| class Game_Actor < Game_Battler #----------------------------------------------------------------------------| # New public instance variables | #----------------------------------------------------------------------------| attr_accessor :unison_inputs attr_writer :unison_level #----------------------------------------------------------------------------| # (v1.01d+)Alias method: setup | #----------------------------------------------------------------------------| alias setup_unison_item setup def setup(actor_id) setup_unison_item(actor_id) # Added to initialize the number of reserved action slots @unison_inputs = 0 # end # setup #----------------------------------------------------------------------------| # (v1.00d+)Alias method: clear_actions | #----------------------------------------------------------------------------| alias clear_actions_unison_item clear_actions def clear_actions clear_actions_unison_item # Added to reset the number of reserved action slots @unison_inputs = 0 # end # clear_actions #----------------------------------------------------------------------------| # (v1.01d+)Alias method: next_command | #----------------------------------------------------------------------------| alias next_command_unison_item next_command def next_command # Added to return false if the next slot is reserved for unison skill/items return false if @action_input_index >= @actions.size - 1 - @unison_inputs # next_command_unison_item end # next_command #----------------------------------------------------------------------------| # (v1.01a+)New method: level | #----------------------------------------------------------------------------| def level @unison_level || @level end # level end # Game_Actor #------------------------------------------------------------------------------| # * Edit class: Window_ItemList | #------------------------------------------------------------------------------| class Window_ItemList < Window_Selectable #----------------------------------------------------------------------------| # (v1.00c+)Alias method: enable? | #----------------------------------------------------------------------------| alias enable_unison_item? enable? def enable?(item) # Rewritten to set disable unison items when unison conditions aren't met return enable_unison_item?(item) unless item.is_a?(RPG::Item) && item.unison_item && SceneManager.scene_is?(Scene_Battle) BattleManager.actor.usable?(item) # end # enable? end # Window_ItemList #------------------------------------------------------------------------------| # * Edit class: Window_BattleLog | #------------------------------------------------------------------------------| class Window_BattleLog < Window_Selectable #----------------------------------------------------------------------------| # Alias method: display_use_item | #----------------------------------------------------------------------------| alias display_use_item_unison_item display_use_item def display_use_item(subject, item) # Rewritten to display unison actors while using unison skills or items unless DoubleX_RMVXA::Unison_Item::SHOW_UNISON_ACTOR && item.unison_item return display_use_item_unison_item(subject, item) end display_unison_item(item) # end # display_use_item #----------------------------------------------------------------------------| # New method: display_unison_item | #----------------------------------------------------------------------------| def display_unison_item(item) unless item.is_a?(RPG::Skill) return add_text(sprintf(Vocab::UseItem, unison_actor_names(item), item.name)) end add_text(unison_actor_names(item) + item.message1) return if item.message2.empty? wait add_text(item.message2) end # display_unison_item #----------------------------------------------------------------------------| # New method: unison_actor_names | #----------------------------------------------------------------------------| def unison_actor_names(item) names = "" size = item.unison_actor_id.size item.unison_actor_id.each_with_index { |actor_id, index| if index > 0 && index < size - 1 names += ", " elsif size > 1 && index == size - 1 names += " and " end names += $game_actors[actor_id].name } names end # unison_actor_names end # Window_BattleLog #------------------------------------------------------------------------------| # * Edit class: Scene_Battle | #------------------------------------------------------------------------------| class Scene_Battle < Scene_Base #----------------------------------------------------------------------------| # (v1.01d+)Alias method: start | #----------------------------------------------------------------------------| alias start_unison_item start def start start_unison_item # Added to initialize the unison action linkage hash @unison_actor_ids = {} # end # start #----------------------------------------------------------------------------| # Alias method: next_command | #----------------------------------------------------------------------------| alias next_command_unison_item next_command def next_command # Added to set the link of the unison action slot to the unison invokees add_unison_actor_ids if (actor = BattleManager.actor) && actor.input && actor.input.item && actor.input.item.unison_item # next_command_unison_item end # next_command #----------------------------------------------------------------------------| # Alias method: prior_command | #----------------------------------------------------------------------------| alias prior_command_unison_item prior_command def prior_command # Added to clear the currently selected action before selecting the prior BattleManager.actor.input.clear if BattleManager.actor.input # prior_command_unison_item # Added to clear the unison action linkage and unconfirm the action clear_unison_actor_ids if BattleManager.actor # end # prior_command #----------------------------------------------------------------------------| # Alias method: turn_start | #----------------------------------------------------------------------------| alias turn_start_unison_item turn_start def turn_start # Added to reset the links of the unison action slots to the unison invokees @unison_actor_ids = {} $game_party.alive_members.each { |mem| mem.unison_inputs = -1 } # turn_start_unison_item end # turn_start #----------------------------------------------------------------------------| # New method: add_unison_actor_ids | #----------------------------------------------------------------------------| def add_unison_actor_ids ids = (actor = BattleManager.actor).input.item.unison_actor_id - [actor.id] @unison_actor_ids[[actor.index, actor.action_input_index]] = ids ids.each { |id| $game_actors[id].unison_inputs += 1 } end # add_unison_actor_ids #----------------------------------------------------------------------------| # New method: clear_unison_actor_ids | #----------------------------------------------------------------------------| def clear_unison_actor_ids a = BattleManager.actor return unless ids = @unison_actor_ids[[a.index, a.action_input_index]] @unison_actor_ids.delete([a.index, a.action_input_index]) ids.each { |id| $game_actors[id].unison_inputs -= 1 } end # clear_unison_actor_ids end # Scene_Battle #==============================================================================|