
#==============================================================================
# ** Earthbound-Ish Battle Core
#------------------------------------------------------------------------------
# Version: 1.0
# Author: cozziekuns
# Date: February 17, 2013
#==============================================================================
# Description:
#------------------------------------------------------------------------------
# This script attempts to mimic the battle system of the Earthbound/Mother
# series; most notably Earthbound and Earthbound 2 (Mother 2 and 3).
#==============================================================================
# Instructions:
#------------------------------------------------------------------------------
# Paste this script into its own slot in the Script Editor, above Main but
# below Materials. Edit the modules to your liking.
#==============================================================================
#==============================================================================
# ** Cozziekuns
#==============================================================================
module Cozziekuns
module Earthboundish
ActorIcons ={
# Command Name => IconID
"Attack" => 116,
"Magic" => 152,
"Special" => 128,
"Guard" => 161,
"Items" => 260,
"Escape" => 474,
}
ActorIcons.default = 0
end
end
include Cozziekuns
#==============================================================================
# ** Sprite Battler
#==============================================================================
class Sprite_Battler
alias coz_ebish_spbtlr_update_effect update_effect
def update_effect(*args)
update_select_whiten if @effect_type == :select_white
if @battler.sprite_effect_type == :select_white_to_normal
revert_to_normal
@battler.sprite_effect_type = nil
end
coz_ebish_spbtlr_update_effect(*args)
end
def update_select_whiten
self.color.set(255, 255, 255, 0)
self.color.alpha = 128
end
end
#==============================================================================
# ** Window_ActorCommand
#==============================================================================
class Window_ActorCommand
def visible_line_number
return 1
end
def col_max
return 6
end
def contents_height
item_height
end
def top_col
ox / (item_width + spacing)
end
def top_col=(col)
col = 0 if col < 0
col = col_max - 1 if col > col_max - 1
self.ox = col * (item_width + spacing)
end
def bottom_col
top_col + col_max - 1
end
def bottom_col=(col)
self.top_col = col - (col_max - 1)
end
def ensure_cursor_visible
self.top_col = index if index < top_col
self.bottom_col = index if index > bottom_col
end
def item_rect(index)
rect = super(index)
rect.x = index * (item_width + spacing)
rect.y = 0
rect
end
def window_width
Graphics.width - 224
end
def open
@help_window.open
super
end
def close
@help_window.close
super
end
def update
super
@help_window.update
end
def draw_item(index)
rect = item_rect_for_text(index)
x = rect.x + rect.width / 2 - 12
y = item_rect_for_text(index).y
draw_icon(Earthboundish::ActorIcons[command_name(index)], x, y, command_enabled?(index))
end
alias coz_ebish_waccmd_make_command_list make_command_list
def make_command_list(*args)
coz_ebish_waccmd_make_command_list(*args)
add_escape_command
end
def add_escape_command
add_command(Vocab::escape, :escape, BattleManager.can_escape?)
end
def update_help
@help_window.set_text(command_name(index))
end
end
#==============================================================================
# ** Window_BattleStatus
#==============================================================================
class Window_BattleStatus
[:basic_area_rect, :gauge_area_rect].each { |method|
define_method(method) { |index|
rect = item_rect(index)
rect
}
}
def col_max
$game_party.members.size
end
def window_width
Graphics.width / ( 4 / $game_party.members.size.to_f )
end
def window_height
fitting_height($data_system.opt_display_tp ? 5 : 4)
end
def item_width
(window_width - standard_padding * 2) / $game_party.members.size
end
def item_height
(window_height - standard_padding * 2)
end
def draw_basic_area(rect, actor)
draw_actor_name(actor, rect.x, rect.y, rect.width)
draw_actor_icons(actor, rect.x + 4, rect.y + line_height, rect.width)
end
def draw_gauge_area_with_tp(rect, actor)
draw_gauge_area_without_tp(rect, actor)
draw_actor_tp(actor, rect.x + 4, rect.y + line_height * 4, rect.width - 8)
end
def draw_gauge_area_without_tp(rect, actor)
draw_actor_hp(actor, rect.x + 4, rect.y + line_height * 2, rect.width - 8)
draw_actor_mp(actor, rect.x + 4, rect.y + line_height * 3, rect.width - 8)
end
def draw_actor_name(actor, x, y, width = 112)
change_color(hp_color(actor))
draw_text(x, y, width, line_height, actor.name, 1)
end
alias coz_ebish_wbtlsts_item_rect item_rect
def item_rect(index, *args)
rect = coz_ebish_wbtlsts_item_rect(index, *args)
rect.x = index % col_max * item_width
rect
end
def update
super
update_position
end
def update_position
self.x = (Graphics.width - window_width) / 2 + 128
end
end
#==============================================================================
# ** Window_BattleActor
#==============================================================================
class Window_BattleActor
def update_position
self.x = (Graphics.width - window_width) / 2
end
end
#==============================================================================
# ** Window_BattleEnemy
#==============================================================================
class Window_BattleEnemy
def cursor_left(wrap)
select((index - 1 + item_max) % item_max)
end
def cursor_right(wrap)
select((index + 1) % item_max)
end
def cursor_up(wrap)
cursor_left(true)
end
def cursor_down(wrap)
cursor_right(true)
end
def show
select(0)
self
end
def update_help
@help_window.set_text(enemy.name)
end
end
#==============================================================================
# ** Window_BattleSkill + Window_BattleItem
#==============================================================================
[:Window_BattleSkill, :Window_BattleItem].each { |klass|
Object.const_get(klass).send(:define_method, :show) {
select_last
super()
}
Object.const_get(klass).send(:define_method, :hide) { super() }
}
#==============================================================================
# ** Window_ActorHelp
#==============================================================================
class Window_ActorHelp < Window_Help
def initialize
super(1)
self.openness = 0
update_position
end
def update_position
self.x = Graphics.width - 224
self.width = 224
create_contents
end
def refresh
contents.clear
draw_text(4, 0, 224 - standard_padding * 2, line_height, @text, 1)
end
end
#==============================================================================
# ** Scene_Battle
#==============================================================================
class Scene_Battle
def start_party_command_selection
unless scene_changing?
@status_window.open
@status_window.refresh
if BattleManager.input_start
next_command
start_actor_command_selection
else
@party_command_window.deactivate
turn_start
end
end
end
def create_actor_command_window
@actor_command_window = Window_ActorCommand.new
@actor_command_window.set_handler(:attack, method(:command_attack))
@actor_command_window.set_handler(:skill, method(:command_skill))
@actor_command_window.set_handler(:guard, method(:command_guard))
@actor_command_window.set_handler(:item, method(:command_item))
@actor_command_window.set_handler(:escape, method(:command_escape))
@actor_command_window.set_handler(:cancel, method(:prior_command))
@actor_command_window.help_window = Window_ActorHelp.new
end
def create_help_window
@help_window = Window_Help.new(1)
@help_window.visible = false
end
alias coz_ebish_scbtl_create_enemy_window create_enemy_window
def create_enemy_window(*args)
coz_ebish_scbtl_create_enemy_window(*args)
@enemy_window.help_window = @actor_command_window.help_window
end
alias coz_ebish_scbtl_update_basic update_basic
def update_basic(*args)
old_enemy = @enemy_window.active ? @enemy_window.enemy : nil
coz_ebish_scbtl_update_basic(*args)
update_enemy_whiten(old_enemy)
end
def update_enemy_whiten(old_enemy)
if !@enemy_window.active or old_enemy != @enemy_window.enemy
old_enemy.sprite_effect_type = :select_white_to_normal if old_enemy && !old_enemy.dead?
end
@enemy_window.enemy.sprite_effect_type = :select_white if @enemy_window.active
end
def update_info_viewport
move_info_viewport(128)
end
end
#==============================================================================
# ** Earthbound-Ish Sprite Display
#------------------------------------------------------------------------------
# Version: 1.0
# Author: cozziekuns
# Date: February 17, 2013
#==============================================================================
# Description:
#------------------------------------------------------------------------------
# This script attempts to emulate the battle system of the Earthbound/Mother
# series; most notably Earthbound and Earthbound 2 (Mother 2 and 3). This
# certain addon addresses the character sprite movements found in Mother 3,
# where active actors bobbed up and down the screen.
#==============================================================================
# Instructions:
#------------------------------------------------------------------------------
# Paste this script into its own slot in the Script Editor, above Main but
# below Materials.
#==============================================================================
#==============================================================================
# ** BattleManager
#==============================================================================
class << BattleManager
alias coz_ebishspd_btlmngr_init_members init_members
def init_members(*args)
coz_ebishspd_btlmngr_init_members(*args)
@dummy_battler = nil
end
def dummy_battler
@dummy_battler
end
def next_subject
loop do
battler = @action_battlers.shift
unless battler
@dummy_battler = nil
return nil
end
next unless battler.index && battler.alive?
@dummy_battler = battler
return battler
end
end
end
#==============================================================================
# ** Game_Actor
#==============================================================================
class Game_Actor
def use_sprite?
true
end
end
#==============================================================================
# ** Sprite_BattlerCharacter
#==============================================================================
class Sprite_BattlerCharacter < Sprite_Battler
def initialize(viewport, battler = nil)
super(viewport, battler)
@y_offset = 0
end
def make_animation_sprites
@ani_sprites = []
@ani_duplicated = @@ani_checker.include?(@animation)
if !@ani_duplicated && @animation.position == 3
@@ani_checker.push(@animation)
end
end
def update
super
update_position
update_zoom
update_y_offset
end
def update_bitmap
new_bitmap = set_character_bitmap
if bitmap != new_bitmap
self.bitmap = new_bitmap
init_visibility
end
update_src_rect
end
def set_character_bitmap
bitmap = Cache.character(@battler.character_name)
sign = @battler.character_name[/^[\!\$]./]
if sign && sign.include?('$')
@cw = bitmap.width / 3
@ch = bitmap.height / 4
else
@cw = bitmap.width / 12
@ch = bitmap.height / 8
end
self.ox = @cw / 2
self.oy = @ch
bitmap
end
def update_origin
if bitmap
self.ox = @cw / 2
self.oy = 0
end
end
def update_src_rect
index = @battler.character_index
sx = (index % 4 * 3 + 1) * @cw
sy = (index / 4 * 4) * @ch
self.src_rect.set(sx, sy, @cw, @y_offset)
end
def update_position
width = Graphics.width / ( 4 / $game_party.members.size.to_f )
sx = (Graphics.width - width) / 2 + 128
self.x = @battler.index * 128 + sx / 2 + 12 + 32 * (4 - $game_party.members.size)
self.y = 296 - @y_offset * 2
end
def update_zoom
self.zoom_x = 2.0
self.zoom_y = 2.0
end
def update_y_offset
if BattleManager.actor == @battler or BattleManager.dummy_battler == @battler
@y_offset = [@y_offset + 4, 32].min
else
@y_offset = [@y_offset - 4, 0].max
end
end
end
#==============================================================================
# ** Spriteset_Battle
#==============================================================================
class Spriteset_Battle
def create_actors
@actor_sprites = $game_party.members.collect { |actor|
Sprite_BattlerCharacter.new(@viewport3, actor)
}
end
end
#==============================================================================
# ** Earthbound-Ish Odometer Roll
#------------------------------------------------------------------------------
# Version: 1.0
# Author: cozziekuns
# Date: February 17, 2013
#==============================================================================
# Description:
#------------------------------------------------------------------------------
# This script attempts to emulate the battle system of the Earthbound/Mother
# series; most notably Earthbound and Earthbound 2 (Mother 2 and 3). This
# certain addon addresses the infamous HP/MP scrolling system that made battles
# that much more intense.
#==============================================================================
# Instructions:
#------------------------------------------------------------------------------
# Paste this script into its own slot in the Script Editor, above Main but
# below Materials. Edit the modules to your liking.
#==============================================================================
# Graphics:
#------------------------------------------------------------------------------
# You must have two Odometer pictures in your Graphics/System folder. One of
# them must be named "Odometer_HP", and the other one must be named
# "Odometer_MP". Obviously, they represent the odometer for HP and MP values,
# respectively
#==============================================================================
#==============================================================================
# ** Cozziekuns
#==============================================================================
module Cozziekuns
module Earthboundish
Odometer_Roll_Speed = 4 # Smaller speeds are faster than larger speeds.
end
end
include Cozziekuns
#==============================================================================
# ** Game_Actor
#==============================================================================
class Game_Actor
attr_accessor :odometer_hp
attr_accessor :odometer_mp
alias coz_ebisohd_gmactr_setup setup
def setup(actor_id, *args)
coz_ebisohd_gmactr_setup(actor_id, *args)
@odometer_hp = 0
@odometer_mp = 0
end
alias coz_ebishod_gmactr_execute_damage execute_damage
def execute_damage(user, *args)
if $game_party.in_battle
on_damage(@result.hp_damage) if @result.hp_damage > 0
@odometer_hp += @result.hp_damage
@odometer_mp += @result.mp_damage
user.hp += @result.hp_drain
user.mp += @result.mp_drain
else
coz_ebishod_gmactr_execute_damage(user, *args)
end
end
[:hp, :mp].each { |stat|
alias_method("coz_ebishod_gmactr_item_effect_recover_#{stat}".to_sym, "item_effect_recover_#{stat}".to_sym)
define_method("item_effect_recover_#{stat}".to_sym) { |user, item, effect|
if $game_party.in_battle
value = (send("m#{stat}".to_sym) * effect.value1 + effect.value2) * rec
value *= user.pha if item.is_a?(RPG::Item)
value = value.to_i
@result.send("#{stat}_damage=".to_sym, @result.send("#{stat}_damage".to_sym) - value)
@result.success = true
send("odometer_#{stat}=".to_sym, send("odometer_#{stat}".to_sym) - value)
else
send("coz_ebishod_gmactr_item_effect_recover_#{stat}".to_sym, user, item, effect)
end
}
}
end
#==============================================================================
# ** Game_Enemy
#==============================================================================
class Game_Enemy
def execute_damage(user)
on_damage(@result.hp_damage) if @result.hp_damage > 0
self.hp -= @result.hp_damage
self.mp -= @result.mp_damage
user.odometer_hp -= @result.hp_drain
user.odometer_mp -= @result.mp_drain
end
end
#==============================================================================
# ** Window_BattleStatus
#==============================================================================
class Window_BattleStatus
def refresh_hpmp(actor, index)
rect = item_rect(index)
if gauge_area_rect(index) == item_rect(index)
rect.y += line_height * 2
rect.height -= line_height * 2
contents.clear_rect(rect)
else
contents.clear_rect(gauge_area_rect(index))
end
draw_gauge_area(gauge_area_rect(index), actor)
end
[:hp, :mp].each { |stat|
define_method("draw_actor_#{stat}".to_sym) { |actor, x, y, width|
change_color(system_color)
draw_text(x, y, 30, line_height, Vocab.send("#{stat}_a"))
od_x = x + contents.text_size(Vocab.send("#{stat}_a")).width + 4
actor_hp = actor.send("#{stat}".to_sym)
actor_od_hp = actor.send("odometer_#{stat}".to_sym)
draw_odometer(od_x, y, stat, actor_hp, actor_od_hp)
}
}
def draw_odometer(x, y, type, value, od_value)
bitmap = Cache.system("Odometer_#{type.upcase}")
places = [1000, 100, 10, 1]
od_ary = value.to_s.split("").collect { |str| str.to_i }
(4 - od_ary.size).times { od_ary.unshift(0) }
od_ary.each_index { |i|
src_y = (9 - od_ary[i]) * 20
if (od_ary.join.to_i) % places[i] == 0 and od_value != 0
src_y += 20 / Earthboundish::Odometer_Roll_Speed * (Graphics.frame_count % Earthboundish::Odometer_Roll_Speed)
end
contents.blt(x + i * 24, y + 2, bitmap, Rect.new(0, src_y, 24, 20))
}
end
end
#==============================================================================
# ** Scene_Battle
#==============================================================================
class Scene_Battle
alias coz_ebishod_scbtl_update_basic update_basic
def update_basic(*args)
coz_ebishod_scbtl_update_basic(*args)
update_odometer
end
def update_odometer
$game_party.members.each { |actor|
if actor.odometer_hp != 0 or actor.odometer_mp != 0
if actor.odometer_hp != 0 and Graphics.frame_count % Earthboundish::Odometer_Roll_Speed == 0
damage = actor.odometer_hp > 0 ? 1 : - 1
actor.hp -= damage
actor.odometer_hp -= damage
end
if actor.odometer_mp != 0 and Graphics.frame_count % Earthboundish::Odometer_Roll_Speed == 0
damage = actor.odometer_mp > 0 ? 1 : - 1
actor.mp -= damage
actor.odometer_mp -= damage
end
@status_window.refresh_hpmp(actor, actor.index)
end
}
end
end