#==============================================================================
# Add-On: Overdrive
# by Atoa
# Based on KCG's Overdrive
#==============================================================================
# This Add-On adds an Overdrive/Limit Break system to the game.
# It works like this:
# A new bar is created, and gets filled up by many different actions, easily
# defined by you. When full, you can use special skills that you couldn't before.
#==============================================================================
module N01
# Name of the Overdrive bar graphic file. Must be on the Graphic/Windowskins folder.
OVERDRIVE_METER = "ODMeter"
# Maximum value of the Overdrive Bar.
MAX_OVERDRIVE = 1000
# Overdrive gain ratio, change these values as you wish
OD_GAIN_RATE = [ 1000, 300, 100, 100, 200, 150, 100, 30, 50, 150, 100]
# [ A, B, C, D, E, F, G, H, I, J, K]
# A = Gain on attacking, varies depending on the amount of damage dealt
# B = Gain when attacked, varies depending on the amount of damage received
# C = Gain when attack is dodged
# D = Gain when an attack misses
# E = Gain when a battle is won
# F = Gain after fleeing a battle
# G = Gain on the beginning of a dead ally's turn
# H = Gain at the beginning of an alive ally's turn
# I = Fixed Gain at the beginning of the turn
# J = Gain at the beginning of the turn if the character is almost dead
# K = Gain if the character kills the target while attacking
# Here you must set up the character's IDs according to the form that they
# fill their OD meter. Only the character's that have their ID defined on a
# certain way will fill their OD Meter like that. Remember, to assign at least
# one kind of OD gain to each character, or it will never fill the OD meter.
# Ex.: DAMAGE_OD_PLUS = [4,5,8] Means that the characters 4, 5 e 8 will fill
# their OD meter when receiving damage from an enemy
# IDs of chars that gains OD:
ATTACK_OD_PLUS = [1,2] #when attacking
DAMAGE_OD_PLUS = [3,4] #when being attacked
EVADE_OD_PLUS = [3] #when dodgin an attack
MISS_OD_PLUS = [1] #when missing an attack
WIN_OD_PLUS = [1] #when a battle is won
ESCAPE_OD_PLUS = [4] #after a successful escape
DEAD_OD_PLUS = [3] #when a dead ally reaches his/her turn
ALIVE_OD_PLUS = [3,4] #when an alive ally begins his/her turn
TURN_OD_PLUS = [2,3] #fixed at the beginning of a turn
CRITICAL_OD_PLUS = [2,4] #when the character is on a critical state, near dead
KILL_OD_PLUS = [1,2] #when the character kills the target while attacking
# OD Meter position on the Battle Status Window
BATTLE_STYLE = 0
# 0 = Horizontal Pattern, not centralized
# 1 = Horizontal Pattern, centralized
# 2 = Vertical bars
# 3 = Custom Position
# Readjustment of the OD Meter's position on the Battle Status Window.
# On the right side, the default values are shown for when the meter is
# displayed Verticaly(Vert) and Horizontaly(Horz)
# feel ree to change these values at will
OD_X_POS = 0 #Default Value - Vert: 128| Horz: 0
OD_Y_POS = 112 #Default Value - Vert: 16 | Horz: 0
# Custom OD Bar position, only valid when BATTLE_STYLE = 3
OD_CUSTOM_POSITION = [[460,180],[480,210],[500,240],[520,270]]
# OD Meter position in main menu
MENU_STYLE = 1
# 0 = Don't show
# 1 = Above HP
# 2 = Bellow name
# 3 = Bellow level
end
#==============================================================================
# RPG::Skill
#==============================================================================
class RPG::Skill
#==============================================================================
# Add here the ID for the Overdrive Skill
#==============================================================================
alias extension_od_n01 extension
def extension
case @id
when 84 #Overdrive's Skill ID
return ["Magazine Discharge"]
#Add here the Overdrive Skills' IDs, remembering that the skill can have
#other extensions.
#when X (X = Skill's ID)
# return ["OVERDRIVE"]
end
extension_od_n01
end
end
#==============================================================================
# Game_Actor
#==============================================================================
class Game_Actor < Game_Battler
#--------------------------------------------------------------------------
include N01
#--------------------------------------------------------------------------
def max_overdrive
return MAX_OVERDRIVE
end
#--------------------------------------------------------------------------
def overdrive
return @overdrive == nil ? @overdrive = 0 : @overdrive
end
#--------------------------------------------------------------------------
def overdrive=(n)
@overdrive = [[n.to_i, 0].max, self.max_overdrive].min
end
#--------------------------------------------------------------------------
def overdrive_full?
return @overdrive == self.max_overdrive
end
#--------------------------------------------------------------------------
def overdrive_update
@overdrive = 0 if self.dead?
end
end
#==============================================================================
# Window_Base
#==============================================================================
class Window_Base < Window
#--------------------------------------------------------------------------
include N01
#--------------------------------------------------------------------------
def draw_actor_overdrive(actor, x, y)
@skin = RPG::Cache.windowskin(OVERDRIVE_METER)
@width = @skin.width
@height = @skin.height / 3
src_rect = Rect.new(0, 0, @width, @height)
self.contents.blt(x , y, @skin, src_rect)
@line = (actor.overdrive == actor.max_overdrive ? 2 : 1)
@amount = 100 * actor.overdrive / actor.max_overdrive
src_rect2 = Rect.new(0, @line * @height, @width * @amount / 100, @height)
self.contents.blt(x , y, @skin, src_rect2)
end
end
#==============================================================================
# Game_Battler
#==============================================================================
class Game_Battler
#--------------------------------------------------------------------------
alias skill_can_use_od_n01 skill_can_use?
def skill_can_use?(skill_id)
skill = $data_skills[skill_id]
if self.is_a?(Game_Actor) && skill != nil && skill.extension.include?("OVERDRIVE")
return false unless self.overdrive_full?
end
skill_can_use_od_n01(skill_id)
end
#--------------------------------------------------------------------------
alias attack_effect_od_n01 attack_effect
def attack_effect(attacker)
result = attack_effect_od_n01(attacker)
if result && self.damage.is_a?(Numeric)
if attacker.is_a?(Game_Actor) && self.is_a?(Game_Enemy) &&
ATTACK_OD_PLUS.include?(attacker.id) && self.damage > 0
od_up = [self.damage * OD_GAIN_RATE[0] / (attacker.level + 10) / 50, 10].max
attacker.overdrive += od_up
attacker.overdrive += OD_GAIN_RATE[10] if self.hp <= 0 and KILL_OD_PLUS.include?(attacker.id)
elsif attacker.is_a?(Game_Enemy) && self.is_a?(Game_Actor) &&
DAMAGE_OD_PLUS.include?(self.id) && self.damage > 0
od_up = [self.damage * OD_GAIN_RATE[1] / self.maxhp, 1].max
self.overdrive += od_up
end
end
if @missed or @evaded
if attacker.is_a?(Game_Actor) && self.is_a?(Game_Enemy) &&
MISS_OD_PLUS.include?(attacker.id)
attacker.overdrive += OD_GAIN_RATE[3]
elsif attacker.is_a?(Game_Enemy) && self.is_a?(Game_Actor) &&
EVADE_OD_PLUS.include?(self.id)
self.overdrive += OD_GAIN_RATE[2]
end
end
return result
end
#--------------------------------------------------------------------------
alias skill_effect_od_n01 skill_effect
def skill_effect(user, skill)
@base_damage = nil
result = skill_effect_od_n01(user, skill)
if result && self.damage.is_a?(Numeric)
if user.is_a?(Game_Actor) && self.is_a?(Game_Enemy) &&
ATTACK_OD_PLUS.include?(user.id) && self.damage > 0
od_up = [self.damage * OD_GAIN_RATE[0] / (user.level + 10) / 50, 10].max
user.overdrive += od_up
user.overdrive += OD_GAIN_RATE[10] if self.hp <= 0 and KILL_OD_PLUS.include?(user.id)
elsif user.is_a?(Game_Enemy) && self.is_a?(Game_Actor) &&
DAMAGE_OD_PLUS.include?(self.id) && self.damage > 0
od_up = [self.damage * OD_GAIN_RATE[1] / self.maxhp, 1].max
self.overdrive += od_up
end
end
if @missed or @evaded
if user.is_a?(Game_Actor) && self.is_a?(Game_Enemy) &&
MISS_OD_PLUS.include?(user.id)
user.overdrive += OD_GAIN_RATE[3]
elsif user.is_a?(Game_Enemy) && self.is_a?(Game_Actor) &&
EVADE_OD_PLUS.include?(self.id)
self.overdrive += OD_GAIN_RATE[2]
end
end
return result
end
#--------------------------------------------------------------------------
alias perfetc_attack_effect_od_n01 attack_effect
def perfetc_attack_effect(attacker)
@overdrive_plus = nil
result = perfetc_attack_effect_od_n01(attacker)
if result && self.damage.is_a?(Numeric)
if attacker.is_a?(Game_Actor) && self.is_a?(Game_Enemy) &&
ATTACK_OD_PLUS.include?(attacker.id) && self.damage > 0
od_up = [self.damage * OD_GAIN_RATE[0] / (attacker.level + 10) / 50, 10].max
attacker.overdrive += od_up
attacker.overdrive += OD_GAIN_RATE[10] if self.hp <= 0 and KILL_OD_PLUS.include?(attacker.id)
elsif attacker.is_a?(Game_Enemy) && self.is_a?(Game_Actor) &&
DAMAGE_OD_PLUS.include?(self.id) && self.damage > 0
od_up = [self.damage * OD_GAIN_RATE[1] / self.maxhp, 1].max
self.overdrive += od_up
end
end
return result
end
#--------------------------------------------------------------------------
alias perfetc_skill_effect_od_n01 skill_effect
def perfetc_skill_effect(user, skill)
@base_damage = nil
result = perfetc_skill_effect_od_n01(user, skill)
if result && self.damage.is_a?(Numeric)
if user.is_a?(Game_Actor) && self.is_a?(Game_Enemy) &&
ATTACK_OD_PLUS.include?(user.id) && self.damage > 0
od_up = [self.damage * OD_GAIN_RATE[0] / (user.level + 10) / 50, 10].max
user.overdrive += od_up
user.overdrive += OD_GAIN_RATE[10] if self.hp <= 0 and KILL_OD_PLUS.include?(user.id)
elsif user.is_a?(Game_Enemy) && self.is_a?(Game_Actor) &&
DAMAGE_OD_PLUS.include?(self.id) && self.damage > 0
od_up = [self.damage * OD_GAIN_RATE[1] / self.maxhp, 1].max
self.overdrive += od_up
end
end
return result
end
end
#==============================================================================
# ■ Window_Skill
#==============================================================================
class Window_Skill < Window_Selectable
#--------------------------------------------------------------------------
def draw_item(index)
skill = @data[index]
if @actor.skill_can_use?(skill.id)
self.contents.font.color = normal_color
self.contents.font.color = crisis_color if skill.extension.include?("OVERDRIVE")
else
self.contents.font.color = disabled_color
end
x = 4 + index % 2 * (288 + 32)
y = index / 2 * 32
rect = Rect.new(x, y, self.width / @column_max - 32, 32)
self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
bitmap = RPG::Cache.icon(skill.icon_name)
opacity = self.contents.font.color == disabled_color ? 128 : 255
self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity)
self.contents.draw_text(x + 28, y, 204, 32, skill.name, 0)
cost = @actor.calc_sp_cost(@actor, skill)
self.contents.draw_text(x + 232, y, 48, 32, cost.to_s, 2)
end
end
#==============================================================================
# Window_BattleStatus
#==============================================================================
class Window_BattleStatus < Window_Base
#--------------------------------------------------------------------------
alias refresh_od_n01 refresh
#--------------------------------------------------------------------------
def refresh
refresh_od_n01
for i in 0...$game_party.actors.size
actor = $game_party.actors[i]
case BATTLE_STYLE
when 0
meter_x = i * (624 / MAX_MEMBER) + OD_X_POS
meter_y = OD_Y_POS
when 1
meter_x = OD_X_POS + ((624 / MAX_MEMBER) * ((MAX_MEMBER - $game_party.actors.size)/2.0 + i)).floor
meter_y = OD_Y_POS
when 2
meter_x = OD_X_POS
meter_y = i * 32 + OD_Y_POS
when 3
meter_x = OD_CUSTOM_POSITION[i][0]
meter_y = OD_CUSTOM_POSITION[i][1]
end
draw_actor_overdrive(actor, meter_x, meter_y)
end
end
end
#==============================================================================
# Window_MenuStatus
#==============================================================================
class Window_MenuStatus < Window_Selectable
#--------------------------------------------------------------------------
alias refresh_od_n01 refresh
#--------------------------------------------------------------------------
def refresh
refresh_od_n01
for i in 0...$game_party.actors.size
actor = $game_party.actors[i]
x = 64
y = i * 116
draw_actor_overdrive(actor, x + 236, y + 12) if MENU_STYLE == 1
draw_actor_overdrive(actor, x + 4, y + 24) if MENU_STYLE == 2
draw_actor_overdrive(actor, x + 4, y + 56) if MENU_STYLE == 3
end
end
end
#==============================================================================
# Window_Status
#==============================================================================
class Window_Status < Window_Base
#--------------------------------------------------------------------------
alias refresh_od_n01 refresh
#--------------------------------------------------------------------------
def refresh
refresh_od_n01
draw_actor_overdrive(@actor, 96, 96) if MENU_STYLE != 0
end
end
#==============================================================================
# Scene_Battle
#==============================================================================
class Scene_Battle
#--------------------------------------------------------------------------
include N01
#--------------------------------------------------------------------------
alias battle_end_od_n01 battle_end
def battle_end(result)
case result
when 0
for actor in $game_party.actors
next unless actor.exist?
if WIN_OD_PLUS.include?(actor.id)
actor.overdrive += OD_GAIN_RATE[4]
end
end
when 1
for actor in $game_party.actors
next unless actor.exist?
if ESCAPE_OD_PLUS.include?(actor.id)
actor.overdrive += OD_GAIN_RATE[5]
end
end
end
@status_window.refresh
battle_end_od_n01(result)
end
#--------------------------------------------------------------------------
alias update_phase4_step2_KGC_OverDrive update_phase4_step2
def update_phase4_step2
if @active_battler.is_a?(Game_Actor)
od_up = 0
for actor in $game_party.actors
od_up += OD_GAIN_RATE[6] if DEAD_OD_PLUS.include?(@active_battler.id) and actor.dead?
od_up += OD_GAIN_RATE[7] if DEAD_OD_PLUS.include?(@active_battler.id) and !actor.dead?
end
if TURN_OD_PLUS.include?(@active_battler.id)
od_up += OD_GAIN_RATE[8]
end
if CRITICAL_OD_PLUS.include?(@active_battler.id)
od_up += @active_battler.hp <= @active_battler.maxhp / 4 ? OD_GAIN_RATE[9] : 0
end
@active_battler.overdrive += od_up
end
@status_window.refresh
update_phase4_step2_KGC_OverDrive
end
#--------------------------------------------------------------------------
alias make_skill_action_result_KGC_OverDrive make_skill_action_result
def make_skill_action_result
make_skill_action_result_KGC_OverDrive
if @active_battler.is_a?(Game_Actor) && @skill.extension.include?("OVERDRIVE")
@active_battler.overdrive = 0
end
@status_window.refresh
end
#--------------------------------------------------------------------------
alias update_phase4_step6_od_n01 update_phase4_step6
def update_phase4_step6
update_phase4_step6_od_n01
for actor in $game_party.actors
actor.overdrive_update
end
@status_window.refresh
end
end
#==============================================================================
# Scene_Skill
#==============================================================================
class Scene_Skill
#--------------------------------------------------------------------------
alias update_skill_od_n01 update_skill
#--------------------------------------------------------------------------
def update_skill
if Input.trigger?(Input::C)
unless @skill == nil or not @actor.skill_can_use?(@skill.id) or @skill.scope >= 3
@actor.overdrive = 0 if @skill.extension.include?("OVERDRIVE")
end
end
update_skill_od_n01
end
#--------------------------------------------------------------------------
def update_target
if Input.trigger?(Input::B)
$game_system.se_play($data_system.cancel_se)
@skill_window.active = true
@target_window.visible = false
@target_window.active = false
return
end
if Input.trigger?(Input::C)
unless @actor.skill_can_use?(@skill.id)
$game_system.se_play($data_system.buzzer_se)
return
end
if @target_window.index == -1
used = false
for i in $game_party.actors
used |= i.skill_effect(@actor, @skill)
end
end
if @target_window.index <= -2
target = $game_party.actors[@target_window.index + 10]
used = target.skill_effect(@actor, @skill)
end
if @target_window.index >= 0
target = $game_party.actors[@target_window.index]
used = target.skill_effect(@actor, @skill)
end
if used
$game_system.se_play(@skill.menu_se)
@actor.overdrive = 0 if @skill.extension.include?("OVERDRIVE")
@actor.sp -= @skill.sp_cost
@status_window.refresh
@skill_window.refresh
@target_window.refresh
if $game_party.all_dead?
$scene = Scene_Gameover.new
return
end
if @skill.common_event_id > 0
$game_temp.common_event_id = @skill.common_event_id
$scene = Scene_Map.new
return
end
end
unless used
$game_system.se_play($data_system.buzzer_se)
end
return
end
end
end