#Formation Bonus v1.3
#----------#
#Features: Rearrange actors by rows and make formations, granting bonuses
# based on what row and formation the actors are in.
#
#Usage: Plug and play, customize as needed.
#
#----------#
#-- Script by: V.M of D.T
#
#- Questions or comments can be:
# posted on the thread for the script
# given by email: sumptuaryspade@live.ca
# provided on facebook:
http://www.facebook.com/DaimoniousTailsGames
# All my other scripts and projects can be found here:
http://daimonioustails.weebly.com/
#
#--- Free to use in any project, commercial or non-commercial, with credit given
# - - Though a donation's always a nice way to say thank you~ (I also accept actual thank you's)
#Location for actor sprites in battle:
FORMATION_ROWS = 4
FORMATION_COLS = 3
#Set a number of locations equal to rows * cols
FORMATION_LOCATIONS = [
[370,200],[410,200],[450,200],
[380,220],[420,220],[460,220],
[390,240],[430,240],[470,240],
[400,260],[440,260],[480,260]]
FORMATION_SX = 20
#Icon to be displayed as formation slot in the Formation Changing Scene.
FORMATION_ICON = 430
#Change in damage given/recieved based on row position:
#Front row, middle row, back row
FORMATION_ROW_ATK = [1.5, 1.0, 0.8]
FORMATION_ROW_DEF = [1.0, 1.0, 1.5]
FORMATION_ROW_MAT = [1.0, 1.0, 2.0]
FORMATION_ROW_MDF = [1.0, 1.0, 1.5]
FORMATION_ROW_TGR = [2.0, 1.0, 0.5]
#The special Formations actors can be placed in:
# id => { :name => "name of formation", :slots = [slots to be filled], ... }
# Slot ids are:
# 0,1,2
# 3,4,5
# 6,7,8
# Stat options are: :hp, :mp, :atk, :def, :mat, :mdf, :agi, :luk
# Formation bonuses apply to all actors.
# Example:
# 1 => { :name => "Back Row", :slots => [2,5,8], :hp => 20, :mp => 5,}
FORMATION_BONUS = { 0 => {},
1 => { :name => "One Liner", :slots => [3,4,5,6], :hp => 20,}
}
class Game_Actor < Game_Battler
attr_accessor :formation_slot
alias formation_init initialize
alias formation_param param
def initialize(actor_id)
formation_init(actor_id)
@formation_slot = -1
end
def screen_x
FORMATION_LOCATIONS[@formation_slot][0]
end
def screen_y
FORMATION_LOCATIONS[@formation_slot][1]
end
def front_row?
array = []
FORMATION_ROWS.times do |i|
array.push(FORMATION_COLS * i)
end
array.include?(@formation_slot)
end
def middle_row?
!front_row? && !back_row?
end
def back_row?
array = []
FORMATION_ROWS.times do |i|
array.push(FORMATION_COLS * i + FORMATION_COLS - 1)
end
array.include?(@formation_slot)
end
def param(param_id)
sym = [:hp,:mp,:atk,:def,:mat,:mdf,:agi,:luk]
value = formation_param(param_id)
if $game_party.short_form[sym[param_id]]
value *= ($game_party.short_form[sym[param_id]] * 0.01 + 1)
end
[[value, param_max(param_id)].min, param_min(param_id)].max.to_i
end
end
class Game_Enemy < Game_Battler
def front_row?
true
end
def middle_row?
false
end
def back_row?
false
end
end
class Game_Battler
def tgr
return sparam(0) * FORMATION_ROW_TGR[2] if back_row?
return sparam(0) * FORMATION_ROW_TGR[1] if middle_row?
return sparam(0) * FORMATION_ROW_TGR[0]
end
def make_damage_value(user, item)
value = item.damage.eval(user, self, $game_variables)
value *= item_element_rate(user, item)
value *= pdr if item.physical?
value *= mdr if item.magical?
value *= rec if item.damage.recover?
value *= row_defense if item.physical? && !item.damage.recover?
value *= row_attack(user) if item.physical? && !item.damage.recover?
value *= row_magic_attack(user) if item.magical? && !item.damage.recover?
value *= row_magic_defense if item.magical? && !item.damage.recover?
value = apply_critical(value) if @result.critical
value = apply_variance(value, item.damage.variance)
value = apply_guard(value)
@result.make_damage(value.to_i, item)
end
def row_defense
return FORMATION_ROW_DEF[1] if middle_row?
return FORMATION_ROW_DEF[2] if back_row?
return FORMATION_ROW_DEF[0]
end
def row_attack(user)
return FORMATION_ROW_ATK[2] if user.back_row?
return FORMATION_ROW_ATK[1] if user.middle_row?
return FORMATION_ROW_ATK[0]
end
def row_magic_defense
return FORMATION_ROW_MDF[1] if middle_row?
return FORMATION_ROW_MDF[2] if back_row?
return FORMATION_ROW_MDF[0]
end
def row_magic_attack(user)
return FORMATION_ROW_MAT[2] if user.back_row?
return FORMATION_ROW_MAT[1] if user.middle_row?
return FORMATION_ROW_MAT[0]
end
end
class Game_Party
attr_accessor :formation_id
def first_available_slot
end
def formation_slot(id)
members.each do |actor|
return actor if actor.formation_slot == id
end
return nil
end
def formation_name
return current_formation[:name] if current_formation
return "-----"
end
def setup_starting_members
@actors = $data_system.party_members.clone
iter = 0
members.each do |actor|
actor.formation_slot = iter
iter += 1
end
current_formation
end
def current_formation
FORMATION_BONUS.each do |sym, form|
next if sym == 0
valid = true
form[:slots].each do |val|
valid = false unless formation_slot(val)
end
next unless valid
@formation_id = sym
return FORMATION_BONUS[sym]
end
@formation_id = 0
return nil
end
def short_form
@formation_id = 0 unless @formation_id
FORMATION_BONUS[@formation_id]
end
def add_actor(actor_id)
return if @actors.include?(actor_id)
@actors.push(actor_id)
(FORMATION_ROWS * FORMATION_COLS).times do |i|
if formation_slot(i).nil?
$game_actors[actor_id].formation_slot = i
break
end
end
$game_player.refresh
$game_map.need_refresh = true
end
def remove_actor(actor_id)
return unless @actors.include?(actor_id)
@actors.delete(actor_id)
$game_actors[actor_id].formation_slot = -1
$game_player.refresh
$game_map.need_refresh = true
end
end
class Scene_Formation < Scene_Base
def start
super
@help_window = Window_Help.new(1)
@list_window = Window_FormList.new
@list_window.set_handler

ok, method

list_ok))
@list_window.set_handler

cancel, method

list_cancel))
@bonus_window = Window_FormBonus.new
@form_window = Window_Formation.new
@form_window.set_handler

ok, method

form_ok))
@form_window.set_handler

cancel, method

form_cancel))
@stat_window = Window_FormStat.new
@list_window.select(0)
@list_window.activate
end
def update
super
if @list_window.active
@stat_window.set_actor(@list_window.current_item)
elsif @form_window.active
if @form_window.current_item
@stat_window.set_actor(@form_window.current_item)
else
@stat_window.set_actor(@list_window.current_item)
end
end
end
def list_ok
@form_window.select(@list_window.current_item.formation_slot)
@form_window.activate
end
def list_cancel
SceneManager.return
end
def form_ok
index = @form_window.current_index
actor = @list_window.current_item
if $game_party.formation_slot(index)
$game_party.formation_slot(index).formation_slot = actor.formation_slot
end
actor.formation_slot = index
@form_window.refresh
@bonus_window.refresh
@stat_window.refresh
form_cancel
end
def form_cancel
@form_window.select(-1)
@list_window.activate
end
end
class Window_FormList < Window_Selectable
def initialize
super(0,48,Graphics.width/5*2,(Graphics.height-48)/2)
refresh
end
def item_max
$game_party.battle_members.size
end
def draw_item(index)
actor = $game_party.battle_members[index]
rect = item_rect(index)
draw_text(rect, actor.name)
draw_text(rect, "Lvl ",2)
draw_text(rect, actor.level,2)
end
def current_item
return $game_party.battle_members[@index] if @index >= 0
return nil
end
end
class Window_FormBonus < Window_Base
def initialize
super(Graphics.width/5*2,48+(Graphics.height-48)/3*2,Graphics.width/5*3+3,(Graphics.height-48)/3+2)
refresh
end
def refresh
contents.clear
change_color(system_color)
draw_text(0,0,contents.width,line_height,"Bonuses:")
return unless $game_party.current_formation
change_color(normal_color)
form = $game_party.current_formation
xx = 6;yy = line_height;iter = 1
form.each do |key, val|
next unless [:hp,:mp,:atk,:def,:mat,:mdf,:agi,:luk].include?(key)
case key
when :hp
text = sprintf("%s %+d%", Vocab::hp, val.to_s)
when :mp
text = sprintf("%s %+d%", Vocab::mp, val.to_s)
when :atk
text = sprintf("%s %+d%", Vocab:

aram(2), val.to_s)
when :def
text = sprintf("%s %+d%", Vocab:

aram(3), val.to_s)
when :mat
text = sprintf("%s %+d%", Vocab:

aram(4), val.to_s)
when :mdf
text = sprintf("%s %+d%", Vocab:

aram(5), val.to_s)
when :agi
text = sprintf("%s %+d%", Vocab:

aram(6), val.to_s)
when :luk
text = sprintf("%s %+d%", Vocab:

aram(7), val.to_s)
end
draw_text(xx,yy,contents.width/3,line_height,text)
xx += contents.width/3
if iter % 3 == 0
xx = 5; yy += line_height
end
iter += 1
end
end
end
class Window_Formation < Window_Selectable
def initialize
super(Graphics.width/5*2,48,Graphics.width/5*3+3,(Graphics.height-48)/3*2)
refresh
end
def refresh
contents.clear
xx = FORMATION_SX;yy = contents.height/3;iter = 0
FORMATION_ROWS.times do
FORMATION_COLS.times do
draw_icon(FORMATION_ICON,xx,yy,$game_party.formation_slot(iter))
if $game_party.formation_slot(iter)
draw_actor_graphic($game_party.formation_slot(iter),xx-4,yy-16)
end
xx += 50
iter += 1
end
xx -= FORMATION_COLS * 50
yy += 30;xx += 10
end
change_color(system_color)
draw_text(0,0,contents.width,line_height,"Formation: ")
change_color(normal_color)
draw_text(106,0,contents.width,line_height,$game_party.formation_name)
end
def item_rect(index)
xx = FORMATION_SX;yy = contents.height/3
xx += index % col_max * 50
xx += 10 * (index / col_max).to_i
yy += 30 * (index / col_max).to_i
Rect.new(xx,yy,24,24)
end
def col_max; FORMATION_COLS; end
def row_max; FORMATION_ROWS; end
def item_max; FORMATION_COLS * FORMATION_ROWS; end
def current_item
$game_party.formation_slot(@index) ? $game_party.formation_slot(@index) : nil
end
def current_index
@index
end
def draw_actor_graphic(actor,x,y)
new_bitmap = Cache.character(actor.character_name)
next_bitmap = new_bitmap.clone
xx = actor.character_index % 4 * new_bitmap.width/4
yy = actor.character_index / 4 * new_bitmap.height/2
next_bitmap.blt(0,0,next_bitmap,Rect.new(xx,yy,next_bitmap.width/4,next_bitmap.height/2))
contents.blt(x,y,next_bitmap,Rect.new(0,next_bitmap.height/8,next_bitmap.width/12,next_bitmap.height/8))
end
end
class Window_FormStat < Window_Base
def initialize
super(0,64+(Graphics.height-64)/2,Graphics.width/5*2,(Graphics.height-64)/2)
refresh
end
def refresh
contents.clear
change_color(system_color)
draw_text(0,line_height,contents.width,line_height,"Class:")
draw_text(0,line_height*2,contents.width/2,line_height,Vocab::hp)
draw_text(contents.width/2,line_height*2,contents.width/2,line_height,Vocab::mp)
draw_text(0,line_height*3,contents.width/2,line_height,Vocab:

aram(2))
draw_text(contents.width/2,line_height*3,contents.width/2,line_height,Vocab:

aram(3))
draw_text(0,line_height*4,contents.width/2,line_height,Vocab:

aram(4))
draw_text(contents.width/2,line_height*4,contents.width/2,line_height,Vocab:

aram(5))
draw_text(0,line_height*5,contents.width/2,line_height,Vocab:

aram(6))
draw_text(contents.width/2,line_height*5,contents.width/2,line_height,Vocab:

aram(7))
contents.fill_rect(contents.width/2-2,line_height*2.5,1,line_height*3,Color.new(155,155,155))
return unless @actor
change_color(normal_color)
draw_actor_graphic(@actor,contents.width/2,32)
draw_text(0,line_height,contents.width,line_height,@actor.class.name,2)
draw_text(0,line_height*2,contents.width/2,line_height,@actor.mhp,2)
draw_text(contents.width/2,line_height*2,contents.width/2,line_height,@actor.mmp,2)
draw_text(0,line_height*3,contents.width/2,line_height,@actor.atk,2)
draw_text(contents.width/2,line_height*3,contents.width/2,line_height,@actor.def,2)
draw_text(0,line_height*4,contents.width/2,line_height,@actor.mat,2)
draw_text(contents.width/2,line_height*4,contents.width/2,line_height,@actor.mdf,2)
draw_text(0,line_height*5,contents.width/2,line_height,@actor.agi,2)
draw_text(contents.width/2,line_height*5,contents.width/2,line_height,@actor.luk,2)
end
def set_actor(actor)
return if @actor == actor
@actor = actor
refresh
end
end
#~ class Scene_Menu
#~ def command_formation
#~ SceneManager.call(Scene_Formation)
#~ end
#~ end
class Window_MenuCommand < Window_Command
alias formation1_command add_original_commands
def add_original_commands
formation1_command
add_command("Position", :formation1)
end
end
if $imported["YEA-AceMenuEngine"] #This line is optional only for Yanfly's Menu Engine script
class Scene_Menu < Scene_MenuBase
alias formation1_menu13211 create_command_window
#--------------------------------------------------------------------------
# * Create Command Window
#--------------------------------------------------------------------------
def create_command_window
formation1_menu13211()
@command_window.set_handler

formation1, method

command_formation1))
end
#--------------------------------------------------------------------------
# * New Formation Command
#--------------------------------------------------------------------------
def command_formation1
SceneManager.call(Scene_Formation)
end
end
end #This line is optional only for Yanfly's Menu Engine script
class Window_MenuCommand
def formation_enabled
true
end
end
class Window_MenuCommand
def formation_enabled
true
end
end