(07-10-2014, 04:59 AM)Djigit Wrote: Okay I managed to solve this problem. This topic can be closed by now.
EDIT: Theres still little problem: The actor does also counterattack when somebody uses a heal skill or a cure skill. Is there a chance to fix that problem? Please do not cloe.
Here is what I've done to make it work. First how to make it work WITHOUT an ctb or atb addon
1. put the counterattack addon above main.
2. go to line 475/ 476 put an # infront of these lines.
They should look like this now:
def remember_current_action
@remembered_action = [@current_action.clone, self.action_scope]
end
def restore_current_action
@current_action, self.action_scope = *@remembered_action
clear_remembered_action
end
def clear_remembered_action
@remembered_action = nil
end
end
class Scene_Battle
#--------------------------------------------------------------------------
# * Check allow next action
# EDIT: Always allow Counter-Actions
#--------------------------------------------------------------------------
def allow_next_action
return false if cant_if_same
return false if cant_if_damaged_or_invisible
return false if cant_target_invisible
return true if @active_battlers.empty?
# --- EDIT: ---
@action_battlers.each_with_index do |battler, index|
next unless battler.counter_waiting != nil
next unless battler.counter_waiting.wait_counter
next if @active_battlers.include?(battler)
@action_battlers.delete_at(index)
@action_battlers.unshift(battler)
return true
end
# -------------
return false if cant_if_enemy_target and not Allow_Enemy_Target
return false if cant_target_active and not Allow_Active_Target
return false if cant_target_moving? and not Allow_Moving_Target
return true if next_before_return? and Next_Before_Return
return true if allow_same_targets? and Allow_Same_Target
return true if allow_diff_targets? and Allow_Diff_Targets
return false
end
#--------------------------------------------------------------------------
# * Update battler phase 5 (part 1)
# battler : active battler
# EDIT: Do not remove Countering Targets from the queue!
#--------------------------------------------------------------------------
def step5_part1(battler)
step5_part1_counter(battler)
if battler.counter_waiting != nil
battler.counter_waiting.wait_counter = false
battler.counter_waiting = nil
end
for target in $game_party.actors + $game_troop.enemies
if target.counter_action != nil and target.inputable? and not
target.hp0? and not battler.counter_action_set
set_counter_action(battler, target)
target.counter_action_set = true
@action_battlers.unshift(target)
#@action_battlers.uniq!
if target.returning? and target.moving?
target.current_phase = 'Phase 2-1'
target.target_x = target.actual_x
target.target_y = target.actual_y
end
end
target.counter_action = nil
end
end
#--------------------------------------------------------------------------
# * Set counter action
# battler : battler
# target : target
# EDIT: Remember original action to restore it after Execution;
# Force Counter Action to suppress Restriction-Effects.
#--------------------------------------------------------------------------
alias_method(:set_counter_action_ILC_remember_action, :set_counter_action)
def set_counter_action(battler, target)
target.remember_current_action
set_counter_action_ILC_remember_action(battler, target)
target.current_action.forcing = true
end
#--------------------------------------------------------------------------
# * Update battler phase 5 (part 4)
# battler : active battler
# EDIT: Restore remembered Action when terminating a Counter
#--------------------------------------------------------------------------
def step5_part4(battler)
# ---
battler.restore_current_action if battler.counter_action_set
# ---
step5_part4_counter(battler)
battler.counter_action_set = false
battler.valid_counters.clear
end
end
Now it should work fine unless you use ctb or atb addon
5.1 If yo want to use the ctb or atb addon you have to do the same but add little things.
(REMEMBER: YOU HAVE TO DO THE SAME STEPS BEFORE TOO)
5.2 go to line 63 of the little script and replace:
Code:
target.inputable?
with
Code:
target.inputable_by_status?
5.3 Add this little code between the line 4 and 6.
Code:
alias_method(:inputable_by_status?, :inputable?)
Now it should work also if you use one of the ctb or atb addon.
Thank you very much wulfman and admin or moderator please close this topic..
Hello guys. Thanks for your help.
Normally the counterattack works fine so far. I did everything you said and he counters the attack fine.
But theres one huge problem: I've configurated a state (number 100) where the battler with the state uses a potion (number 37) whenenver he is attacked by a monster.
So according to this configuration the battler with state 101 uses a potion (which is id 37 in my database) to heal whenever he is attacked by an enemy (game enemy) with physical or magical attack.
Well it works, the battler indeed uses a potion after he has been attacked but sadly he doesnt use the potion on himself. He always uses the potion on the first actor. The actor which has the state 101 is the last in the row. (I mean he's the fourth actor).
Instead of healing himself with the potion, he heals the first actor.
Is there any bug in the code or did I just configurated it wrong?
Can you please make your your post more clear? I didint understand the meaning of your posts. (sorry so far)
What I meant is: The battler (which is the last in the row) is supposed to use item 37 whenever he is attacked while having status 101 But instead of healing himself he heals the first actor.
12-14-2014, 09:38 PM (This post was last modified: 12-14-2014, 09:41 PM by Eagleeye1990.)
Oh I see.
Maybe I there's a bug in the script. Allow me to post the two scripts which im Using. Its easier to find a bug when the both scripts are posted complete.
Heres the Add | Counter Attack script by atoa (originally)
Code:
#==============================================================================
# Counter Attack
# by Atoa
#==============================================================================
# This script allows actors/enemies to use counter-attack with
# different conditions.
#==============================================================================
module Atoa
# Don't change or delete these lines.
Counter_Setting = {'Actor' => {}, 'Enemy' => {}, 'Skill' => {}, 'State' => {},
'Armor' => {}, 'Weapon' => {}}
# Don't change or delete these lines.
# Type : Counter-Attack Type
# 'Actor' for actors
# 'Enemy' for enemies
# 'Skill' for skills (the skill has to be learnt)
# 'State' for effects
# 'Armor' for armors
# 'Weapon' for weapons
# Activation = {'type' => type, 'condition' => condition, 'action' => specific action}
# Type: Action which will activate the counter
# 0 = Normal Attack
# 1 = Attack Skills
# 2 = Magic Skills
# 3 = Specific Actions
# 4 = Any attack or skill
#
# Condition: Needed Conditions to counter
# This can be left out (counter will always be executed)
# Text String with the condition to be used can be script commands and available
# methods from Game_Battler Class.
#
# You can add other atrributes using its respective script commands
# "user" - user/attacker (the one who is attacking)
# "target" - target (the one who is being attacked and will counter)
# "skill" - skill
# "damage" - damage dealt on the target
# Examples:
# "damamge.numeric? and damage >= 200" # if damage is a numeric value
# #greater or equal to 200
#
# "damamge.numeric? and damage > 50 * target.maxhp / 100" # if damage is a numeric value
# #greater than 50% target max hp
# "damage == Miss_Message" # if damage is not a value but a message error
# # (when "miss" message shows up)
# "rand(100) < 50" # If random value from 0 to 100 is less than 50
# # (50% chance of countering)
# "rand(100) < 70 and target.hp < target.maxhp / 2" # If random value from 0 to 100
# # is less than 70 (70% chance of countering) and only
# # if taget has half of its full hp
#
# IMPORTANT: to verifuy if a value is "greater or less" when damage is related,
# it's extremely important to use 'damage.numeric?' method to check
# if damage is a numberic value. If you use operator like "<" and ">" for verifications
# using texts, there will be an error, since damage can be shown as texts.
#
# Specific Action : This value can only be used if "Type" is equal to 3
# It has to be a list containing all skill IDs that will make counter
# work
# Effect = [[Type, Target(, [ID], Cost)],...]
# Effect = {'type' => Type, 'target' => Target, 'id' => [ID], 'cost' => Cost, wait => Wait}
# Type : Attack Type
# 0 = Normal Attack
# 1 = Skill
# 2 = Itens
# Target: Action target, it can be left out. If left out the target will be
# the action default ones
# 0 = Enemies (one only target actions will always hit the target battler)
# 1 = Allies (one only target actions will always hit the user)
# ID : Numeric value or list containing action/skill IDs available
# only if type is 1 or 2
# If more than one value is set, the action will be random among
# available actions.
# Cost : Action cost, true or false. Only if type is 1 or 2.
# If true, the skill will just be executed if the cost can be payed
# and it will consume its SP or Item cost.
# Wait : Waiting time, true or false, it can be left out.
# If true, after attackin, the battler will hold on until counter-attack action ends,
# and then returns to its position.
end
#==============================================================================
# ** Atoa Module
#==============================================================================
$atoa_script = {} if $atoa_script.nil?
$atoa_script['Atoa Counter Attack'] = true
#==============================================================================
# ** Game_Battler
#------------------------------------------------------------------------------
# This class deals with battlers. It's used as a superclass for the Game_Actor
# and Game_Enemy classes.
#==============================================================================
class Game_Battler
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_accessor :counter_action
attr_accessor :counter_action_set
attr_accessor :counter_targets
attr_accessor :counter_cost
attr_accessor :wait_counter
attr_accessor :valid_counters
attr_accessor :counter_waiting
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
alias initialize_counter initialize
def initialize
@counter_targets = []
@valid_counters = []
initialize_counter
end
#--------------------------------------------------------------------------
# * Applying Normal Attack Effects
# attacker : battler
#--------------------------------------------------------------------------
alias attack_effect_counter attack_effect
def attack_effect(attacker)
effective = attack_effect_counter(attacker)
if $game_temp.in_battle and attacker != self and not attacker.counter_action_set
damage = attacker.target_damage[self]
set_counter_condition(attacker, damage)
end
return effective
if attacker.states.include?(95)
self.critical = true
end
end
#--------------------------------------------------------------------------
# * Apply Skill Effects
# user : user
# skill : skill
#--------------------------------------------------------------------------
alias skill_effect_counter skill_effect
def skill_effect(user, skill)
effective = skill_effect_counter(user, skill)
if $game_temp.in_battle and user != self and not user.counter_action_set
damage = user.target_damage[self]
set_counter_condition(user, damage, skill)
end
return effective
if skill.element_set.include?(30) and if user.states.include?(95)
self.critical = true
end
end
end
#--------------------------------------------------------------------------
# * Consume skill cost
# skill : skill
#--------------------------------------------------------------------------
alias consume_skill_cost_counter consume_skill_cost
def consume_skill_cost(skill)
return if self.counter_action_set and not self.counter_cost
consume_skill_cost_counter(skill)
end
#--------------------------------------------------------------------------
# * Set counter condition
# user : user
# damage : damage
# skill : skill
#--------------------------------------------------------------------------
def set_counter_condition(user, damage, skill = nil)
if self.actor?
set_counter(user, damage, skill, 'Actor')
set_counter(user, damage, skill, 'Skill')
set_counter(user, damage, skill, 'Armor')
set_counter(user, damage, skill, 'Weapon')
else
set_counter(user, damage, skill, 'Enemy')
end
set_counter(user, damage, skill, 'State')
return if @valid_counters.empty?
self.counter_action = @valid_counters[rand(@valid_counters.size)]
end
#--------------------------------------------------------------------------
# * Set counter
# user : user
# damage : damage
# skill : skill
# kind : kind
#--------------------------------------------------------------------------
def set_counter(user, damage, skill, kind)
if kind == 'Actor' and Counter_Setting['Actor'][self.id] != nil
counter = Counter_Setting['Actor'][self.id].dup
set_counter_values(user, damage, skill, kind, counter)
end
if kind == 'Enemy' and Counter_Setting['Enemy'][self.id] != nil
counter = Counter_Setting['Enemy'][self.id].dup
set_counter_values(user, damage, skill, kind, counter)
end
if kind == 'State'
for id in self.states
if Counter_Setting['State'][id] != nil
counter = Counter_Setting['State'][id]
set_counter_values(user, damage, skill, kind, counter)
end
end
end
if kind == 'Skill'
for id in self.skills
if Counter_Setting['Skill'][id] != nil
counter = Counter_Setting['Skill'][id]
set_counter_values(user, damage, skill, kind, counter)
end
end
end
if kind == 'Armor'
for armor in self.armors
id = armor.id
if Counter_Setting['Armor'][id] != nil
counter = Counter_Setting['Armor'][id]
set_counter_values(user, damage, skill, kind, counter)
end
end
end
if kind == 'Weapon'
for weapon in self.weapons
id = weapon.id
if Counter_Setting['Weapon'][id] != nil
counter = Counter_Setting['Weapon'][id]
set_counter_values(user, damage, skill, kind, counter)
end
end
end
end
#--------------------------------------------------------------------------
# * Set counter values
# user : user
# damage : damage
# skill : skill
# kind : kind
# counter : settings
#--------------------------------------------------------------------------
def set_counter_values(user, damage, skill, kind, counter)
for condition in counter.keys
current = counter[condition]
next if skill.nil? and not [0, 4].include?(condition['type'])
next if skill != nil and not skill.magic? and not [1, 4].include?(condition['type'])
next if skill != nil and skill.magic? and not [2, 4].include?(condition['type'])
next if skill != nil and condition['action'] != nil and not
condition['action'].include?(skill.id)
next if condition['condition'] != nil and not eval(get_condition(condition))
next if current['cost'] and current['type'] == 1 and cant_counter_skill(current['id'])
next if current['cost'] and current['type'] == 2 and cant_counter_item(current['id'])
@valid_counters << set_counter_action(current)
end
end
#--------------------------------------------------------------------------
# * Get condition
# condition : current setting
#--------------------------------------------------------------------------
def get_condition(condition)
current = condition['condition']
current.gsub!(/target/i) {"self"}
return current
end
#--------------------------------------------------------------------------
# * Allow skill for counter
# current : current setting
#--------------------------------------------------------------------------
def cant_counter_skill(current)
return (not skill_can_use?(current)) if current.numeric?
for skill_id in current
return false if skill_can_use?(skill_id)
end
return true
end
#--------------------------------------------------------------------------
# * Allow item for counter
# current : current setting
#--------------------------------------------------------------------------
def cant_counter_item(current)
return (self.actor? and not $game_party.item_can_use?(current)) if current.numeric?
for item_id in current
return false if $game_party.item_can_use?(item_id) or not self.actor?
end
return true
end
#--------------------------------------------------------------------------
# * Set counter action
# current : current setting
#--------------------------------------------------------------------------
def set_counter_action(current)
if current['type'] == 1 and current['id'].is_a?(Array)
available_skills = []
for skill_id in current
available_skills << skill_id if skill_can_use?(skill_id) or not current['cost']
end
action = available_skills[rand(available_skills.size)]
elsif current['type'] == 2 and current['id'].is_a?(Array)
available_skills = []
for item_id in current
available_skills << skill_id if $game_party.item_can_use?(item_id) or not
current['cost'] or not self.actor?
end
action = available_skills[rand(available_skills.size)]
else
action = current['id']
end
return current.dup
end
end
#==============================================================================
# ** Scene_Battle
#------------------------------------------------------------------------------
# This class performs battle screen processing.
#==============================================================================
class Scene_Battle
#--------------------------------------------------------------------------
# * Start battler turn
# battler : battler
#--------------------------------------------------------------------------
alias battler_turn_counter battler_turn if $atoa_script["Atoa ATB"] or $atoa_script["Atoa CTB"]
def battler_turn(battler)
return if battler.counter_action_set
battler_turn_counter(battler)
end
#--------------------------------------------------------------------------
# * Update battler phase 5 (part 1)
# battler : active battler
#--------------------------------------------------------------------------
alias step2_part1_counter step2_part1
def step2_part1(battler)
for target in $game_party.actors + $game_troop.enemies
if target.dead?
target.counter_action = nil
target.counter_action_set = false
target.counter_waiting = nil
target.wait_counter = false
target.counter_cost = false
target.current_action.clear
target.action_scope = 0
end
end
step2_part1_counter(battler)
if battler.counter_action != nil and battler.counter_action_set
battler.current_phase = "Phase 2-1"
return
end
end
#--------------------------------------------------------------------------
# * Update battler phase 5 (part 1)
# battler : active battler
#--------------------------------------------------------------------------
alias step5_part1_counter step5_part1
def step5_part1(battler)
step5_part1_counter(battler)
if battler.counter_waiting != nil
battler.counter_waiting.wait_counter = false
battler.counter_waiting = nil
end
for target in $game_party.actors + $game_troop.enemies
if target.counter_action != nil and target.inputable? and not
target.hp0? and not battler.counter_action_set
set_counter_action(battler, target)
target.counter_action_set = true
@action_battlers.unshift(target)
@action_battlers.uniq!
if target.returning? and target.moving?
target.current_phase = 'Phase 2-1'
target.target_x = target.actual_x
target.target_y = target.actual_y
end
end
target.counter_action = nil
end
end
#--------------------------------------------------------------------------
# * Update battler phase 5 (part 2)
# battler : active battler
#--------------------------------------------------------------------------
alias step5_part2_counter step5_part2
def step5_part2(battler)
return if battler.wait_counter
step5_part2_counter(battler)
end
#--------------------------------------------------------------------------
# * Update battler phase 5 (part 4)
# battler : active battler
#--------------------------------------------------------------------------
alias step5_part4_counter step5_part4
def step5_part4(battler)
step5_part4_counter(battler)
battler.counter_action_set = false
battler.valid_counters.clear
end
#--------------------------------------------------------------------------
# * Set action cost
# battler : battler
#--------------------------------------------------------------------------
alias set_action_cost_counter set_action_cost if $atoa_script['Atoa CTB']
def set_action_cost(battler)
if battler.counter_action_set
battler.current_cost = 0
return
end
set_action_cost_counter(battler)
end
#--------------------------------------------------------------------------
# * ATB reset
# battler : active battler
#--------------------------------------------------------------------------
alias reset_atb_counter reset_atb if $atoa_script['Atoa ATB']
def reset_atb(battler)
return if battler.counter_action_set
reset_atb_counter(battler)
end
#--------------------------------------------------------------------------
# * Set item consum
# battler : battler
#--------------------------------------------------------------------------
alias consum_item_cost_counter consum_item_cost
def consum_item_cost(battler)
return if battler.counter_action_set and not battler.counter_cost
consum_item_cost_counter(battler)
end
#--------------------------------------------------------------------------
# * Set counter action
# battler : battler
# target : target
#--------------------------------------------------------------------------
def set_counter_action(battler, target)
action = target.counter_action
#target.counter_info = [target.current_action.kind, target.current_action.basic,
#target.current_action.skill_id, target.current_action.item_id, target.action_scope]
target.current_action.kind = action["type"]
target.current_action.basic = 0 if action["type"] == 0
target.current_action.skill_id = action["id"] if action["type"] == 1
target.current_action.item_id = action["id"] if action["type"] == 2
target.counter_cost = action["cost"]
if action["type"] == 1 or action["type"] == 2
id = target.current_action.skill_id if action["type"] == 1
id = target.current_action.item_id if action["type"] == 2
target.current_skill = $data_skills[id] if action["type"] == 1
target.current_item = $data_items[id] if action["type"] == 2
end
target.current_action.target_index = battler.index
if action["type"] == 1
scope = 7
target.action_scope = scope
elsif action["type"] == 0
scope = oposite_side(battler, target) ? 1 : 3
target.action_scope = scope
end
if (target.current_skill != nil or target.current_item != nil) and not
oposite_side(battler, target)
current_action = target.current_skill if target.current_skill != nil
current_action = target.current_item if target.current_item != nil
case current_action.scope
when 1 then scope = 3
when 2 then scope = 4
when 3 then scope = 1
when 4 then scope = 2
when 5 then scope = 1
when 6 then scope = 2
end
target.action_scope = scope
end
set_target_battlers(target, scope)
target.action_scope = 0
if action["wait"]
battler.wait_counter = true
target.counter_waiting = battler
battler.pose_id = @spriteset.battler(battler).set_idle_pose
end
end
end
and this is addon which comes right after the first script.
def restore_current_action
@current_action, self.action_scope = *@remembered_action
clear_remembered_action
end
def clear_remembered_action
@remembered_action = nil
end
end
class Scene_Battle
#--------------------------------------------------------------------------
# * Check allow next action
# EDIT: Always allow Counter-Actions
#--------------------------------------------------------------------------
def allow_next_action
return false if cant_if_same
return false if cant_if_damaged_or_invisible
return false if cant_target_invisible
return true if @active_battlers.empty?
# --- EDIT: ---
@action_battlers.each_with_index do |battler, index|
next unless battler.counter_waiting != nil
next unless battler.counter_waiting.wait_counter
next if @active_battlers.include?(battler)
@action_battlers.delete_at(index)
@action_battlers.unshift(battler)
return true
end
# -------------
return false if cant_if_enemy_target and not Allow_Enemy_Target
return false if cant_target_active and not Allow_Active_Target
return false if cant_target_moving? and not Allow_Moving_Target
return true if next_before_return? and Next_Before_Return
return true if allow_same_targets? and Allow_Same_Target
return true if allow_diff_targets? and Allow_Diff_Targets
return false
end
#--------------------------------------------------------------------------
# * Update battler phase 5 (part 1)
# battler : active battler
# EDIT: Do not remove Countering Targets from the queue!
#--------------------------------------------------------------------------
def step5_part1(battler)
step5_part1_counter(battler)
if battler.counter_waiting != nil
battler.counter_waiting.wait_counter = false
battler.counter_waiting = nil
end
for target in $game_party.actors + $game_troop.enemies
if target.counter_action != nil and target.inputable_by_status? and not
target.hp0? and not battler.counter_action_set
set_counter_action(battler, target)
target.counter_action_set = true
@action_battlers.unshift(target)
#@action_battlers.uniq!
if target.returning? and target.moving?
target.current_phase = 'Phase 2-1'
target.target_x = target.actual_x
target.target_y = target.actual_y
end
end
target.counter_action = nil
end
end
#--------------------------------------------------------------------------
# * Set counter action
# battler : battler
# target : target
# EDIT: Remember original action to restore it after Execution;
# Force Counter Action to suppress Restriction-Effects.
#--------------------------------------------------------------------------
alias_method(:set_counter_action_ILC_remember_action, :set_counter_action)
def set_counter_action(battler, target)
target.remember_current_action
set_counter_action_ILC_remember_action(battler, target)
target.current_action.forcing = true
end
#--------------------------------------------------------------------------
# * Update battler phase 5 (part 4)
# battler : active battler
# EDIT: Restore remembered Action when terminating a Counter
#--------------------------------------------------------------------------
def step5_part4(battler)
# ---
battler.restore_current_action if battler.counter_action_set
# ---
step5_part4_counter(battler)
battler.counter_action_set = false
battler.valid_counters.clear
end
It has nothing to do with your second script. Using your config, I too have an issue. However it is my 2nd party member (also actor #2 in the database) that is healed, whether it be by a potion or by healing skill. My party is the default ATOA party of Atoa, KaHn, DarkLuar and Tunico.
As a side note: State based counterattacks do not work at all when using the ATB script add-on. I had to remove it to get the state counter attack to function at all, even if damaged in function.
Up is down, left is right and sideways is straight ahead. - Cord "Circle of Iron", 1978 (written by Bruce Lee and James Coburn... really...)
Im sorry for needing to revive this topic. Glad that I found it. Solved many problems.
Counterattack works fine for me when using your patch with the CTB addon. Except for the healing item potion but I dont need that anyway.
What troubkles me is this: When I have counter as a state and Im casting a skill and I get attacked, the cast ends by casting the skill while cast wasnt done yet. So, the counter even reacts when skills are casted what I dont want.
I hope this problem is solvable. But I dont know how.
I used the same counter scripts as posted on post #16. And heres the normal CTB Code:
Damn, its so big, it cant be posed.
I put it into a attachment