04-05-2014, 08:14 AM
DoubleX RMVXA Intercept Magic
Version: v1.03b
IntroductionVersion: v1.03b
Allows users to set states that intercepts magic under some conditions(similar to FF6's Runic command)
Features
* Use of notetags(requires knowledge of notetag usage) to set specific states to let battlers intercept skills
Video
Script
"script"
Code:
#==============================================================================|
# ** DoubleX RMVXA Intercept Magic v1.03b |
#------------------------------------------------------------------------------|
# * Changelog |
# v1.03b(GMT 1400 7-7-2015): |
# - Improved this script's efficiency and readability |
# v1.03a(GMT 1000 7-12-2014): |
# - Added <ally intercept>, <enemy intercept> and <intercept chance>notetags|
# v1.02b(GMT 1000 27-7-2014): |
# - Fixed crashes with Intercept_MP_Limit or Intercept_TP_Limit being true |
# v1.02a(GMT 0700 21-6-2014): |
# - Added <hit intercept mp> and <hit intercept tp> notetags |
# v1.01a(GMT 0200 8-4-2014): |
# - Allows users to set intercept animations |
# v1.00b(GMT 0900 7-4-2014): |
# - Fixed intercept magic not working on allies' skills bug |
# v1.00a(GMT 0700 5-4-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 set states that intercepts magic under some conditions |
#------------------------------------------------------------------------------|
# * 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 aliasing or rewriting method: |
# - self.load_database under module DataManager |
# - add_state under class Game_Battler |
# - use_item 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 Intercept Magic"] = true
#==============================================================================|
# ** You only need to edit this part as it's about what this script does |
#------------------------------------------------------------------------------|
module DoubleX_RMVXA
module Intercept_Magic
#------------------------------------------------------------------------------|
# * Notetag <intercept tier: x> for skills and states: |
# - Allows battlers having states with this notetag to intercept skills with|
# this notetag(x must be greater than 0 in order for this notetag to work)|
# - If the intercept tier of the states is greater than or equal to that of |
# the skills, those skills will be intercepted if other conditions are met|
# - If more than 1 battler can intercept a skill, the one having any |
# intercept state for the shortest time will intercept the skill |
# - This notetag needs <ally intercept> or <enemy intercept> to be present |
# to work(they can be used together to let any battler be the interceptor)|
#------------------------------------------------------------------------------|
# * Notetag <intercept mp> for skills and states: |
# - Interceptors having states with this notetag absorb mp equal to the mp |
# cost of the skills intercepted if those skills also have this notetag |
# - Put this notetag below <intercept tier: x> to make this notetag work |
#------------------------------------------------------------------------------|
# * Notetag <intercept tp> for skills and states: |
# - Interceptors having states with this notetag absorb tp equal to the tp |
# cost of the skills intercepted if those skills also have this notetag |
# - Put this notetag below <intercept tier: x> to make this notetag work |
#------------------------------------------------------------------------------|
# * (v1.02a+)Notetag <hit intercept mp> for skills and states: |
# - Failed interceptions due to Intercept_MP_Limit will cause the skill to |
# only hit the interceptor if both the skills and states have this notetag|
#------------------------------------------------------------------------------|
# * (v1.02a+)Notetag <hit intercept tp> for skills and states: |
# - Failed interceptions due to Intercept_TP_Limit will cause the skill to |
# only hit the interceptor if both the skills and states have this notetag|
#------------------------------------------------------------------------------|
# * (v1.03a+)Notetag <ally intercept> for skills and states: |
# - Interceptors having states with this notetag can intercept skills with |
# this notetag if their users are allies and other conditions are met |
# - Putting this notetag above <enemy intercept> means allies will always |
# intercept the skills if enemies can also intercept them |
# - The ordering of <ally intercept> and <enemy intercept> in skills to be |
# intercepted will be used if intercepting states also has those notetags |
# - Put this notetag below <intercept tier: x> to make this notetag work |
#------------------------------------------------------------------------------|
# * (v1.03a+)Notetag <enemy intercept> for skills and states: |
# - Interceptors having states with this notetag can intercept skills with |
# this notetag if their users are enemies and other conditions are met |
# - Putting this notetag above <ally intercept> means enemies will always |
# intercept the skills if allies can also intercept them |
# - The ordering of <ally intercept> and <enemy intercept> in skills to be |
# intercepted will be used if intercepting states also has those notetags |
# - Put this notetag below <intercept tier: x> to make this notetag work |
#------------------------------------------------------------------------------|
# * (v1.03a+)Notetag <intercept chance: x> for skills and states: |
# - Interceptors having states with this notetag have a x% chance to |
# intercept skills that can be intercepted if other conditions are met |
# - Skills that can be intercepted with this notetag have a x% chance to be |
# intercepted by interceptors if other conditions are met |
# - The real chance of success is that of intercepting states multiplied by |
# that of skills to be intercepted |
# - If this notetag is absent, the chance of success will be 100% |
#------------------------------------------------------------------------------|
#------------------------------------------------------------------------------|
# * (v1.01a+)Intercept_Animation_Id, default = 0 |
# Animations with id Intercept_Animation_Id will be played upon interception|
# if 0 < Intercept_Animation_Id < 1000 |
#------------------------------------------------------------------------------|
Intercept_Animation_Id = 0
#------------------------------------------------------------------------------|
# * Intercept_SE, default = RPG::SE.new(File, Volume, Pitch) |
# SE file File with volume Volume and pitch Pitch will be played upon |
# successful interceptions |
#------------------------------------------------------------------------------|
# File is a SE file without specifying its extension and with or without
# specifying its path
# Volume and Pitch range from 1 to 100 and 5 to 200 respectively
# Setting Intercept_SE as nil or false will disable this feature
Intercept_SE = RPG::SE.new("Absorb1", 80, 100)
#------------------------------------------------------------------------------|
# * Intercept_Times_Limit, default = 0 |
# Intercept states will worn off after its battlers intercepted |
# Intercept_Times_Limit skills(0 here means no such limit) |
#------------------------------------------------------------------------------|
Intercept_Times_Limit = 0
#------------------------------------------------------------------------------|
# * (v1.02a+)Count_Fail_Intercept, default = true |
# Failed interceptions will also be counted for Intercept_Times_Limit |
#------------------------------------------------------------------------------|
Count_Fail_Intercept = true
#------------------------------------------------------------------------------|
# * Intercept_MP_Limit, default = true |
# If Intercept_MP_Limit is true and the interceptors' MP will be greater |
# than their MMP after intercepting a skill, that skill can't be intercepted|
#------------------------------------------------------------------------------|
Intercept_MP_Limit = true
#------------------------------------------------------------------------------|
# * Intercept_TP_Limit, default = true |
# If Intercept_TP_Limit is true and the interceptors' TP will be greater |
# than their max TP value after intercepting a skill, that skill can't be |
# intercepted |
#------------------------------------------------------------------------------|
Intercept_TP_Limit = true
#------------------------------------------------------------------------------|
# * Intercept_Learnt_Skill, default = true |
# Battlers can only intercept skills that they're learnt |
#------------------------------------------------------------------------------|
Intercept_Learnt_Skill = true
#------------------------------------------------------------------------------|
# * Intercept_Usable_Skill, default = true |
# Battlers can only intercept skills that they can use at the moment |
#------------------------------------------------------------------------------|
Intercept_Usable_Skill = true
#------------------------------------------------------------------------------|
# * Intercept_Learn_Skill, default = false |
# Successful interceptions causes interceptors to learn intercepted skills |
#------------------------------------------------------------------------------|
Intercept_Learn_Skill = false
#------------------------------------------------------------------------------|
# * Intercept_MCR, default = true |
# The MP absorbed by the interceptor will be the actual MP used by the users|
# of the skills intercepted If Intercept_MCR is true |
#------------------------------------------------------------------------------|
Intercept_MCR = true
end # Intercept_Magic
end # DoubleX_RMVXA
#==============================================================================|
#==============================================================================|
# ** You need not edit this part as it's about how this script works |
#------------------------------------------------------------------------------|
class << DataManager
#----------------------------------------------------------------------------|
# Alias method: load_database |
#----------------------------------------------------------------------------|
alias load_database_intercept_magic load_database
def load_database
load_database_intercept_magic
# Added to load intercept magic notetags
load_notetags_intercept_magic
#
end # load_database
#----------------------------------------------------------------------------|
# New method: load_notetags_intercept_magic |
#----------------------------------------------------------------------------|
def load_notetags_intercept_magic
[$data_skills, $data_states].each { |data|
data.each { |obj| obj.load_notetags_intercept_magic if obj }
}
end # load_notetags_intercept_magic
end # DataManager
class RPG::BaseItem
#----------------------------------------------------------------------------|
# New public instance variables |
#----------------------------------------------------------------------------|
attr_accessor :intercept_tier
attr_accessor :intercept_mp
attr_accessor :intercept_tp
attr_accessor :hit_intercept_mp
attr_accessor :hit_intercept_tp
attr_accessor :battler_intercept
attr_accessor :intercept_chance
#----------------------------------------------------------------------------|
# New method: load_notetags_intercept_magic |
#----------------------------------------------------------------------------|
def load_notetags_intercept_magic
im = DoubleX_RMVXA::Intercept_Magic
@intercept_tier = 0
@intercept_chance =100
@battler_intercept = {}
@intercept_mp = @intercept_tp = false
@hit_intercept_mp = @hit_intercept_tp = false
@note.split(/[\r\n]+/).each { |line|
case line
when /<(?:INTERCEPT_TIER|intercept tier):[ ]*(\d+)>/i
@intercept_tier = $1.to_i if $1.to_i > @intercept_tier
when /<(?:INTERCEPT_MP|intercept mp)>/i
@intercept_mp ||= @intercept_tier > 0
when /<(?:INTERCEPT_TP|intercept tp)>/i
@intercept_tp ||= @intercept_tier > 0
when /<(?:HIT_INTERCEPT_MP|hit intercept mp)>/i
@hit_intercept_mp ||= im::Intercept_MP_Limit && @intercept_mp
when /<(?:HIT_INTERCEPT_TP|hit intercept tp)>/i
@hit_intercept_tp ||= im::Intercept_TP_Limit && @intercept_tp
when /<(?:ALLY_INTERCEPT|ally intercept)>/i
@battler_intercept[:ally] = true
when /<(?:ENEMY_INTERCEPT|enemy intercept)>/i
@battler_intercept[:enemy] = true
when /<(?:INTERCEPT_CHANCE|intercept chance):[ ]*(\d+)>/i
@intercept_chance = $1.to_i if $1.to_i < @intercept_chance
end
}
@intercept_chance /= 100.0
end # load_notetags_intercept_magic
end # RPG::BaseItem
module Vocab
InterceptMagic = "%s intercepts the skill!"
LearnInterceptMagic = "%s learns the intercepted skill!"
FailInterceptMagic = "%s fails to intercept the skill!"
end # Vocab
class Game_Temp
#----------------------------------------------------------------------------|
# New public instance variable |
#----------------------------------------------------------------------------|
attr_accessor :skill_interceptor
#----------------------------------------------------------------------------|
# (v1.03b+)Alias method: initialize |
#----------------------------------------------------------------------------|
alias initialize_intercept_magic initialize
def initialize
initialize_intercept_magic
# Added to initialize the array storing all skill interceptors
@skill_interceptor = []
#
end # initialize
#----------------------------------------------------------------------------|
# New method: intercept_order |
#----------------------------------------------------------------------------|
def intercept_order(subject)
@skill_interceptor.each_with_index { |battler, index|
return index + 1 if battler == subject
}
end # intercept_order
end # Game_Temp
class Game_Action
#----------------------------------------------------------------------------|
# (v1.02a+)New method: fail_intercept |
#----------------------------------------------------------------------------|
def fail_intercept(target)
return [target] if item.for_user?
return [target] * item.number_of_targets if item.for_random?
if item.for_one?
return [target] * (1 + (attack? ? subject.atk_times_add.to_i : 0))
end
return [target] * opponents_unit.alive_members.size if item.for_opponent?
return [target] * friends_unit.dead_members.size if item.for_dead_friend?
[target] * friends_unit.alive_members.size
end # fail_intercept
end # Game_Action
class Game_BattlerBase
#----------------------------------------------------------------------------|
# New public instance variables |
#----------------------------------------------------------------------------|
attr_accessor :intercept_order
attr_accessor :intercept_times
#----------------------------------------------------------------------------|
# (v1.03b+)Alias method: initialize |
#----------------------------------------------------------------------------|
alias initialize_intercept_magic initialize
def initialize
initialize_intercept_magic
# Added to initialize the order of this battler among all interceptors
@intercept_order = 0
#
end # initialize
#----------------------------------------------------------------------------|
# New method: intercept_magic |
#----------------------------------------------------------------------------|
def intercept_magic(notetag)
if @states
intercept_magic = notetag == :tier ? 0 : notetag == :key ? [] : false
@states.each { |state|
case notetag
when :tier
if $data_states[state].intercept_tier > intercept_magic
intercept_magic = $data_states[state].intercept_tier
end
when :key
$data_states[state].battler_intercept.each_key { |key|
intercept_magic.push(key) unless intercept_magic.include?(key)
}
when :mp
return true if $data_states[state].intercept_mp
when :tp
return true if $data_states[state].intercept_tp
when :hit_mp
return true if $data_states[state].hit_intercept_mp
when :hit_tp
return true if $data_states[state].hit_intercept_tp
when :chance
return true if rand < $data_states[state].intercept_chance
end
}
end
intercept_magic
end # intercept_magic
#----------------------------------------------------------------------------|
# New method: remove_intercept_states |
#----------------------------------------------------------------------------|
def remove_intercept_states
@states.delete_if { |state| $data_states[state].intercept_tier > 0 }
@intercept_times = 0
$game_temp.skill_interceptor.delete(self) if @intercept_order > 0
@intercept_order = 0
end # remove_intercept_states
#----------------------------------------------------------------------------|
# (v1.02a+)New method: intercept_mp_tp |
#----------------------------------------------------------------------------|
def intercept_mp_tp(notetag, item, user = nil)
if notetag == :mp
return item.mp_cost unless DoubleX_RMVXA::Intercept_Magic::Intercept_MCR
return (item.mp_cost * user.mcr).to_i
elsif notetag == :tp
return item.tp_cost
end
mmp > tp ? mmp + 1 : tp + 1
end # intercept_mp_tp
end # Game_BattlerBase
class Game_Battler < Game_BattlerBase
#----------------------------------------------------------------------------|
# Alias method: add_state |
#----------------------------------------------------------------------------|
alias add_state_intercept_magic add_state
def add_state(state_id)
add_state_intercept_magic(state_id)
# Added to set the intercept order
add_intercept_states(state_id) if $data_states[state_id].intercept_tier > 0
#
end # add_state
#----------------------------------------------------------------------------|
# (v1.02a+)New method: add_intercept_states |
#----------------------------------------------------------------------------|
def add_intercept_states(state_id)
if (interceptor = $game_temp.skill_interceptor).include?(self)
interceptor.delete(self)
end
interceptor << self
@intercept_order = $game_temp.intercept_order(self)
end # add_intercept_states
end # Game_Battler
class Game_Unit
#----------------------------------------------------------------------------|
# New method: intercept_magic |
#----------------------------------------------------------------------------|
def intercept_magic(user, item, key)
return nil unless is_a?(Game_Party) || is_a?(Game_Troop)
im = DoubleX_RMVXA::Intercept_Magic
intercept_member = nil
members.each { |member|
next if member.intercept_magic(:tier) < item.intercept_tier
next unless member.intercept_magic(:key).include?(key)
next if im::Intercept_MP_Limit && item.intercept_mp &&
member.intercept_magic(:mp) && (!item.hit_intercept_mp ||
!member.intercept_magic(:hit_mp)) &&
member.intercept_mp_tp(:mp, item, user) > member.mmp - member.mp
next if im::Intercept_TP_Limit && item.intercept_tp &&
member.intercept_magic(:tp) && (!item.hit_intercept_tp ||
!member.intercept_magic(:hit_tp)) &&
member.intercept_mp_tp(:tp, item) > member.max_tp - member.tp
next if im::Intercept_Learnt_Skill && member.actor? &&
!member.skill_learn?(item)
next if im::Intercept_Usable_Skill && !member.usable?(item)
next unless member.intercept_magic(:chance)
next if intercept_member &&
intercept_member.intercept_order >= member.intercept_order
intercept_member = member
}
intercept_member
end # intercept_magic
end # Game_Unit
class Window_BattleLog < Window_Selectable
#----------------------------------------------------------------------------|
# New method: display_intercept_item |
#----------------------------------------------------------------------------|
def display_intercept_item(target)
if (im = DoubleX_RMVXA::Intercept_Magic)::Intercept_SE
im::Intercept_SE.play
end
add_text(sprintf(Vocab::InterceptMagic, target.name))
end # display_intercept_item
#----------------------------------------------------------------------------|
# New method: display_learn_intercept_item |
#----------------------------------------------------------------------------|
def display_learn_intercept_item(target)
add_text(sprintf(Vocab::LearnInterceptMagic, target.name))
end # display_learn_intercept_item
#----------------------------------------------------------------------------|
# (v1.02a+)New method: display_fail_intercept_item |
#----------------------------------------------------------------------------|
def display_fail_intercept_item(target)
add_text(sprintf(Vocab::FailInterceptMagic, target.name))
end # display_fail_intercept_item
end # Window_BattleLog
class Scene_Battle < Scene_Base
#----------------------------------------------------------------------------|
# Alias method: use_item |
#----------------------------------------------------------------------------|
alias use_item_intercept_magic use_item
def use_item
# Rewritten to intercept magic when conditions are met
item = @subject.current_action.item
unless item.is_a?(RPG::Skill) && item.intercept_tier > 0
return use_item_intercept_magic
end
return use_item_intercept_magic unless rand < item.intercept_chance
interceptor = nil
item.battler_intercept.each_key { |key|
interceptor ||=
@subject.friends_unit.intercept_magic(@subject, item, key) if key == :ally
next if if key != :enemy
interceptor ||=
@subject.opponents_unit.intercept_magic(@subject, item, key)
}
interceptor ? intercept_magic(interceptor, item) : use_item_intercept_magic
#
end # use_item
#----------------------------------------------------------------------------|
# New method: intercept_magic |
#----------------------------------------------------------------------------|
def intercept_magic(target, item)
@log_window.display_use_item(@subject, item)
@subject.use_item(item)
refresh_status
target.intercept_times ||= 0
if item.hit_intercept_mp && target.intercept_magic(:hit_mp) &&
target.intercept_mp_tp(:mp, item, @subject) > target.mmp - target.mp ||
item.hit_intercept_tp && target.intercept_magic(:hit_tp) &&
target.intercept_mp_tp(:tp, item) > target.max_tp - target.tp
fail_intercept(target, item)
else
success_intercept(target, item)
end
if (im = DoubleX_RMVXA::Intercept_Magic)::Intercept_Times_Limit > 0 &&
target.intercept_times >= im::Intercept_Times_Limit
target.remove_intercept_states
end
refresh_status
end # intercept_magic
#----------------------------------------------------------------------------|
# (v1.02a+)New method: fail_intercept |
#----------------------------------------------------------------------------|
def fail_intercept(target, item)
@log_window.display_fail_intercept_item(target)
if DoubleX_RMVXA::Intercept_Magic::Count_Fail_Intercept
target.intercept_times += 1
end
targets = @subject.current_action.fail_intercept(target).compact
targets.each {|target| item.repeats.times { invoke_item(target, item) } }
end # fail_intercept
#----------------------------------------------------------------------------|
# (v1.02a+)New method: success_intercept |
#----------------------------------------------------------------------------|
def success_intercept(target, item)
im = DoubleX_RMVXA::Intercept_Magic
@log_window.display_intercept_item(target)
if im::Intercept_Animation_Id > 0 && im::Intercept_Animation_Id < 1000
show_animation([target], im::Intercept_Animation_Id)
end
target.intercept_times += 1
if item.intercept_mp && target.intercept_magic(:mp)
target.mp += target.intercept_mp_tp(:mp, item, @subject)
target.mp = target.mmp if target.mp > target.mmp
if item.intercept_tp && target.intercept_magic(:tp)
target.tp += target.intercept_mp_tp(:tp, item)
target.tp = target.max_tp if target.tp > target.max_tp
end
return unless im::Intercept_Learn_Skill
return unless target.actor? && target.skill_learn?(item)
target.learn_skill(item.id)
@log_window.display_learn_intercept_item(target)
end # success_intercept
end # Scene_Battle
#==============================================================================|
Instructions
Open the script editor and put this script into an open slot between Materials and Main. Save to take effect.
FAQ
None
Compatibility
Scripts aliasing or rewriting method:
- self.load_database under module DataManager
- add_state under class Game_Battler
- use_item under class Scene_Battle
may have compatibility issues with this script
Place this script above those aliasing any of these methods if possible
Credits and Thanks
None
Author's Notes
None
Terms and Conditions
None other than not claiming this script as created by anyone except DoubleX or his alias