Neo-Bahamut
Member
Improved Battle Codeby Neo-Bahamut aka Wurstinator
Hi
This is my "Improved Battle Code" script. It's a rewrite of most methods of the classes Game_Battler, Game_Actor, Game_Enemy, Game_BattleAction, Game_Party and Game_Troop. When you use it itself, without other battle addons or battle systems, you won't notice it.
It's only useful if your project has an ATB system or a well written ABS. It works like an Antilag script - just for battles
Actually, this script is pretty useless for everyone who isn't planning to write some battle addon script :D
Screenshots
Nothing to see here, move on.
Code
Bugs and other insects
My script should work with the SDK.
I didn't test it much, so if someone uses this and finds a bug, contact me so I can repair it.
Hi
This is my "Improved Battle Code" script. It's a rewrite of most methods of the classes Game_Battler, Game_Actor, Game_Enemy, Game_BattleAction, Game_Party and Game_Troop. When you use it itself, without other battle addons or battle systems, you won't notice it.
It's only useful if your project has an ATB system or a well written ABS. It works like an Antilag script - just for battles
Actually, this script is pretty useless for everyone who isn't planning to write some battle addon script :D
Screenshots
Nothing to see here, move on.
Code
Ruby:
# Improved Battle Code
# Version 1.0
# 08.07.2010 (DD.MM.YYYY)
# by Neo-Bahamut aka Wurstinator
#
# This script is a rewrite of most methods in the classes Game_Battler,
# Game_Actor, Game_Enemy, Game_BattleAction, Game_Party and Game_Troop.
# It runs "a lot" faster now which means about 0.0001 seconds per call :D
if defined?(SDK)
class Game_Battler
def attack_effect_base_damage(attacker)
atk = Math.max(attacker.atk - self.pdef / 2, 0)
self.damage = atk * (20 + attacker.str) / 20
end
def attack_effect_element_correction(attacker)
self.damage = self.damage * elements_correct(attacker.element_set) / 100
end
def attack_effect_dispersion
if self.damage.abs > 0
amp = Math.max(self.damage.abs * 15 / 100, 1)
self.damage += rand(amp+1) + rand(amp+1) - amp
end
end
def attack_effect_second_hit_result(attacker)
eva = 8 * self.agi / attacker.dex + self.eva
hit = self.cant_evade? ? 100 : self.damage < 0 ? 100 : 100 - eva
return (rand(100) < hit)
end
def skill_effect_effective_setup(skill)
effective = (skill.common_event_id > 0)
effective = false
return effective |= skill.common_event_id > 0
end
def skill_effect_power(user, skill)
power = skill.power + user.atk * skill.atk_f / 100
if power > 0
power -= (self.pdef * skill.pdef_f / 200) + (self.mdef * skill.mdef_f / 200)
power = 0 if power < 0
end
return power
end
def skill_effect_disperation(skill)
if skill.variance > 0 and self.damage.abs > 0
amp = Math.max(self.damage.abs * skill.variance / 100, 1)
self.damage += rand(amp+1) + rand(amp+1) - amp
end
end
def item_effect_effective_setup(item)
effective = (item.common_event_id > 0)
end
def item_effect_recovery(item)
recover_hp = maxhp * item.recover_hp_rate / 100 + item.recover_hp
recover_sp = maxsp * item.recover_sp_rate / 100 + item.recover_sp
if recover_hp < 0
recover_hp += (self.pdef * item.pdef_f / 20) + (self.mdef * item.mdef_f / 20)
recover_hp = 0 if recover_hp < 0
end
return recover_hp, recover_sp
end
def item_effect_dispersion(recover_hp, recover_sp, item)
if item.variance > 0 and recover_hp.abs > 0
amp = Math.max(recover_hp.abs * item.variance / 100, 1)
recover_hp += rand(amp+1) + rand(amp+1) - amp
end
if item.variance > 0 and recover_sp.abs > 0
amp = Math.max(recover_sp.abs * item.variance / 100, 1)
recover_sp += rand(amp+1) + rand(amp+1) - amp
end
return recover_hp, recover_sp
end
def slip_damage_effect_dispersion
if self.damage.abs > 0
amp = Math.max(self.damage.abs * 15 / 100, 1)
self.damage += rand(amp+1) + rand(amp+1) - amp
end
end
end
end
if !defined?(SDK)
class Game_Battler
def attack_effect(attacker)
self.critical = false
hit_result = (rand(100) < attacker.hit)
if hit_result
atk = Math.max(attacker.atk - self.pdef / 2, 0)
dmg = atk * (20 + attacker.str) / 20
dmg = dmg * elements_correct(attacker.element_set) / 100
if dmg > 0
if rand(100) < 4 * attacker.dex / self.agi
dmg *= 2
self.critical = true
end
dmg /= 2 if self.guarding?
end
if dmg.abs > 0
amp = Math.max(dmg.abs * 15 / 100, 1)
dmg += rand(amp + 1) + rand(amp + 1) - amp
end
eva = 8 * self.agi / attacker.dex + self.eva
hit = (self.cant_evade? or dmg < 0) ? 100 : 100-eva
self.damage = dmg
if rand(100) < hit
remove_states_shock
self.hp -= self.damage
@state_changed = false
states_plus(attacker.plus_state_set)
states_minus(attacker.minus_state_set)
else
self.damage = 'Miss'
self.critical = false
end
end
return true
end
def skill_effect(user, skill)
self.critical = false
if ((skill.scope == 3 or skill.scope == 4) and self.hp == 0) or
((skill.scope == 5 or skill.scope == 6) and self.hp >= 1)
return false
end
hit = skill.hit
hit *= user.hit / 100 if skill.atk_f > 0
hit_result = (rand(100) < hit)
effective = (hit < 100 or skill.common_event_id > 0)
if hit_result
power = skill.power + user.atk * skill.atk_f / 100
if power > 0
power = Math.max(0, power - self.pdef*skill.pdef_f/200 - self.mdef*skill.mdef_f/200)
end
rate = 20 + (user.str * skill.str_f + user.dex * skill.dex_f +
user.agi * skill.agi_f + user.int * skill.int_f) / 100
dmg = power * rate / 20
dmg = dmg * elements_correct(skill.element_set) / 100
if dmg > 0 and self.guarding?
dmg /= 2
end
if skill.variance > 0 and dmg.abs > 0
amp = Math.max(dmg.abs * skill.variance / 100, 1)
dmg += rand(amp + 1) + rand(amp + 1) - amp
end
eva = 8 * self.agi / user.dex + self.eva
hit = (self.cant_evade? or dmg < 0) ? 100 : 100-(eva*skill.eva_f/100)
effective |= (hit < 100)
self.damage = dmg
if rand(100) < hit
if skill.power != 0 and skill.atk_f > 0
remove_states_shock
effective = true
end
last_hp = self.hp
self.hp -= self.damage
effective |= (self.hp != last_hp)
@state_changed = false
effective |= states_plus(skill.plus_state_set)
effective |= states_minus(skill.minus_state_set)
if skill.power == 0
self.damage = @state_changed ? '' : 'Miss'
end
else
self.damage = 'Miss'
end
end
self.damage = nil if !$game_temp.in_battle
return effective
end
def item_effect(item)
self.critical = false
if ((item.scope == 3 or item.scope == 4) and self.hp == 0) or
((item.scope == 5 or item.scope == 6) and self.hp >= 1)
return false
end
hit_result = (rand(100) < item.hit)
effective = (item.hit < 100 or item.common_event_id > 0)
if hit_result
recover_hp = maxhp * item.recover_hp_rate / 100 + item.recover_hp
recover_sp = maxsp * item.recover_sp_rate / 100 + item.recover_sp
if recover_hp < 0
recover_hp = Math.max(0, power - self.pdef*item.pdef_f/200 - self.mdef*item.mdef_f/200)
end
recover_hp = recover_hp * elements_correct(item.element_set) / 100
recover_sp = recover_sp * elements_correct(item.element_set) / 100
if item.variance > 0
if recover_hp.abs > 0
amp = Math.max(recover_hp.abs * item.variance / 100, 1)
recover_hp += rand(amp + 1) + rand(amp + 1) - amp
end
if recover_sp.abs > 0
amp = Math.max(recover_sp.abs * item.variance / 100, 1)
recover_sp += rand(amp + 1) + rand(amp + 1) - amp
end
end
if recover_hp < 0 and self.guarding?
recover_hp /= 2
end
self.damage = -recover_hp
last_hp, last_sp = self.hp, self.sp
self.hp += recover_hp
self.sp += recover_sp
effective |= (self.hp != last_hp or self.sp != last_sp)
if item_parameter_type > 0 and item.parameter_points != 0
case item.parameter_type
when 1 then @maxhp_plus += item.parameter_points
when 2 then @maxsp_plus += item.parameter_points
when 3 then @str_plus += item.parameter_points
when 4 then @dex_plus += item.parameter_points
when 5 then @agi_plus += item.parameter_points
when 6 then @int_plus += item.parameter_points
end
effective = true
end
if item.recover_hp_rate == 0 and item.recover_hp == 0
if item.recover_sp_rate == 0 and item.recover_sp == 0 and
(item.parameter_type == 0 or item.parameter_points == 0) and !@state_changed
self.damage = 'Miss'
else
self.damage = ''
end
end
else
self.damage = 'Miss'
end
self.damage = nil if !$game_temp.in_battle
return effective
end
def slip_damage_effect
dmg = self.maxhp / 10
if dmg.abs > 0
amp = Math.max(dmg.abs * 15 / 100, 1)
dmg += rand(amp + 1) + rand(amp + 1) - amp
end
self.damage = dmg
self.hp -= self.damage
return true
end
end
end
if !defined?(SDK)
class Game_Actor
def exp=(exp)
@exp = Math.max(Math.min(exp, 9999999), 0)
learnings = $data_classes[@class_id].learnings
while @exp >= @exp_list[@level + 1] and @exp_list[@level + 1] > 0
@level += 1
learnings.each do |l|
learn_skill(l.skill_id) if l.level == @level
end
end
while @exp < @exp_list[@level]
@level -= 1
end
@hp = Math.min(self.maxhp, @hp)
@sp = Math.min(self.maxsp, @sp)
end
end
end
module Math
def Math.max(a, b)
a < b ? b : a
end
def Math.min(a, b)
a < b ? a : b
end
end
class Game_Battler
States_Plus_Array = [0, 100, 80, 60, 40, 20, 0]
end
class Game_Actor
Element_Rate_Table = [0, 200, 150, 100, 50, 0, -100]
end
class Game_Enemy
Element_Rate_Table = [0, 200, 150, 100, 50, 0, -100]
end
class Game_Party
CheckMapSlipDamageFlashColor = Color.new(255, 0, 0, 128)
end
class Game_Battler
def each_state(&block)
@states.each do |id|
yield $data_states[id]
end
end
def maxhp
n = Math.max(Math.min(@maxhp_plus + base_maxhp, 999999), 1)
each_state do |i|
n *= i.maxhp_rate / 100.0
end
n = Math.max(Math.min(Integer(n), 999999), 1)
return n
end
def maxsp
n = Math.max(Math.min(@maxsp_plus + base_maxsp, 9999), 1)
each_state do |i|
n *= i.maxsp_rate / 100.0
end
n = Math.max(Math.min(Integer(n), 9999), 1)
return n
end
def str
n = Math.max(Math.min(@str_plus + base_str, 999), 1)
each_state do |i|
n *= i.str_rate / 100.0
end
n = Math.max(Math.min(Integer(n), 999), 1)
return n
end
def dex
n = Math.max(Math.min(@dex_plus + base_dex, 999), 1)
each_state do |i|
n *= i.dex_rate / 100.0
end
n = Math.max(Math.min(Integer(n), 999) ,1)
return n
end
def agi
n = Math.max(Math.min(@agi_plus + base_agi, 999), 1)
each_state do |i|
n *= i.agi_rate / 100.0
end
n = Math.max(Math.min(Integer(n), 999), 1)
return n
end
def int
n = Math.max(Math.min(@int_plus + base_int, 999), 1)
each_state do |i|
n *= i.int_rate / 100.0
end
n = Math.max(Math.min(Integer(n), 999), 1)
return n
end
def maxhp=(maxhp)
@maxhp_plus = Math.max(Math.min(@maxhp_plus + maxhp - self.maxhp, 9999), -9999)
@hp = Math.min(@hp, self.maxhp)
end
def maxsp=(maxsp)
@maxsp_plus = Math.max(Math.min(@maxsp_plus + maxsp - self.maxsp, 9999), -9999)
@sp = Math.min(@sp, self.maxsp)
end
def str=(str)
@str_plus = Math.max(Math.min(@str_plus + str - self.str, 999), -999)
end
def dex=(dex)
@dex_plus = Math.max(Math.min(@dex_plus + dex - self.dex, 999), -999)
end
def agi=(agi)
@agi_plus = Math.max(Math.min(@agi_plus + agi - self.agi, 999), -999)
end
def int=(int)
@int_plus = Math.max(Math.min(@int_plus + int - self.int, 999), -999)
end
def hit
n = 100
each_state do |i|
n *= i.hit_rate / 100.0
end
return Integer(n)
end
def atk
n = base_atk
each_state do |i|
n *= i.atk_rate / 100.0
end
return Integer(n)
end
def pdef
n = base_pdef
each_state do |i|
n *= i.pdef_rate / 100.0
end
return Integer(n)
end
def mdef
n = base_mdef
each_state do |i|
n *= i.mdef_rate / 100.0
end
return Integer(n)
end
def eva
n = base_eva
each_state do |i|
n *= i.eva / 100.0
end
return Integer(n)
end
def hp=(hp)
before_dead = dead?
@hp = Math.max(Math.min(hp, self.maxhp), 0)
if before_dead and !dead?
@states.each do |i|
if $data_states[i].zero_hp
remove_state(i)
end
end
elsif !before_dead and dead?
1.upto($data_states.size - 1) do |i|
if $data_states[i].zero_hp
add_state(i)
end
end
end
end
def sp=(sp)
@sp = Math.max(Math.min(sp, self.maxsp), 0)
end
def recover_all
@hp, @sp = self.maxhp, self.maxsp
@states.size.times {remove_state(@states[0])}
end
def make_action_speed
@current_action.speed = get_action_speed
end
def get_action_speed
agility = self.agi
agility + rand(10 + agility / 4)
end
def add_state(state_id, force = false)
return if $data_states[state_id].nil?
if !force
return if @states.any? do |id|
mss = $data_states[id].minus_state_set
mss.include?(state_id) and !mss.include?(id)
end
end
if !state?(state_id)
@states.push(state_id)
self.hp = 0 if $data_states[state_id].zero_hp
@states.sort! do |a, b|
sa, sb = $data_states[a], $data_states[b]
if sa.rating > sb.rating then -1
elsif sa.rating < sb.rating then 1
elsif sa.restriction > sb.restriction then -1
elsif sa.restriction < sb.restriction then 1
else a <=> b end
end
end
@states_turn[state_id] = -1 if force
@states_turn[state_id] = $data_states[state_id].hold_turn if @states_turn[state_id] == -1
@current_action.clear if movable?
@hp = Math.min(self.maxhp, @hp)
@sp = Math.min(self.maxsp, @sp)
end
def remove_state(state_id, force = false)
return if !state?(state_id)
return if @states_turn[state_id] == -1 and !force
if @hp == 0 and $data_states[state_id].zero_hp
if !@states.any? {|id| id != state_id and $data_states[id].zero_hp}
@hp = 1
end
end
@states.delete(state_id)
@states_turn.delete(state_id)
@hp = Math.min(self.maxhp, @hp)
@sp = Math.min(self.maxsp, @sp)
end
def state_animation_id
return 0 if @states.empty?
return $data_states[@states[0]].animation_id
end
def restriction
return 0 if @states.empty?
$data_states[@states.sort {|a, b| $data_states[a].restriction <=> $data_states[b].restriction}[0]].restriction
end
def cant_get_exp?
@states.any? {|i| $data_states[i].cant_get_exp}
end
def cant_evade?
@states.any? {|i| $data_states[i].cant_evade}
end
def slip_damage?
@states.any? {|i| $data_states[i].slip_damage}
end
def remove_states_battle
n = 0
@states.size.times do
if $data_states[@states[n]].battle_only
remove_state(@states[n])
else
n += 1
end
end
end
def remove_states_auto
n = 0
@states.size.times do
m = @states[n]
if @states_turn[m] != nil and @states_turn[m] > 0
@states_turn[m] -= 1
n += 1
elsif rand(100) < $data_states[m].auto_release_prob
remove_state(m)
else
n += 1
end
end
end
def remove_states_shock
n = 0
@states.size.times do
if rand(100) < $data_states[@states[n]].shock_release_prob
remove_state(@states[n])
else
n += 1
end
end
end
def states_plus(plus_state_set)
effective = false
plus_state_set.each do |i|
next if self.state_guard?(i)
effective |= !self.state_full?(i)
if $data_states[i].nonresistance
@state_changed = true
add_state(i)
elsif !self.state_full?(i)
if rand(100) < States_Plus_Array[self.state_ranks[i]]
@state_changed = true
add_state(i)
end
end
end
return effective
end
def states_minus(minus_state_set)
effective = false
minus_state_set.each do |i|
effective |= self.state?(i)
@state_changed = true
remove_state(i)
end
return effective
end
def skill_can_use?(skill_id)
if ($data_skills[skill_id].sp_cost > self.sp) or
($data_skills[skill_id].atk_f == 0 and self.restriction == 1) or
(dead?)
return false
end
occasion = $data_skills[skill_id].occasion
if $game_temp.in_battle
return (occasion == 0 or occasion == 1)
else
return (occasion == 0 or occasion == 2)
end
end
def elements_correct(element_set)
return 100 if element_set.empty?
weakest = -100
element_set.each do |id|
weakest = Math.max(weakest, self.element_rate(id))
end
return weakest
end
end
class Game_BattleAction
def valid?
@kind != 0 or @basic != 3
end
def for_one_friend?
skill, item = $data_skills[@skill_id], $data_items[@item_id]
sscope = skill.nil? ? 0 : skill.scope
iscope = item.nil? ? 0 : item.scope
return( (@kind == 1 and (sscope == 3 or sscope == 5)) or
(@kind == 2 and (iscope == 3 or iscope == 5)) )
end
def for_one_friend_hp0?
return( (@kind == 1 and $data_skills[@skill_id].scope == 5) or
(@kind == 2 and $data_items[@item_id].scope == 5) )
end
end
class Game_Actor
def each_armor(&block)
yield $data_armors[@armor1_id]
yield $data_armors[@armor2_id]
yield $data_armors[@armor3_id]
yield $data_armors[@armor4_id]
end
def each_armor_id(&block)
yield @armor1_id
yield @armor2_id
yield @armor3_id
yield @armor4_id
end
def each_equipment(&block)
yield $data_weapons[@weapon_id]
yield $data_armors[@armor1_id]
yield $data_armors[@armor2_id]
yield $data_armors[@armor3_id]
yield $data_armors[@armor4_id]
end
def make_exp_list
actor = $data_actors[@actor_id]
@exp_list[1] = 0
pow_i = 2.4 + actor.exp_inflation / 100.0
2.upto(100) do |n|
if n > actor.final_level
@exp_list[n] = 0
else
m = actor.exp_basis * ((n+3) ** pow_i) / (5**pow_i)
@exp_list[n] = @exp_list[n-1] + Integer(m)
end
end
end
def element_rate(element_id)
result = Element_Rate_Table[$data_classes[@class_id].element_ranks[element_id]]
each_armor do |i|
if !i.nil? and i.guard_element_set.include?(element_id)
result /= 2
end
end
each_state do |i|
result /= 2 if i.guard_element_set.include?(element_id)
end
return result
end
def state_guard?(state_id)
each_armor do |i|
if !i.nil? and i.guard_state_set.include?(state_id)
return true
end
end
return false
end
def element_set
weapon = $data_weapons[@weapon_id]
return weapon.nil? ? Empty_Array_Set : weapon.element_set
end
def maxhp
n = Math.max(Math.min(base_maxhp + @maxhp_plus, 9999), 1)
each_state do |i|
n *= i.maxhp_rate / 100.0
end
return Math.max(Math.min(Integer(n), 9999), 1)
end
def base_str
n = $data_actors[@actor_id].parameters[2, @level]
each_equipment do |i|
n += i.str_plus if !i.nil?
end
return Math.max(Math.min(n, 999), 1)
end
def base_dex
n = $data_actors[@actor_id].parameters[3, @level]
each_equipment do |i|
n += i.dex_plus if !i.nil?
end
return Math.max(Math.min(n, 999), 1)
end
def base_agi
n = $data_actors[@actor_id].parameters[4, @level]
each_equipment do |i|
n += i.agi_plus if !i.nil?
end
return Math.max(Math.min(n, 999), 1)
end
def base_int
n = $data_actors[@actor_id].parameters[5, @level]
each_equipment do |i|
n += i.int_plus if !i.nil?
end
return Math.max(Math.min(n, 999), 1)
end
def level=(level)
self.exp = @exp_list[Math.max(Math.min($data_actors[@actor_id].final_level, level), 1)]
end
end
class Game_Enemy < Game_Battler
def element_rate(element_id)
result = Element_Rate_Table[$data_enemies[@enemy_id].element_ranks[element_id]]
each_state do |i|
result /= 2 if i.guard_element_set.include?(element_id)
end
return result
end
end
class Game_Party
def refresh
@actors.collect! do |i|
$data_actors[i.id]
end.compact!
end
def max_level
return 0 if @actors.empty?
@actors.sort {|a, b| a.level <=> b.level}[0].level
end
def gain_gold(n)
@gold = Math.max(Math.min(@gold + n, 9999999), 0)
end
def increase_steps
@steps = Math.min(9999999, @steps + 1)
end
def gain_item(item_id, n)
return if item_id == 0
@items[item_id] = Math.max(Math.min(item_number(item_id) + n, 99), 0)
end
def gain_weapon(weapon_id, n)
return if weapon_id == 0
@weapons[weapon_id] = Math.max(Math.min(weapon_number(weapon_id) + n, 99), 0)
end
def gain_armor(armor_id, n)
return if armor_id == 0
@armors[armor_id] = Math.max(Math.min(armor_number(armor_id) + n, 99), 0)
end
def item_can_use?(item_id)
return false if item_number(item_id) == 0
occasion = $data_items[item_id].occasion
occasion == 0 or (occasion == ($game_temp.in_battle ? 1 : 2))
end
def inputable?
@actors.any? {|i| i.inputable?}
end
def all_dead?
return false if actors.empty?
return true if actors.all? {|i| i.hp < 1}
return false
end
def check_map_slip_damage
@actors.each do |i|
next if i.hp < 1 or !i.slip_damage?
actor.hp -= Math.max(1, actor.maxhp / 100)
if actor.hp == 0
$game_system.se_play($data_system.actor_collapse_se)
end
$game_screen.start_flash(CheckMapSlipDamageFlashColor, 4)
$game_temp.gameover = all_dead?
end
end
def random_target_actor_base(&condition)
roulette = []
@actors.each do |i|
next if !yield(i)
(4 - $data_classes[i.class_id].position).times do
roulette.push(i)
end
end
roulette.empty? ? nil : roulette[rand(roulette.size)]
end
def random_target_actor(hp0 = false)
if hp0
random_target_actor_base {|i| i.hp0?}
else
random_target_actor_base {|i| i.exist?}
end
end
def smooth_target_actor(actor_index)
actor = @actors[actor_index]
return actor if actor != nil and actor.exist?
return @actors.find {|i| i.exist?}
end
end
class Game_Troop
def random_target_enemy_base(&condition)
rolette = []
@enemies.each do |i|
next if !yield(i)
roulette.push(i)
end
roulette.empty? ? nil : roulette[rand(roulette.size)]
end
def random_target_actor(hp0 = false)
if hp0
random_target_actor_base {|i| i.hp0?}
else
random_target_actor_base {|i| i.exist?}
end
end
def smooth_target_enemy(enemy_index)
enemy = @enemies[enemy_index]
return enemy if enemy != nil and enemy.exist?
return @enemies.find {|i| i.exist?}
end
end
Bugs and other insects
My script should work with the SDK.
I didn't test it much, so if someone uses this and finds a bug, contact me so I can repair it.