#==============================================================================| # ** DoubleX RMVXA Counterattack Edit v1.05b | #------------------------------------------------------------------------------| # * Changelog | # v1.05b(GMT 1500 14-7-2015): | # - Fixed class notetags not working bug | # - In sync with the latest DoubleX RMVXA Substitute Edit version | # - Improved this script's readibility | # v1.05a(GMT 0200 5-7-2014): | # - Allows users to keep counterattack skill's animations, scopes and times | # - Compatible with DoubleX RMVXA Substitute Edit | # v1.04a(GMT 2300 1-4-2014): | # - Allows users to set actor's counterattack skill needs to be learnt | # v1.03a(GMT 0900 18-3-2014): | # - Allows users to set whether counterattack negates hits | # v1.02a(GMT 0000 14-2-2014): | # - Allows users to set whether counterattack messages will be shown | # v1.01b(GMT 0900 16-1-2014): | # - Fixed a & b bug in damage formula of counterattack skills | # v1.01a(GMT 1000 15-1-2014): | # - Allows users to set whether magic evasion invokes counterattack | # v1.00a(GMT 0400 5-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 alter the skills used in counterattack | #------------------------------------------------------------------------------| # * 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 Vocab CounterAttack or aliasing or rewriting method: | # - item_cnt or item_apply under class Game_Battler | # - display_counter under class Window_BattleLog | # - apply_item_effects and invoke_counter_attack under class Scene_Battle | # may have compatibility issues with this script | # Place this script above those aliasing any of these method if possible | #==============================================================================| ($imported ||= {})["DoubleX RMVXA Counterattack Edit"] = true #------------------------------------------------------------------------------| # * (v1.01a+)Notetag <mev invoke cnt> for actors, classes, equips, enemies and| # states: | # To set a battler having chance based on his/her/its CNT to invoke | # counterattack upon successful magic evasion, put the above notetag into | # the related actor's, class's, equip's, enemy's or state's notebox in the | # database. | #------------------------------------------------------------------------------| # * Notetag <counterattack skill: x> for actors(1), classes(2), equips(3), | # enemies(1) and states(4):(the larger the number, the higher the priority) | # To alter a battler's counterattack skill's id to x, put the above notetag | # into the related actor's, class's, equip's, enemy's or state's notebox in | # the database. | #------------------------------------------------------------------------------| #==============================================================================| # ** You only need to edit this part as it's about what this script does | #------------------------------------------------------------------------------| module DoubleX_RMVXA module Counterattack_Edit #------------------------------------------------------------------------------| # * (v1.05a+)Keep_Ani, default = false | # If Keep_Ani is true, the counterattack skill's animations will be played | # when the counterattack's invoked | #------------------------------------------------------------------------------| Keep_Ani = false #------------------------------------------------------------------------------| # * (v1.05a+)Keep_Scope, default = false | # If Keep_Scope is true, the counterattack skill's scope will stay intact, | # otherwise it'll only target the one attacked that battler | #------------------------------------------------------------------------------| Keep_Scope = false #------------------------------------------------------------------------------| # * (v1.05a+)Keep_Times, default = false | # If Keep_Scope is true, the counterattack skill's repeats will stay intact,| # otherwise it'll be 1 | #------------------------------------------------------------------------------| Keep_Times = false #------------------------------------------------------------------------------| # * (v1.04a+)Actor_Learn_Counterattack_Skill, default = false | # If Actor_Learn_Counterattack_Skill is true and an actor hasn't learnt the | # counterattack skill, Default_Counterattack will be that actor's skill | #------------------------------------------------------------------------------| Actor_Learn_Counterattack_Skill = false #------------------------------------------------------------------------------| # * (v1.03a+)CNT_Negate_Hit, default = true | # Normal physical hit and damage determinations will take place before that | # of CNT if CNT_Negate_Hit is false | #------------------------------------------------------------------------------| CNT_Negate_Hit = true #------------------------------------------------------------------------------| # * (v1.02a+)COUNTERATTACK_MESSAGE, default = true | # Counterattack messages won't be shown if COUNTERATTACK_MESSAGE is false | #------------------------------------------------------------------------------| COUNTERATTACK_MESSAGE = true #------------------------------------------------------------------------------| # * (v1.01a+)MEV_Invoke_CNT, default = false | # Successful magic evasion invokes counterattack with chance based on CNT if| # MEV_Invoke_CNT is true, even when <mev invoke cnt> notetags are absent | #------------------------------------------------------------------------------| MEV_Invoke_CNT = false #------------------------------------------------------------------------------| # * Default_Counterattack, default = 1 | # The counterattack skill of a battler will be the one's id equal to | # Default_Counterattack if he/she/it doesn't have any notetag | #------------------------------------------------------------------------------| Default_Counterattack = 1 end # Counterattack_Edit end # DoubleX_RMVXA #==============================================================================| #==============================================================================| # ** You need not edit this part as it's about how this script works | #------------------------------------------------------------------------------| module Vocab CounterAttack = "%s countered with %s!" end # Vocab #------------------------------------------------------------------------------| # * Edit module: DataManager | #------------------------------------------------------------------------------| class << DataManager #----------------------------------------------------------------------------| # Alias method: load_database | #----------------------------------------------------------------------------| alias load_database_counterattack_edit load_database def load_database load_database_counterattack_edit # Added to load notetags load_notetags_counterattack_edit # end # load_database #----------------------------------------------------------------------------| # New method: load_notetags_counterattack_edit | #----------------------------------------------------------------------------| def load_notetags_counterattack_edit [$data_actors, $data_classes, $data_enemies, $data_weapons, $data_armors, $data_states].each { |data| data.each { |obj| obj.load_notetags_counterattack_edit if obj } } end # load_notetags_counterattack_edit end # DataManager #------------------------------------------------------------------------------| # * Edit class: RPG::BaseItem | #------------------------------------------------------------------------------| class RPG::BaseItem #----------------------------------------------------------------------------| # New public instance variables | #----------------------------------------------------------------------------| attr_accessor :counterattack_skill attr_accessor :mev_invoke_cnt #----------------------------------------------------------------------------| # New method: load_notetags_counterattack_edit | #----------------------------------------------------------------------------| def load_notetags_counterattack_edit @counterattack_skill = DoubleX_RMVXA::Counterattack_Edit::Default_Counterattack @mev_invoke_cnt = DoubleX_RMVXA::Counterattack_Edit::MEV_Invoke_CNT @note.split(/[\r\n]+/).each { |line| case line when /<(?:COUNTERATTACK_SKILL|counterattack skill):[ ]*(\d+)>/i @counterattack_skill = $1.to_i when /<(?:MEV_INVOKE_CNT|mev invoke cnt)>/i @mev_invoke_cnt = true end } end # load_notetags_counterattack_edit end # RPG::BaseItem #------------------------------------------------------------------------------| # * Edit class: Game_Battler | #------------------------------------------------------------------------------| class Game_Battler < Game_BattlerBase #----------------------------------------------------------------------------| # New public instance variable | #----------------------------------------------------------------------------| attr_reader :invoke_counter_attack #----------------------------------------------------------------------------| # (v1.03a+)Alias method: item_cnt | #----------------------------------------------------------------------------| alias item_cnt_counterattack_edit item_cnt def item_cnt(user, item) # Rewritten to negate hit upon CNT if CNT_Negate_Hit is true return 0 unless DoubleX_RMVXA::Counterattack_Edit::CNT_Negate_Hit item_cnt_counterattack_edit(user, item) # end #----------------------------------------------------------------------------| # (v1.01a+)Alias method: item_apply | #----------------------------------------------------------------------------| alias item_apply_counterattack_edit item_apply def item_apply(user, item) item_apply_counterattack_edit(user, item) # Added to invoke cnt upon mev if MEV_Invoke_CNT is true @invoke_counter_attack = @result.evaded && item.magical? && rand < cnt # end # item_apply #----------------------------------------------------------------------------| # (v1.01a+)New method: mev_invoke_cnt? | #----------------------------------------------------------------------------| def mev_invoke_cnt? states.each { |state| return true if state.mev_invoke_cnt } if actor? if equips equips.each { |equip| return true if equip && equip.mev_invoke_cnt } end return self.class.mev_invoke_cnt || actor.mev_invoke_cnt end enemy? && enemy.mev_invoke_cnt end # mev_invoke_cnt? #----------------------------------------------------------------------------| # New method: counterattack_skill_id | #----------------------------------------------------------------------------| def counterattack_skill_id cnte = DoubleX_RMVXA::Counterattack_Edit skill_cnt = cnte::Default_Counterattack states.each { |state| next unless actor? && (!cnte::Actor_Learn_Counterattack_Skill || skill_learn?($data_skills[state.counterattack_skill])) || enemy? skill_cnt = state.counterattack_skill } return skill_cnt if skill_cnt != cnte::Default_Counterattack return enemy.counterattack_skill if enemy? if actor? if equips equips.each { |equip| next unless equip && (!cnte::Actor_Learn_Counterattack_Skill || skill_learn?($data_skills[equip.counterattack_skill])) skill_cnt = equip.counterattack_skill } end return skill_cnt if skill_cnt != cnte::Default_Counterattack if (!cnte::Actor_Learn_Counterattack_Skill || skill_learn?($data_skills[self.class.counterattack_skill])) && self.class.counterattack_skill != skill_cnt return self.class.counterattack_skill end if !cnte::Actor_Learn_Counterattack_Skill || skill_learn?($data_skills[actor.counterattack_skill]) return actor.counterattack_skill end end skill_cnt end # counterattack_skill_id end # Game_Battler #------------------------------------------------------------------------------| # * Edit class: Window_BattleLog | #------------------------------------------------------------------------------| class Window_BattleLog < Window_Selectable #----------------------------------------------------------------------------| # Rewrite method: display_counter | #----------------------------------------------------------------------------| def display_counter(target, item) Sound.play_evasion # Rewritten to alter the vocab of counterattack if DoubleX_RMVXA::Counterattack_Edit::COUNTERATTACK_MESSAGE add_text(sprintf(Vocab::CounterAttack, target.name, $data_skills[target.counterattack_skill_id].name)) end # wait back_one end # display_counter end # Window_BattleLog #------------------------------------------------------------------------------| # * Edit class: Scene_Battle | #------------------------------------------------------------------------------| class Scene_Battle < Scene_Base #----------------------------------------------------------------------------| # Rewrite method: invoke_counter_attack | #----------------------------------------------------------------------------| def invoke_counter_attack(target, item) @log_window.display_counter(target, item) # Rewritten to alter the counterattack skill cnte = DoubleX_RMVXA::Counterattack_Edit @cnt_subject = target if cnte::Keep_Ani attack_skill = $data_skills[target.counterattack_skill_id] if attack_skill.for_opponent? if cnte::Keep_Scope scope = targets_for_opponents_counterattack_edit(target, attack_skill) else scope = [@subject] end apply_counterattack_edit(target, attack_skill, scope, $imported["DoubleX RMVXA Substitute Edit"]) elsif attack_skill.for_friend? if cnte::Keep_Scope scope = targets_for_friends_counterattack_edit(target, attack_skill) else scope = [target] end apply_counterattack_edit(target, attack_skill, scope) end @cnt_subject &&= !cnte::Keep_Ani # refresh_status end # invoke_counter_attack #----------------------------------------------------------------------------| # (v1.05a+)Alias method: show_attack_animation | #----------------------------------------------------------------------------| alias show_attack_animation_counterattack_edit show_attack_animation def show_attack_animation(targets) # Rewritten to handle the Keep_Ani case if @cnt_subject && @cnt_subject.actor? show_normal_animation(targets, @cnt_subject.atk_animation_id1, false) show_normal_animation(targets, @cnt_subject.atk_animation_id2, true) else show_attack_animation_counterattack_edit(targets) end # end # show_attack_animation #----------------------------------------------------------------------------| # (v1.01a+)Alias method: apply_item_effects | #----------------------------------------------------------------------------| alias apply_item_effects_counterattack_edit apply_item_effects def apply_item_effects(target, item) apply_item_effects_counterattack_edit(target, item) # Added to invoke cnt upon mev or !CNT_Negate_Hit with chance cnt return unless target.mev_invoke_cnt? && target.invoke_counter_attack || !DoubleX_RMVXA::Counterattack_Edit::CNT_Negate_Hit && rand < target.item_cnt_counterattack_edit(@subject, item) invoke_counter_attack(target, item) # end # apply_item_effects #----------------------------------------------------------------------------| # (v1.05b+)New method: apply_counterattack_edit | #----------------------------------------------------------------------------| def apply_counterattack_edit(target, attack_skill, scope, substitute = false) cnte = DoubleX_RMVXA::Counterattack_Edit se = DoubleX_RMVXA::Substitute_Edit if substitute show_animation(scope, attack_skill.animation_id) if cnte::Keep_Ani repeats = cnte::Keep_Times ? attack_skill.repeats : 1 scope.each { |s| repeats.times { unless substitute s.item_apply(target, attack_skill) next @log_window.display_action_results(s, attack_skill) end if se::Hit_Substitute s.item_apply(target, attack_skill) next @log_window.display_action_results(s, attack_skill) end sub = apply_substitute(s, attack_skill) sub.item_apply(target, attack_skill) @log_window.display_action_results(s, attack_skill) if sub == s } } end # apply_counterattack_edit #----------------------------------------------------------------------------| # New method: targets_for_opponents_counterattack_edit | #----------------------------------------------------------------------------| def targets_for_opponents_counterattack_edit(target, item) if item.for_random? Array.new(item.number_of_targets) { target.opponents_unit.random_target } elsif item.for_one? num = 1 if item == $data_skills[target.attack_skill_id] num += target.atk_times_add.to_i end return [@subject] * num end target.opponents_unit.alive_members end # targets_for_opponents_counterattack_edit #----------------------------------------------------------------------------| # New method: targets_for_friends_counterattack_edit | #----------------------------------------------------------------------------| def targets_for_friends_counterattack_edit(target, item) return [target] if item.for_user? if item.for_dead_friend? return [target.friends_unit.random_dead_target] if item.for_one? target.friends_unit.dead_members elsif item.for_friend? return [target.friends_unit.random_target] if item.for_one? target.friends_unit.alive_members end end # targets_for_friends_counterattack_edit end # Scene_Battle #==============================================================================|