Counterattack Script, Read the title |
|
|
|
|
Mar 26 2010, 03:55 PM
|
Level 2

Group: Member
Posts: 19
Type: None
RM Skill: Undisclosed

|
COTUS COUNTER Version: 1.2Author: ThorondorRelease date: March 26th 2010Updated: May 26th 2010IntroductionThis script lets you set states to allow counterattacks, and set a variety of factors pertaining to the counterattack, such as strength, what sets it off, and the elements of the attack. Now also allows you to give the counterattack a chance to activate, instead of activating every time the conditions are met. Skills can be activated by a counterattack, instead of doing a normal counterattack. Features- Counterattacks can interrupt the action that triggered them
- Variable counterattack strength, based off of attack, spirit, agility, or defense
- A selection of possible requirements for actions to trigger the counterattack
- Set the animation, elements, accuracy and critical rate of the counterattack if desired
- NEW! Give the counterattack a chance to activate upon its conditions being met
- NEWER! Activate a skill instead of making a normal counterattack
Script<div style="margin:20px; margin-top:5px"><div style="margin-bottom:2px"> [Show/Hide] Script</div><div style="margin: 0px; padding: 6px; border: 1px inset;"><div style="display: none;"> CODE =begin
=begin
COTUS - Counterattack Version 1.3 by Thorondor
=============================================================================== Updates: 5-24-2010: Added the 'chance' attribute, allowing counterattacks to activate only a certain percentage of the time instead of all the time. 5-26-2010: Now allows counterattacks to activate skills. 1-17-2012: Minor fixes on counterattack skills, which now are completely functional except with YEM and possibly the Yanfly Engine Redux battle system as well. Changes to function of couterattacks that use skills but not the <targetnorm> tag. ===============================================================================
Installation: put it under materials, and above main. You may have to move it around some due to other scripts.
Counterattacks are set by putting a series of notes in a state's notebox. That state will then allow whichever battlers it is on to counterattack. A normal counterattack is denoted by <counter>, an interrupting counterattack is denoted <interrupt>. By default, counterattacks are only activated when the battler making the counterattack is targetted; this can be changed by the use of <guardian>, causing the battler to counterattack if any allies are targetted as well. The damage dealt by the counterattack is determined by the use of four tags: <atk_f x>, <spi_f x>, <def_f x>, and <agi_f x>, where x is the percentage of base damage used. Attack and spirit based damage are done the same way as for skills, and defense and agility are treated the same way as spirit. There are a variety of tags for what actions can set off the counterattack. <vs_attacks> counters attacks, <vs_skills> counters skills, <vs_items> counters items, <vs_physical> counters attacks and skills or items with the physical attack tag, <vs_phys_skills> counters physical attack skills, <vs_phys_items> counters physical attack items, <vs_spells> counters skills with any spi_f, <vs_spell_items> is the same as <vs_spells>, but for items, <vs_other_skill> counters any skill that is neither physical nor a spell, and <vs_other_item> counters any item that is neither physical nor a spell. Any or all of these can be used for one state. <counterspell> gives the counterattack different text upon activation, and treats the counterattack more like a skill than an attack, ignoring any states normally applied by an attack and ignoring evasion unless specified otherwise by the use of <evasion>. <animation x> sets the counterattack's animation; if x is 0 or the tag isn't used, the animation will be the same as a normal attack's. <element x> or <element x,x>, with as many x's as wanted, sets the counterattacks elements. If x is zero, or the tag isn't used, no elements will be used; if it is -1, a normal attack's elements will be used. <accuracy x> gives the counterattack an accuracy seperate from a normal attack's; 0 or non-use means normal attack accuracy. <critical x> determines critical rate; it not entered, the battler's critical rate will be used. <chance x> determines the counterattack's chance of activating when conditions are met. The number entered is the percent chance of activating. If not entered, it is 100. <cskill x> sets the counterattack to activate a skill, x being the id of the skill. The skill will be activated whether or not the battler can use it normally. This tag overrides other tags that determine the strength of a counterattack. <costskill> causes the skill to cost its normal amount of MPs. <targetnorm> is intended to allow this script to work with custom targetting, but is not currently functional. Without it, the skill uses the targetting set in the database. Currently, however, it seems to cause one specific battler to always be targetted. Without it, a skill that targets enemies will always target the battler that triggered it, even if normally it would target a random foe. Any additional random foes are selected as normal. Skills that target all foes function as normal. If the skill targets an ally, it will target the counterattacking battler. Skills that target all allies still do so.
A couple of example counterattack setups:
<interrupt> <guardian> <spi_f 100> <vs_spells> <vs_spell_items> <counterspell> <animation 15> <element 6> <accuracy 100> <critical 0> This counterattack is of the counterspell variety, and is an interrupting counterattack. It activates off of spells and spell items targetting any ally. Damage dealt is full spirit damage (look in the RPGmaker's help file if you don't know the formula). The animation ID is 15, the attack uses element 6, it never misses, and never gets a critical.
<counter> <atk_f 100> <vs_physical> <element -1> This counterattack activates when attacks or physical items or skills are used on whatever battler has this state. The damage dealt is the same as if a normal attack. The counterattack uses the battler's attack elements.
================================================================================ Compatibility notes: Alias: Scene_Battle; execute_action_attack, and skill and item versions of same Overwrites: Game_BattleAction; make_targets ================================================================================ Credit: If you use this, please credit me; COTUS works, Thorondor probably does, although I don't know if anyone else is using that name, a possibility which could cause some confusion...
Also, I'd like to thank the many other people who have made scripts, as I learned a lot of how to do it from other people's scripts. ================================================================================ =end
$imported = {} if $imported == nil $imported["COTUS Counter"] = true
module COTUS module REGEXP module STATE # This is the text looked for in the notebox. If you don't know what you # are doing, leave it be. :) # These adjust the type of counterattack COUNTER = /<(?:COUNTER|counter)>/i INTERRUPT = /<(?:INTERRUPT|interrupt)>/i GUARDIAN = /<(?:GUARDIAN|guardian)>/i VS_ATTACKS = /<(?:VS_ATTACKS|vs_attacks)>/i VS_SKILLS = /<(?:VS_SKILLS|vs_skills)>/i VS_ITEMS = /<(?:VS_ITEMS|vs_items)>/i VS_PHYSICAL = /<(?:VS_PHYSICAL|vs_physical)>/i VS_PHYS_SKILLS = /<(?:VS_PHYS_SKILLS|vs_phys_skills)>/i VS_PHYS_ITEMS = /<(?:VS_PHYS_ITEMS|vs_phys_items)>/i VS_SPELLS = /<(?:VS_SPELLS|vs_spells)>/i VS_SPELL_ITEMS = /<(?:VS_SPELL_ITEMS|vs_spell_items)>/i VS_OTHER_SKILL = /<(?:VS_OTHER_SKILL|vs_other_skill)>/i VS_OTHER_ITEM = /<(?:VS_OTHER_ITEM|vs_other_item)>/i COUNTERSPELL = /<(?:COUNTERSPELL|counterspell)>/i # These adjust numbered attributes ATK_F = /<(?:ATF_F|atk_f)[ ]*(\d+)>/i SPI_F = /<(?:SPI_F|spi_f)[ ]*(\d+)>/i AGI_F = /<(?:AGI_F|agi_f)[ ]*(\d+)>/i DEF_F = /<(?:DEF_F|def_f)[ ]*(\d+)>/i ANIMATION = /<(?:ANIMATION|animation)[ ]*(\d+)>/i ACCURACY = /<(?:ACCURACY|accuracy)[ ]*(\d+)>/i CRITICAL = /<(?:CRITICAL|critical)[ ]*(\d+)>/i ELEMENT = /<(?:ELEMENT|element)[ ]*(\d+(?:\s*,\s*\d+)*)>/i CHANCE = /<(?:CHANCE|chance)[ ]*(\d+)>/i CSKILL = /<(?:CSKILL|cskill)[ ]*(\d+)>/i # These are different EVASION = /<(?:EVASION|evasion)>/i COSTSKILL = /<(?:COSTSKILL|costskill)>/i TARGETNORM = /<(?:TARGETNORM|targetnorm)>/i end # STATE end # REGEXP module VOCAB # HERE IS THE TEXT FOR A COUNTERATTACK: change as desired # Standard counterattack text, where %s = counterattacker COUNTERTEXT = "%s counterattacks!" # Standard interrupt text INTERRUPTTEXT = "%s interrupts!" # Counterspell text CSPELLTEXT = "%s's counterspell!" # Counterspell interrupt text CSPELLINTERRUPT = "%s interrupts with a counterspel1" end # VOCAB end # COTUS
#=============================================================================== # RPG::State # This is the stuff for defining the new attributes of states. #===============================================================================
class RPG::State #-------------------------------------------------------------------------- # COTUS_Cache_CCA #-------------------------------------------------------------------------- def cotus_cache_cca # Creating new state factors @counter = false; @interrupt = false; @guardian = false; @vs_attacks = false; @vs_skills = false; @vs_items = false; @vs_physical = false; @vs_phys_skills = false; @vs_phys_items = false; @vs_spells = false; @vs_spell_items = false; @vs_other_skill = false; @vs_other_item = false; @counterspell = false; @atk_fc = 0; @spi_fc = 0; @agi_fc = 0; @def_fc = 0; @animation = 0; @accuracy = -1; @critical = -1; @evasion = false; @element = []; @chance = 100; @cskill = 0; @costskill = false; @targetnorm = false self.note.split(/[\r\n]+/).each { |line| # Finding text in the noteboxes case line when COTUS::REGEXP::STATE::ELEMENT $1.scan(/\d+/).each { |num| if num.to_i >= 0 @element.push(num.to_i) end } when COTUS::REGEXP::STATE::COUNTER @counter = true when COTUS::REGEXP::STATE::INTERRUPT @interrupt = true when COTUS::REGEXP::STATE::GUARDIAN @guardian = true when COTUS::REGEXP::STATE::VS_ATTACKS @vs_attacks = true when COTUS::REGEXP::STATE::VS_SKILLS @vs_skills = true when COTUS::REGEXP::STATE::VS_ITEMS @vs_items = true when COTUS::REGEXP::STATE::VS_PHYSICAL @vs_physical = true when COTUS::REGEXP::STATE::VS_PHYS_SKILLS @vs_phys_skills = true when COTUS::REGEXP::STATE::VS_PHYS_ITEMS @vs_phys_items = true when COTUS::REGEXP::STATE::VS_SPELLS @vs_spells = true when COTUS::REGEXP::STATE::VS_SPELL_ITEMS @vs_spell_items = true when COTUS::REGEXP::STATE::VS_OTHER_SKILL @vs_other_skill = true when COTUS::REGEXP::STATE::VS_OTHER_ITEM @vs_other_item = true when COTUS::REGEXP::STATE::COUNTERSPELL @counterspell = true when COTUS::REGEXP::STATE::ATK_F @atk_fc = $1.to_i when COTUS::REGEXP::STATE::SPI_F @spi_fc = $1.to_i when COTUS::REGEXP::STATE::AGI_F @agi_fc = $1.to_i when COTUS::REGEXP::STATE::DEF_F @def_fc = $1.to_i when COTUS::REGEXP::STATE::ANIMATION @animation = $1.to_i when COTUS::REGEXP::STATE::ACCURACY @accuracy = $1.to_i when COTUS::REGEXP::STATE::CRITICAL @critical = $1.to_i when COTUS::REGEXP::STATE::CHANCE @chance = $1.to_i when COTUS::REGEXP::STATE::CSKILL @cskill = $1.to_i when COTUS::REGEXP::STATE::EVASION @evasion = true when COTUS::REGEXP::STATE::COSTSKILL @costskill = true when COTUS::REGEXP::STATE::TARGETNORM @targetnorm = true end } @element = [0] if @element == [] end # cotus_cache_cca #-------------------------------------------------------------------------- # Counter Types #-------------------------------------------------------------------------- def counter cotus_cache_cca if @counter == nil return @counter end def interrupt cotus_cache_cca if @interrupt == nil return @interrupt end def guardian cotus_cache_cca if @guardian == nil return @guardian end #-------------------------------------------------------------------------- # Counter Times #-------------------------------------------------------------------------- def vs_attacks cotus_cache_cca if @vs_attacks == nil return @vs_attacks end def vs_skills cotus_cache_cca if @vs_skills == nil return @vs_skills end def vs_items cotus_cache_cca if @vs_items == nil return @vs_items end def vs_physical cotus_cache_cca if @vs_physical == nil return @vs_physical end def vs_phys_skills cotus_cache_cca if @vs_phys_skills == nil return @vs_phys_skills end def vs_phys_items cotus_cache_cca if @vs_phys_items == nil return @vs_phys_items end def vs_spells cotus_cache_cca if @vs_spells == nil return @vs_spells end def vs_spell_item cotus_cache_cca if @vs_spell_item == nil return @vs_spell_item end def vs_other_skill cotus_cache_cca if @vs_other_skill == nil return @vs_other_skill end def vs_other_item cotus_cache_cca if @vs_other_item == nil return @vs_other_item end def counterspell cotus_cache_cca if @counterspell == nil return @counterspell end #-------------------------------------------------------------------------- # Counter Strength #-------------------------------------------------------------------------- def atk_fc cotus_cache_cca if @atf_fc == nil return @atk_fc end def spi_fc cotus_cache_cca if @spi_fc == nil return @spi_fc end def agi_fc cotus_cache_cca if @agi_fc == nil return @agi_fc end def def_fc cotus_cache_cca if @def_fc == nil return @def_fc end #-------------------------------------------------------------------------- # Additional Effects #-------------------------------------------------------------------------- def animation cotus_cache_cca if @animation == nil return @animation end def accuracy cotus_cache_cca if @accuracy == nil return @accuracy end def critical cotus_cache_cca if @critical == nil return @critical end def chance cotus_cache_cca if @chance == nil return @chance end def cskill cotus_cache_cca if @cskill == nil return @cskill end def evasion cotus_cache_cca if @evasion == nil return @evasion end def costskill cotus_cache_cca if @costskill == nil return @costskill end def targetnorm cotus_cache_cca if @targetnorm == nil return @targetnorm end def element cotus_cache_cca if @element == nil return @element end end # RPG::State
#=============================================================================== # Game_Temp # I needed to put these variables somewhere they could be accessed... #===============================================================================
class Game_Temp #-------------------------------------------------------------------------- # Public Instance Variables #-------------------------------------------------------------------------- attr_accessor :newtargets # Store targets for later use attr_accessor :interrupt_state # Store the interrupting state attr_accessor :interrupter # Store the interrupting battler end # Game_Temp
#=============================================================================== # Game_BattleAction #===============================================================================
class Game_BattleAction #-------------------------------------------------------------------------- # * Overwrite Create Target Array #-------------------------------------------------------------------------- def make_targets $game_temp.interrupter = nil $game_temp.interrupt_state = nil @newtargets = [] if attack? targets = make_attack_targets # Set targets if foe_target_cca?(targets) # If used on foes check_interrupt(battler, targets) # Check for an interrupt end elsif skill? targets = make_obj_targets(skill) # Set targets if foe_target_cca?(targets) # If used on foes check_interrupt(battler, targets) # Check for an interrupt end elsif item? targets = make_obj_targets(item) # Set targets if foe_target_cca?(targets) # If used on foes check_interrupt(battler, targets) # Check for an interrupt end end $game_temp.newtargets = targets # Store targets if $game_temp.interrupt_state != nil # If there is an interrupt for target in targets # For each target targets.delete(target) # Delete target end end return targets end #-------------------------------------------------------------------------- # foe_target_cca? #-------------------------------------------------------------------------- def foe_target_cca?(targets) for target in targets # For each target if opponents_unit.members.include?(target) # If target is an enemy return true end end return false end #-------------------------------------------------------------------------- # Make Counter? #-------------------------------------------------------------------------- def make_counter?(state) if rand(100) >= state.chance # If activation fails return false # Counterattack cannot be made end if self.kind == 0 and self.basic == 0 # If action is an attack return true if state.vs_attacks or state.vs_physical elsif self.skill.is_a?(RPG::Skill) # If action is a skill if self.skill.physical_attack # If skill is a physical attack return true if state.vs_skills or state.vs_physical or state.vs_phys_skills elsif self.skill.spi_f > 0 # If skill is a spell return true if state.vs_skills or state.vs_spells else # If none of the above return true if state.vs_skills or state.vs_other_skill end elsif self.item.is_a?(RPG::Item) # If action is an item if self.item.physical_attack # If item is a physical attak return true if state.vs_items or state.vs_physical or state.vs_phys_items elsif self.item.spi_f > 0 # If item is a spell return true if state.vs_skills or state.vs_spell_items else # If none of the above return true if state.vs_items or state.vs_other_item end end return false end #-------------------------------------------------------------------------- # Check Interrupt #-------------------------------------------------------------------------- def check_interrupt(battler, targets) for member in battler.action.opponents_unit.existing_members for state in member.states if state.guardian # If guardian flag is active if state.interrupt # If interrupt flag is active if battler.action.make_counter?(state) # If interrupt is valid return unless member.movable? # Return if immobile $game_temp.interrupter = member # Set interrupter $game_temp.interrupt_state = state # Set interrupting state return end end end end end for target in targets return if battler.action.friends_unit.members.include?(target) # Ignore friends for state in target.states if state.interrupt # If counter flag is active if not state.guardian # Ensure there are no repeats if battler.action.make_counter?(state) # If interrupt is valid return unless target.movable? # Return if immobile $game_temp.interrupter = target # Set interrupter $game_temp.interrupt_state = state # Set interrupting state return end end end end end end #-------------------------------------------------------------------------- # Make Counter Skill Targets #-------------------------------------------------------------------------- def make_cskill_targets(cskill, battler, trigger) targets = [] if cskill.for_opponent? if cskill.for_random? if cskill.for_one? # One random enemy number_of_targets = 0 elsif cskill.for_two? # Two random enemies number_of_targets = 1 else # Three random enemies number_of_targets = 2 end targets.push(trigger) number_of_targets.times do targets.push(opponents_unit.random_target) end elsif cskill.dual? # One enemy, dual targets.push(trigger) targets.push(trigger) elsif cskill.for_one? # One enemy targets.push(trigger) else # All enemies targets += opponents_unit.existing_members end elsif cskill.for_user? # User targets.push(battler) elsif cskill.for_dead_friend? if cskill.for_one? # One ally (incapacitated) targets.push(battler) else # All allies (incapacitated) targets += friends_unit.dead_members end elsif cskill.for_friend? if cskill.for_one? # One ally targets.push(battler) else # All allies targets += friends_unit.existing_members end end return targets end end # Game_BattleAction
#=============================================================================== # Game_Battler #===============================================================================
class Game_Battler #-------------------------------------------------------------------------- # Counter Effects #-------------------------------------------------------------------------- def counter_effect(attacker, state) clear_action_results unless attack_effective?(attacker) # If target is dead @skipped = true return end if state.accuracy < 0 # If no set accuracy accuracy = calc_hit(attacker) # Set accuracy to base else accuracy = state.accuracy # Use counterattack accuracy end if rand(100) >= accuracy # If attack misses @missed = true return end if state.counterspell # If a counterspell if state.evasion # If has evasion tag evasion = calc_eva(attacker) # Use normal evasion else evasion = 0 # No evasion end else evasion = calc_eva(attacker) # Use normal evasion end if rand(100) < evasion # If attack is evaded @evaded = true return end make_counter_damage_value(attacker, state) # Damage calculation execute_damage(attacker) # Damage reflection if @hp_damage == 0 # Physical and no damage? return end apply_state_changes(attacker) unless state.counterspell # State changes if $imported["CustomSkillEffects"] # Compatibility effects if state.counterspell if YE::BATTLE::INC_RAGE_SKILL attacker.rage += YE::BATTLE::NUM_RAGE_SKILL end else if YE::BATTLE::INC_RAGE_ATTACK attacker.rage += YE::BATTLE::NUM_RAGE_ATTACK end end end if $imported["BattleEngineMelody"] if state.counterspell value = YEM::BATTLE_ENGINE::SKILL_SETTINGS[:magical_rage_gain] else value = YEM::BATTLE_ENGINE::SKILL_SETTINGS[:attack_rage_gain] end value = attacker.rage_modifiers(value) attacker.gain_rage(value) end if $imported["SubclassSelectionSystem"] # Compatibility effects return unless attacker.actor? return unless YE::SUBCLASS::EARN_JP_VIA_ATTACK_ENABLE amount = YE::SUBCLASS::EARN_JP_VIA_ATTACK_AMOUNT unless YE::SUBCLASS::EARN_JP_VIA_ATTACK_RANDOM == 0 amount += rand(YE::SUBCLASS::EARN_JP_VIA_ATTACK_RANDOM) end attacker.gain_jp(amount) end end #-------------------------------------------------------------------------- # Counterattack damage calculation #-------------------------------------------------------------------------- def make_counter_damage_value(attacker, state) damage_atk = attacker.atk * 4 - self.def * 2 # Attack damage damage_atk *= state.atk_fc # Modified by multiplier if $imported["RES Stat"] # Compatability damage_spi = attacker.spi * 2 - self.res # Spirit damage else damage_spi = attacker.spi * 2 - self.spi # Spirit damage end damage_spi *= state.spi_fc # Modified by multiplier damage_agi = attacker.agi * 2 - self.agi # Agility damage damage_agi *= state.agi_fc # Modified by multiplier damage_def = attacker.def * 2 - self.def # Defense damage damage_def *= state.def_fc # Modified by multiplier damage = damage_atk + damage_spi + damage_agi + damage_def # Combined damage /= 100 # Complete multipliers damage = 0 if damage < 0 # No negative damage elements = [] if state.element.include?(-1) # If element -1 for element in attacker.element_set elements.push(element) # Add attack elements end elements.push(state.element) # Add counterattack elements elements.delete(-1) # Remove trigger element elsif state.element.include?(0) # If element 0 elements = [] # No elements else for element in state.element elements.push(element) # Add counterattack elements end end damage *= elements_max_rate(elements) # Element based damage mod damage /= 100 # Complete element damage if damage == 0 # If damage is 0, damage = rand(2) # Half of the time, 1 dmg elsif damage > 0 if state.critical < 0 # If no set critical rate critical = attacker.cri # Attacker's rate else critical = state.critical # Set critical rate end @critical = (rand(100) < attacker.cri) # Critical hit? @critical = false if prevent_critical # Criticals prevented? damage *= 3 if @critical # Critical adjustment end damage = apply_variance(damage, 20) # Variance damage = apply_guard(damage) # Guard adjustment @hp_damage = damage # Damage HP end end # Game_Battler
#=============================================================================== # Scene_Battle #===============================================================================
class Scene_Battle < Scene_Base #-------------------------------------------------------------------------- # * Alias Execute Battle Action: Attack #-------------------------------------------------------------------------- alias execute_action_attack_cca execute_action_attack def execute_action_attack execute_action_attack_cca if $game_temp.interrupt_state != nil # If there is an interrupt if $game_temp.interrupt_state.cskill > 0 execute_skill_interrupt($game_temp.interrupt_state, $game_temp.interrupter) else execute_action_interrupt($game_temp.interrupt_state, $game_temp.interrupter) # Execute end else check_counter($game_temp.newtargets) # Check for a counterattack end end #-------------------------------------------------------------------------- # * Alias Execute Battle Action: Skill #-------------------------------------------------------------------------- alias execute_action_skill_cca execute_action_skill def execute_action_skill execute_action_skill_cca if $game_temp.interrupt_state != nil # If there is an interrupt if $game_temp.interrupt_state.cskill > 0 execute_skill_interrupt($game_temp.interrupt_state, $game_temp.interrupter) else execute_action_interrupt($game_temp.interrupt_state, $game_temp.interrupter) # Execute end elsif @active_battler.action.foe_target_cca?($game_temp.newtargets) # If targetting an enemy check_counter($game_temp.newtargets) # Check for a counterattack end end #-------------------------------------------------------------------------- # * Alias Execute Battle Action: Item #-------------------------------------------------------------------------- alias execute_action_item_cca execute_action_item def execute_action_item execute_action_item_cca if $game_temp.interrupt_state != nil # If there is an interrupt if $game_temp.interrupt_state.cskill > 0 execute_skill_interrupt($game_temp.interrupt_state, $game_temp.interrupter) else execute_action_interrupt($game_temp.interrupt_state, $game_temp.interrupter) # Execute end elsif @active_battler.action.foe_target_cca?($game_temp.newtargets) # If targetting an enemy check_counter($game_temp.newtargets) # Check for a counterattack end end #-------------------------------------------------------------------------- # display attack animation counter #-------------------------------------------------------------------------- def display_attack_animation_counter(attacker, targets) if $imported["AnimationFix"] # Compatibility effects if attacker.is_a?(Game_Enemy) if YE::FIX::ENEMY_ANI if attacker.enemy.attack_ani > 0 ani_id = attacker.enemy.attack_ani else ani_id = YE::FIX::ENEMY_ATTACK_ANI end display_normal_animation(targets, ani_id, false) else Sound.play_enemy_attack wait(15, true) end else aid1 = attacker.atk_animation_id aid2 = attacker.atk_animation_id2 display_normal_animation(targets, aid1, false) display_normal_animation(targets, aid2, true) end wait_for_animation elsif $imported["BattleEngineMelody"] if attacker.is_a?(Game_Enemy) aid1 = attacker.atk_animation_id display_normal_animation(targets, aid1) else aid1 = attacker.atk_animation_id aid2 = attacker.atk_animation_id2 display_normal_animation(targets, aid1, false) wait_for_animation if aid2 != 0 display_normal_animation(targets, aid2, true) end wait_for_animation else if attacker.is_a?(Game_Enemy) # If a monster Sound.play_enemy_attack # Do monster thing wait(15, true) else # Otherwise, do attack animation aid1 = attacker.atk_animation_id aid2 = attacker.atk_animation_id2 display_normal_animation(targets, aid1, false) display_normal_animation(targets, aid2, true) end wait_for_animation end end #-------------------------------------------------------------------------- # Check Counter #-------------------------------------------------------------------------- def check_counter(targets) for battler in @active_battler.action.opponents_unit.existing_members for state in battler.states if state.guardian # If guardian flag is active if state.counter # If counter flag is active return unless battler.movable? # Return if immobile if state.cskill > 0 # If counter uses a skill execute_skill_counter(state, battler) # Make skill counterattack else execute_action_counter(state, battler) # Make counterattack end end end end end for target in targets return if @active_battler.action.friends_unit.members.include?(target) # Ignore friends for state in target.states if state.counter # If counter flag is active if not state.guardian # Ensure there are no repeats return unless target.movable? # Return if immobile if state.cskill > 0 # If counter uses a skill execute_skill_counter(state, target) # Make skill counterattack else execute_action_counter(state, target) # Make counterattack end end end end end end #-------------------------------------------------------------------------- # Execute Battle Action: Counterattack #-------------------------------------------------------------------------- def execute_action_counter(state, battler) return unless @active_battler.action.make_counter?(state) # Return if counter invalid mini_line = @message_window.line_number if $imported["SceneBattleReDux"] # Compatibility effects if YE::REDUX::BATTLE::MSG_CURRENT_ACTION if state.counterspell text = sprintf(COTUS::VOCAB::CSPELLTEXT, battler.name) else text = sprintf(COTUS::VOCAB::COUNTERTEXT, battler.name) end @message_window.add_instant_text(text) end else if state.counterspell # If a counterspell text = sprintf(COTUS::VOCAB::CSPELLTEXT, battler.name) # Counterspell text else # Otherwise text = sprintf(COTUS::VOCAB::COUNTERTEXT, battler.name) # Counterattack text end @message_window.add_instant_text(text) end targets = [@active_battler] if state.animation == 0 # If no set animation for counter display_attack_animation_counter(battler, targets) # Use battler's attack animation else display_animation(targets, state.animation) # Use counterattack's animation end @active_battler.counter_effect(battler, state) # Calculate effects display_action_effects(@active_battler) # Display effects if $imported["BattleEngineMelody"] @active_battler.perform_collapse end if $imported["SceneBattleReDux"] # Compatibility effects for target in targets target.perform_collapse unless target.collapse if @redux_msg and target.actor? @status_window.draw_item(target.index) if target.collapse end end end @message_window.back_to(mini_line) end #-------------------------------------------------------------------------- # Execute Battle Action: Interrupt #-------------------------------------------------------------------------- def execute_action_interrupt(state, battler) mini_line = @message_window.line_number if $imported["SceneBattleReDux"] # Compatibility effects if YE::REDUX::BATTLE::MSG_CURRENT_ACTION if state.counterspell text = sprintf(COTUS::VOCAB::CSPELLINTERRUPT, battler.name) else text = sprintf(COTUS::VOCAB::INTERRUPTTEXT, battler.name) end @message_window.add_instant_text(text) end else if state.counterspell # If a counterspell text = sprintf(COTUS::VOCAB::CSPELLINTERRUPT, battler.name) # CSpell interrupt text else text = sprintf(COTUS::VOCAB::INTERRUPTTEXT, battler.name) # Interrupt text end @message_window.add_instant_text(text) end targets = [@active_battler] if state.animation == 0 # If no set animation for counter display_attack_animation_counter(battler, targets) # Use battler's attack animation else # Otherwise display_animation(targets, state.animation) # Use counterattack's animation end @active_battler.counter_effect(battler, state) # Calculate effects display_action_effects(@active_battler) # Display effects if $imported["BattleEngineMelody"] @active_battler.perform_collapse end if $imported["SceneBattleReDux"] # Compatibility effects for target in targets target.perform_collapse unless target.collapse if @redux_msg and target.actor? @status_window.draw_item(target.index) if target.collapse end end end @message_window.back_to(mini_line) end #-------------------------------------------------------------------------- # Execute Battle Action: Counterattack Skill #-------------------------------------------------------------------------- def execute_skill_counter(state, battler) return unless @active_battler.action.make_counter?(state) # Return if counter invalid mini_line = @message_window.line_number if $imported["SceneBattleReDux"] # Compatibility effects if YE::REDUX::BATTLE::MSG_CURRENT_ACTION if state.counterspell text = sprintf(COTUS::VOCAB::CSPELLTEXT, battler.name) else text = sprintf(COTUS::VOCAB::COUNTERTEXT, battler.name) end @message_window.add_instant_text(text) end else if state.counterspell # If a counterspell text = sprintf(COTUS::VOCAB::CSPELLTEXT, battler.name) # Counterspell text else # Otherwise text = sprintf(COTUS::VOCAB::COUNTERTEXT, battler.name) # Counterattack text end @message_window.add_instant_text(text) end cskill = $data_skills[state.cskill] if state.targetnorm targets = battler.action.make_obj_targets(cskill) else targets = battler.action.make_cskill_targets(cskill, battler, @active_battler) end if cskill.animation_id < 0 and state.animation == 0 display_attack_animation_counter(battler, targets) elsif state.animation != 0 display_animation(targets, state.animation) else display_animation(targets, cskill.animation_id) end if state.costskill battler.mp -= battler.calc_mp_cost(skill) end $game_temp.common_event_id = cskill.common_event_id for target in targets target.skill_effect(battler, cskill) display_action_effects(target, cskill) if $imported["BattleEngineMelody"] # Compatibility effects target.perform_collapse end if $imported["SceneBattleReDux"] # Compatibility effects target.perform_collapse unless target.collapse if @redux_msg and target.actor? @status_window.draw_item(target.index) if target.collapse end end end @message_window.back_to(mini_line) end #-------------------------------------------------------------------------- # Execute Battle Action: Interrupt Skill #-------------------------------------------------------------------------- def execute_skill_interrupt(state, battler) return unless @active_battler.action.make_counter?(state) # Return if counter invalid mini_line = @message_window.line_number if $imported["SceneBattleReDux"] # Compatibility effects if YE::REDUX::BATTLE::MSG_CURRENT_ACTION if state.counterspell text = sprintf(COTUS::VOCAB::CSPELLINTERRUPT, battler.name) else text = sprintf(COTUS::VOCAB::INTERRUPTTEXT, battler.name) end @message_window.add_instant_text(text) end else if state.counterspell # If a counterspell text = sprintf(COTUS::VOCAB::CSPELLINTERRUPT, battler.name) # CSpell interrupt text else text = sprintf(COTUS::VOCAB::INTERRUPTTEXT, battler.name) # Interrupt text end @message_window.add_instant_text(text) end cskill = $data_skills[state.cskill] if state.targetnorm targets = battler.action.make_obj_targets(cskill) else targets = battler.action.make_cskill_targets(cskill, battler, @active_battler) end if cskill.animation_id < 0 and state.animation == 0 display_attack_animation_counter(battler, targets) elsif state.animation != 0 display_animation(targets, state.animation) else display_animation(targets, cskill.animation_id) end if state.costskill battler.mp -= battler.calc_mp_cost(skill) end $game_temp.common_event_id = cskill.common_event_id for target in targets target.skill_effect(battler, cskill) display_action_effects(target, cskill) if $imported["BattleEngineMelody"] # Compatibility effects target.perform_collapse end if $imported["SceneBattleReDux"] # Compatibility effects target.perform_collapse unless target.collapse if @redux_msg and target.actor? @status_window.draw_item(target.index) if target.collapse end end end @message_window.back_to(mini_line) end end # Scene_Battle </div></div></div> CustomizationYou shouldn't have to customize much of the script for normal use, but the text for when a counterattack happens can be easily edited. It's short distance below the description of how to set up counterattack states in the script. Just change the text in the quotes. CompatibilityI don't know how it will react to other counterattack scripts, so it's possible this would be compatable with at least some of them. Other than those, I would expect this to be compatable with most scripts. It should have full compatibility with Yanfly's custom skill effects, animation fix, and scene battle redux scripts, as I added in some pieces for that purpose. It also is intended to work with YEM, but the targeting is not fully functional with it. For it to work with Tankentai, insert the following line: @spriteset.set_damage_pop(@active_battler.actor?, @active_battler.index, @hp_damage) between the lines display_action_effects(@active_battler) # Display effects and if $imported["BattleEngineMelody"] (Thanks to ave369 for finding this.) InstallationJust put it above Main and below Materials. Some shuffling may be required to get it to work right with other scripts. Terms and ConditionsUse as desired; please credit me if you use it, that kind of stuff. For crediting, COTUS should work, Thorondor is also fine, but I don't know if anyone else is using that name and making scripts. If someone is, COTUS would probably be less likely to cause confusion. CreditsLarge parts of my understanding of scripting came from other peoples scripts, particularly Yanfly's. Without that, I never would have made this script.
This post has been edited by Thorondor: Mar 17 2012, 09:31 AM
|
|
|
|
|
|
|
|
|
May 24 2010, 06:27 PM
|
Level 2

Group: Member
Posts: 19
Type: None
RM Skill: Undisclosed

|
QUOTE (Fixxxer4153 @ May 14 2010, 11:24 AM)  That is cool. Might there be a possibility of making one for RMXP?! Or does anyone know of a counterattack script that works similarly to this for XP? Well, I've heard scripts can be converted between VX and XP with only the changing af certain key words, but I don't know enough to even try it. If someone else wants to, they're welcome to. You might be able to find a guide to converting scripts from VX to XP. And I have no idea what scripts there are for XP, so I'm afraid I can't really help you there. And since I'm already posting, I'll point out that I've just updated the script.
|
|
|
|
|
|
|
|
|
May 25 2010, 12:27 AM
|

RRR's little gay boy

Group: Revolutionary
Posts: 3,375
Type: Developer
RM Skill: Advanced

|
This is good. Really good!
Well, with one minor issue: I could really use it if the counterattack triggered a specific skill. Since this isn't compatible with things like Yanfly's custom damage formula as a result (As in a -literal- custom damage formula), and that's kind of important for my current project, but I would really like to use it.
__________________________
RRR 2006 Awards: Best Topic Starter, Ultimate Debater, Most Likely To Bail You Out of Jail, and Most Likely To Become Ruler of the World. RRR 2007 Awards: Master Debater, Elite Gamer, and Uber-Nerd RRR 2008 Awards: Former staff member - VG Hub & General maker discussion
|
|
|
|
|
|
|
|
|
May 25 2010, 08:02 AM
|
Level 2

Group: Member
Posts: 19
Type: None
RM Skill: Undisclosed

|
QUOTE (Garlyle @ May 25 2010, 04:27 AM)  This is good. Really good!
Well, with one minor issue: I could really use it if the counterattack triggered a specific skill. Since this isn't compatible with things like Yanfly's custom damage formula as a result (As in a -literal- custom damage formula), and that's kind of important for my current project, but I would really like to use it. I chould be able to add that. If it isn't too hard I'll probably add that today; otherwise it might be delayed.
|
|
|
|
|
|
|
|
|
May 26 2010, 06:22 AM
|
Level 2

Group: Member
Posts: 19
Type: None
RM Skill: Undisclosed

|
Okay, counterattacks can activate skills now.
|
|
|
|
|
|
|
|
|
Jul 14 2010, 09:18 PM
|
Level 4

Group: Member
Posts: 58
Type: None
RM Skill: Undisclosed

|
im getting error "member variable undefined" at line 785
|
|
|
|
|
|
|
|
|
Jul 16 2011, 01:27 AM
|

Group: Member
Posts: 2
Type: None
RM Skill: Beginner

|
Sorry if this is necropost-y, but I've run into a problem. I'm using YEM for my game, and it seems that every time a counterattack ends the battle, the game just crashes. Any insight on this?
|
|
|
|
|
|
|
|
|
Sep 13 2011, 05:44 PM
|
Level 2

Group: Member
Posts: 19
Type: None
RM Skill: Undisclosed

|
Well...this is absurdly late, due to the fact that I forgot to check back here occasionally, but I've dealt with that by taking the brilliant step of telling the forum to email me whenever someone posts on this thread.  Okay, now, this may be so late I shouldn't respond, but I will anyway, and hopefully you'll see this... I may not have all the YEM scripts, but it isn't crashing for me when a counterattack ends the battle. What YEM scripts are you using, are there any other scripts you are using, and what types of counterattacks? Or if anyone else runs into the problem; now that I should know if anyone posts here, I should see it sometime before a few months...Sorry about that.
|
|
|
|
|
|
|
|
|
Dec 6 2011, 04:43 AM
|

Group: Member
Posts: 2
Type: None
RM Skill: Beginner

|
QUOTE (Thorondor @ Sep 13 2011, 05:44 PM)  Well...this is absurdly late, due to the fact that I forgot to check back here occasionally, but I've dealt with that by taking the brilliant step of telling the forum to email me whenever someone posts on this thread.  Okay, now, this may be so late I shouldn't respond, but I will anyway, and hopefully you'll see this... I may not have all the YEM scripts, but it isn't crashing for me when a counterattack ends the battle. What YEM scripts are you using, are there any other scripts you are using, and what types of counterattacks? Or if anyone else runs into the problem; now that I should know if anyone posts here, I should see it sometime before a few months...Sorry about that. Never mind, I found the problem. Just a request: could you give an example of a <cskill> and <targetnorm> state? I can't seem to get mine to work. Here's what I've done: <counter> <cskill 1> <targetnorm>
|
|
|
|
|
|
|
|
|
Dec 6 2011, 09:02 AM
|
Level 2

Group: Member
Posts: 19
Type: None
RM Skill: Undisclosed

|
Well... it looks like it isn't working right... I don't know if I didn't test it thoroughly, or if something else is wrong. I'll try to fix it, but it might take a while, because I'm a little busy. Once I fix it, I'll add an example as well, but for now:
<counter> <vs_physical> <cskill 29> <targetnorm>
That should make it counterattack with skill 29 using that skill's normal targeting, and be triggered by a physical attack. At the moment, however, it uses skill 29 with...strange targeting. Also, the counterattack happens at the same time as the next attack if a monster goes next, and some other stuff may be wrong. I'll try to fix it soon, though. It's really weird, because I'm sure I tested it back when I first made it, but maybe I then broke it or something later...
*edit* Fixing it may take a while, not just because I'm busy, but also because I'm out of practice. I haven't done any RPG Maker scripting for months, and I don't remember everything.
This post has been edited by Thorondor: Dec 6 2011, 09:32 AM
|
|
|
|
|
|
|
|
|
Jan 17 2012, 09:48 AM
|
Level 2

Group: Member
Posts: 19
Type: None
RM Skill: Undisclosed

|
I'm really sorry about how long this is taking, but I still haven't managed to fix all of it. I've fixed a few more minor problems, but I still can't get counterattack skills to work properly with YEM, and the <targetnorm> tag isn't working, either, as it just makes one battler be targeted every time. To make up for that, I've shifted how it works without the <taretnorm> tag, so that it should target as normal unless you're using a custom targeting system. However, with YEM, when targeting one battler twice, or more than one random battler, it only makes one attack, which is on the triggering battler. I've updated the script here in this thread, so you can use it with skills to a limited extent, but I'll still try to fix it the rest of the way. The <targetnorm> tag will either be dropped, or turned into a tag to make it work with custom targeting, which will probably require you to duplicate the custom targeting code in the counterattack script as well, unfortunately.
|
|
|
|
|
|
|
2 User(s) are reading this topic (2 Guests and 0 Anonymous Users)
0 Members:
RPG RPG Revolution is an Privacy
Policy and Legal
|
|