Vlue

Formation Bonus

Apr 20th, 2014
1,982
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #Formation Bonus v1.4
  2. #----------#
  3. #Features: Rearrange actors by rows and make formations, granting bonuses
  4. #           based on what row and formation the actors are in.
  5. #
  6. #Usage:    Plug and play, customize as needed.
  7. #
  8. #----------#
  9. #-- Script by: V.M of D.T
  10. #
  11. #- Questions or comments can be:
  12. #    posted on the thread for the script
  13. #    given by email: sumptuaryspade@live.ca
  14. #    provided on facebook: http://www.facebook.com/DaimoniousTailsGames
  15. #   All my other scripts and projects can be found here: http://daimonioustails.weebly.com/
  16. #
  17. #--- Free to use in any project, commercial or non-commercial, with credit given
  18. # - - Though a donation's always a nice way to say thank you~ (I also accept actual thank you's)
  19.  
  20. #Location for actor sprites in battle (3x3 grid only right now):
  21. FORMATION_ROWS = 3
  22. FORMATION_COLS = 3
  23. #Set a number of locations equal to rows * cols
  24. FORMATION_LOCATIONS = [
  25.   [375,200],[425,200],[475,200],
  26.   [395,230],[445,230],[495,230],
  27.   [415,260],[465,260],[515,260]]
  28.  
  29. FORMATION_SX = 20
  30.  
  31. #If true only skills with the <RANGE> tag can be used in the back row
  32. FORMATION_USE_RANGE = false
  33.  
  34. #Icon to be displayed as formation slot in the Formation Changing Scene.
  35. FORMATION_ICON = 430
  36. #Change in damage given/recieved based on row position:
  37. #Front row, middle row, back row
  38. FORMATION_ROW_ATK = [1.0, 0.8, 0.5]
  39. FORMATION_ROW_DEF = [1.0, 0.8, 0.5]
  40. FORMATION_ROW_MAT = [1.0, 1.0, 1.0]
  41. FORMATION_ROW_MDF = [1.0, 1.0, 1.0]
  42. FORMATION_ROW_TGR = [2.0, 1.0, 0.5]
  43.  
  44. #The special Formations actors can be placed in:
  45. # id => { :name => "name of formation", :slots = [slots to be filled], ... }
  46. #   Slot ids are:
  47. #    0,1,2
  48. #     3,4,5
  49. #      6,7,8
  50. #  Stat options are: :hp, :mp, :atk, :def, :mat, :mdf, :agi, :luk
  51. #  Formation bonuses apply to all actors.
  52. # Example:
  53. #  1 => { :name => "Back Row", :slots => [2,5,8], :hp => 20, :mp => 5,}
  54. FORMATION_BONUS = { 0 => {},
  55.   1 => { :name => "One Liner", :slots => [3,4,5], :hp => 20,}
  56. }
  57. class Game_Actor < Game_Battler
  58.   attr_accessor :formation_slot
  59.   alias formation_init initialize
  60.   alias formation_param param
  61.   alias formation_scm skill_conditions_met?
  62.   def initialize(actor_id)
  63.     formation_init(actor_id)
  64.     @formation_slot = -1
  65.   end
  66.   def screen_x
  67.     FORMATION_LOCATIONS[@formation_slot][0]
  68.   end
  69.   def screen_y
  70.     FORMATION_LOCATIONS[@formation_slot][1]
  71.   end
  72.   def front_row?
  73.     array = []
  74.     FORMATION_ROWS.times do |i|
  75.       array.push(FORMATION_COLS * i)
  76.     end
  77.     array.include?(@formation_slot)
  78.   end
  79.   def middle_row?
  80.     !front_row? && !back_row?
  81.   end
  82.   def back_row?
  83.     array = []
  84.     FORMATION_ROWS.times do |i|
  85.       array.push(FORMATION_COLS * i + FORMATION_COLS - 1)
  86.     end
  87.     array.include?(@formation_slot)
  88.   end
  89.   def param(param_id)
  90.     sym = [:hp,:mp,:atk,:def,:mat,:mdf,:agi,:luk]
  91.     value = formation_param(param_id)
  92.     if $game_party.short_form[sym[param_id]]
  93.       value *= ($game_party.short_form[sym[param_id]] * 0.01 + 1)
  94.     end
  95.     [[value, param_max(param_id)].min, param_min(param_id)].max.to_i
  96.   end
  97.   def skill_conditions_met?(skill)
  98.     formation_scm(skill) && check_range(skill)
  99.   end
  100.   def check_range(skill)
  101.     return true unless FORMATION_USE_RANGE
  102.     if back_row? && !skill.note.include?("<RANGE>")
  103.       return false
  104.     else
  105.       return true
  106.     end
  107.   end
  108.   def attack_usable?
  109.     if FORMATION_USE_RANGE && back_row?
  110.       if equips[0]
  111.         return false if !equips[0].note.include?("<RANGE>")
  112.       else
  113.         return false
  114.       end
  115.     end
  116.     usable?($data_skills[attack_skill_id])
  117.   end
  118. end
  119.  
  120. class Game_Enemy < Game_Battler
  121.   def front_row?
  122.     true
  123.   end
  124.   def middle_row?
  125.     false
  126.   end
  127.   def back_row?
  128.     false
  129.   end
  130. end
  131.  
  132. class Game_Battler
  133.   def tgr
  134.     return sparam(0) * FORMATION_ROW_TGR[2] if back_row?
  135.     return sparam(0) * FORMATION_ROW_TGR[1] if middle_row?
  136.     return sparam(0) * FORMATION_ROW_TGR[0]
  137.   end
  138.   def make_damage_value(user, item)
  139.     value = item.damage.eval(user, self, $game_variables)
  140.     value *= item_element_rate(user, item)
  141.     value *= pdr if item.physical?
  142.     value *= mdr if item.magical?
  143.     value *= rec if item.damage.recover?
  144.     value *= row_defense if item.physical? && !item.damage.recover?
  145.     value *= row_attack(user) if item.physical? && !item.damage.recover?
  146.     value *= row_magic_attack(user) if item.magical? && !item.damage.recover?
  147.     value *= row_magic_defense if item.magical? && !item.damage.recover?
  148.     value = apply_critical(value) if @result.critical
  149.     value = apply_variance(value, item.damage.variance)
  150.     value = apply_guard(value)
  151.     @result.make_damage(value.to_i, item)
  152.   end
  153.   def row_defense
  154.     return FORMATION_ROW_DEF[1] if middle_row?
  155.     return FORMATION_ROW_DEF[2] if back_row?
  156.     return FORMATION_ROW_DEF[0]
  157.   end
  158.   def row_attack(user)
  159.     return FORMATION_ROW_ATK[2] if user.back_row?
  160.     return FORMATION_ROW_ATK[1] if user.middle_row?
  161.     return FORMATION_ROW_ATK[0]
  162.   end
  163.   def row_magic_defense
  164.     return FORMATION_ROW_MDF[1] if middle_row?
  165.     return FORMATION_ROW_MDF[2] if back_row?
  166.     return FORMATION_ROW_MDF[0]
  167.   end
  168.   def row_magic_attack(user)
  169.     return FORMATION_ROW_MAT[2] if user.back_row?
  170.     return FORMATION_ROW_MAT[1] if user.middle_row?
  171.     return FORMATION_ROW_MAT[0]
  172.   end
  173. end
  174.  
  175. class Game_Party
  176.   attr_accessor  :formation_id
  177.   def first_available_slot
  178.   end
  179.   def formation_slot(id)
  180.     members.each do |actor|
  181.       return actor if actor.formation_slot == id
  182.     end
  183.     return nil
  184.   end
  185.   def formation_name
  186.     return current_formation[:name] if current_formation
  187.     return "-----"
  188.   end
  189.   def setup_starting_members
  190.     @actors = $data_system.party_members.clone
  191.     iter = 0
  192.     members.each do |actor|
  193.       actor.formation_slot = iter
  194.       iter += 1
  195.     end
  196.     current_formation
  197.   end
  198.   def current_formation
  199.     FORMATION_BONUS.each do |sym, form|
  200.       next if sym == 0
  201.       valid = true
  202.       form[:slots].each do |val|
  203.         valid = false unless formation_slot(val)
  204.       end
  205.       next unless valid
  206.       @formation_id = sym
  207.       return FORMATION_BONUS[sym]
  208.     end
  209.     @formation_id = 0
  210.     return nil
  211.   end
  212.   def short_form
  213.     @formation_id = 0 unless @formation_id
  214.     FORMATION_BONUS[@formation_id]
  215.   end
  216.   def add_actor(actor_id)
  217.     return if @actors.include?(actor_id)
  218.     @actors.push(actor_id)
  219.     (FORMATION_ROWS * FORMATION_COLS).times do |i|
  220.       if formation_slot(i).nil?
  221.         $game_actors[actor_id].formation_slot = i
  222.         break
  223.       end
  224.     end
  225.     $game_player.refresh
  226.     $game_map.need_refresh = true
  227.   end
  228.   def remove_actor(actor_id)
  229.     return unless @actors.include?(actor_id)
  230.     @actors.delete(actor_id)
  231.     $game_actors[actor_id].formation_slot = -1
  232.     $game_player.refresh
  233.     $game_map.need_refresh = true
  234.   end
  235. end
  236.  
  237. class Scene_Formation < Scene_Base
  238.   def start
  239.     super
  240.     @help_window = Window_Help.new(1)
  241.     @list_window = Window_FormList.new
  242.     @list_window.set_handler(:ok, method(:list_ok))
  243.     @list_window.set_handler(:cancel, method(:list_cancel))
  244.     @bonus_window = Window_FormBonus.new
  245.     @form_window = Window_Formation.new
  246.     @form_window.set_handler(:ok, method(:form_ok))
  247.     @form_window.set_handler(:cancel, method(:form_cancel))
  248.     @stat_window = Window_FormStat.new
  249.     @list_window.select(0)
  250.     @list_window.activate
  251.   end
  252.   def update
  253.     super
  254.     if @list_window.active
  255.       @stat_window.set_actor(@list_window.current_item)
  256.     elsif @form_window.active
  257.       if @form_window.current_item
  258.         @stat_window.set_actor(@form_window.current_item)
  259.       else
  260.         @stat_window.set_actor(@list_window.current_item)
  261.       end
  262.     end
  263.   end
  264.   def list_ok
  265.     @form_window.select(@list_window.current_item.formation_slot)
  266.     @form_window.activate
  267.   end
  268.   def list_cancel
  269.     SceneManager.return
  270.   end
  271.   def form_ok
  272.     index = @form_window.current_index
  273.     actor = @list_window.current_item
  274.     if $game_party.formation_slot(index)
  275.       $game_party.formation_slot(index).formation_slot = actor.formation_slot
  276.     end
  277.     actor.formation_slot = index
  278.     @form_window.refresh
  279.     @bonus_window.refresh
  280.     @stat_window.refresh
  281.     form_cancel
  282.   end
  283.   def form_cancel
  284.     @form_window.select(-1)
  285.     @list_window.activate
  286.   end
  287. end
  288.  
  289. class Window_FormList < Window_Selectable
  290.   def initialize
  291.     super(0,48,Graphics.width/5*2,(Graphics.height-48)/2)
  292.     refresh
  293.   end
  294.   def item_max
  295.     $game_party.battle_members.size
  296.   end
  297.   def draw_item(index)
  298.     actor = $game_party.battle_members[index]
  299.     rect = item_rect(index)
  300.     draw_text(rect, actor.name)
  301.     draw_text(rect, "Lvl   ",2)
  302.     draw_text(rect, actor.level,2)
  303.   end
  304.   def current_item
  305.     return $game_party.battle_members[@index] if @index >= 0
  306.     return nil
  307.   end
  308. end
  309.  
  310. class Window_FormBonus < Window_Base
  311.   def initialize
  312.     super(Graphics.width/5*2,48+(Graphics.height-48)/3*2,Graphics.width/5*3+3,(Graphics.height-48)/3+2)
  313.     refresh
  314.   end
  315.   def refresh
  316.     contents.clear
  317.     change_color(system_color)
  318.     draw_text(0,0,contents.width,line_height,"Bonuses:")
  319.     return unless $game_party.current_formation
  320.     change_color(normal_color)
  321.     form = $game_party.current_formation
  322.     xx = 6;yy = line_height;iter = 1
  323.     form.each do |key, val|
  324.       next unless [:hp,:mp,:atk,:def,:mat,:mdf,:agi,:luk].include?(key)
  325.       case key
  326.       when :hp
  327.         text = sprintf("%s %+d%", Vocab::hp, val.to_s)
  328.       when :mp
  329.         text = sprintf("%s %+d%", Vocab::mp, val.to_s)
  330.       when :atk
  331.         text = sprintf("%s %+d%", Vocab::param(2), val.to_s)
  332.       when :def
  333.         text = sprintf("%s %+d%", Vocab::param(3), val.to_s)
  334.       when :mat
  335.         text = sprintf("%s %+d%", Vocab::param(4), val.to_s)
  336.       when :mdf
  337.         text = sprintf("%s %+d%", Vocab::param(5), val.to_s)
  338.       when :agi
  339.         text = sprintf("%s %+d%", Vocab::param(6), val.to_s)
  340.       when :luk
  341.         text = sprintf("%s %+d%", Vocab::param(7), val.to_s)
  342.       end
  343.       draw_text(xx,yy,contents.width/3,line_height,text)
  344.       xx += contents.width/3
  345.       if iter % 3 == 0
  346.         xx = 5; yy += line_height
  347.       end
  348.       iter += 1
  349.     end
  350.   end
  351. end
  352.  
  353. class Window_Formation < Window_Selectable
  354.   def initialize
  355.     super(Graphics.width/5*2,48,Graphics.width/5*3+3,(Graphics.height-48)/3*2)
  356.     refresh
  357.   end
  358.   def refresh
  359.     contents.clear
  360.     xx = FORMATION_SX;yy = contents.height/3;iter = 0
  361.     FORMATION_ROWS.times do
  362.       FORMATION_COLS.times do
  363.         draw_icon(FORMATION_ICON,xx,yy,$game_party.formation_slot(iter))
  364.         if $game_party.formation_slot(iter)
  365.           draw_actor_graphic($game_party.formation_slot(iter),xx-4,yy-16)
  366.         end
  367.         xx += 50
  368.         iter += 1
  369.       end
  370.       xx -= FORMATION_COLS * 50
  371.       yy += 30;xx += 10
  372.     end
  373.     change_color(system_color)
  374.     draw_text(0,0,contents.width,line_height,"Formation: ")
  375.     change_color(normal_color)
  376.     draw_text(106,0,contents.width,line_height,$game_party.formation_name)
  377.   end
  378.   def item_rect(index)
  379.     xx = FORMATION_SX;yy = contents.height/3
  380.     xx += index % col_max * 50
  381.     xx += 10 * (index / col_max).to_i
  382.     yy += 30 * (index / col_max).to_i
  383.     Rect.new(xx,yy,24,24)
  384.   end
  385.   def col_max; FORMATION_COLS; end
  386.   def row_max; FORMATION_ROWS; end
  387.   def item_max; FORMATION_COLS * FORMATION_ROWS; end
  388.   def current_item
  389.     $game_party.formation_slot(@index) ? $game_party.formation_slot(@index) : nil
  390.   end
  391.   def current_index
  392.     @index
  393.   end
  394.   def draw_actor_graphic(actor,x,y)
  395.     new_bitmap = Cache.character(actor.character_name)
  396.     next_bitmap = new_bitmap.clone
  397.     xx = actor.character_index % 4 * new_bitmap.width/4
  398.     yy = actor.character_index / 4 * new_bitmap.height/2
  399.     next_bitmap.blt(0,0,next_bitmap,Rect.new(xx,yy,next_bitmap.width/4,next_bitmap.height/2))
  400.     contents.blt(x,y,next_bitmap,Rect.new(0,next_bitmap.height/8,next_bitmap.width/12,next_bitmap.height/8))
  401.   end
  402. end
  403.  
  404. class Window_FormStat < Window_Base
  405.   def initialize
  406.     super(0,48+(Graphics.height-48)/2,Graphics.width/5*2,(Graphics.height-48)/2)
  407.     refresh
  408.   end
  409.   def refresh
  410.     contents.clear
  411.     change_color(system_color)
  412.     draw_text(0,line_height,contents.width,line_height,"Class:")
  413.     draw_text(0,line_height*2,contents.width/2,line_height,Vocab::hp)
  414.     draw_text(contents.width/2,line_height*2,contents.width/2,line_height,Vocab::mp)
  415.     draw_text(0,line_height*3,contents.width/2,line_height,Vocab::param(2))
  416.     draw_text(contents.width/2,line_height*3,contents.width/2,line_height,Vocab::param(3))
  417.     draw_text(0,line_height*4,contents.width/2,line_height,Vocab::param(4))
  418.     draw_text(contents.width/2,line_height*4,contents.width/2,line_height,Vocab::param(5))
  419.     draw_text(0,line_height*5,contents.width/2,line_height,Vocab::param(6))
  420.     draw_text(contents.width/2,line_height*5,contents.width/2,line_height,Vocab::param(7))
  421.     contents.fill_rect(contents.width/2-2,line_height*2.5,1,line_height*3,Color.new(155,155,155))
  422.     return unless @actor
  423.     change_color(normal_color)
  424.     draw_actor_graphic(@actor,contents.width/2,32)
  425.     draw_text(0,line_height,contents.width,line_height,@actor.class.name,2)
  426.     draw_text(0,line_height*2,contents.width/2,line_height,@actor.mhp,2)
  427.     draw_text(contents.width/2,line_height*2,contents.width/2,line_height,@actor.mmp,2)
  428.     draw_text(0,line_height*3,contents.width/2,line_height,@actor.atk,2)
  429.     draw_text(contents.width/2,line_height*3,contents.width/2,line_height,@actor.def,2)
  430.     draw_text(0,line_height*4,contents.width/2,line_height,@actor.mat,2)
  431.     draw_text(contents.width/2,line_height*4,contents.width/2,line_height,@actor.mdf,2)
  432.     draw_text(0,line_height*5,contents.width/2,line_height,@actor.agi,2)
  433.     draw_text(contents.width/2,line_height*5,contents.width/2,line_height,@actor.luk,2)
  434.   end
  435.   def set_actor(actor)
  436.     return if @actor == actor
  437.     @actor = actor
  438.     refresh
  439.   end
  440. end
  441.  
  442. class Scene_Menu
  443.   def command_formation
  444.     SceneManager.call(Scene_Formation)
  445.   end
  446. end
  447.  
  448. class Window_MenuCommand
  449.   def formation_enabled
  450.     true
  451.   end
  452. end
RAW Paste Data