[XP] Blizzard's Multiple Hits Script (Standalone Version)

Started by Simon Greedwell, September 30, 2013, 08:15:40 am

Previous topic - Next topic

Simon Greedwell

Greetings and salutations.

I'd like a standalone version of Blizzard's Multiple Hits script included in Tons of Add-ons. I'm asking for this due to Tons of Add-ons being incompatible with the other scripts in my game.

Those are the scripts I'm currently using:

- FMOD Ex Audio
- Stormtronic Custom Menu Screen
- Interpreter Fix
- Dargor's Large Party Script
- HP Absortion Skills
- Law's Custom Equipment Screen
- Law's Custom Skill Screen
- Weapon/Armor HP/SP Plus by Blizzard
- Jen's Final Fantasy-styled item window
- Large Party Scene Shop & Window Expansion by DerWulfman
- Absorb, Null, and Weak Armors by Bearcat.
Bury with my...money!

KK20

UPDATE: To all those who happen to stumble upon this, I am updating this to version 1.6 as some bugs and feature requests came to light in this thread: https://forums.rpgmakerweb.com/index.php?threads/multi-hit-script-activates-animation-mulitple-times-per-hit.122428/
I will see if I can get Blizz to update Tons of Add-ons.

Give this a shot:
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
# Multi-Hit by Blizzard
# Version: 1.6
# Type: Weapon/Skill/Enemy Enhancement
# Date: 12.8.2007
# Date 1.3b: 23.2.2008
# Date 1.4b: 23.7.2008
# Date 1.5b: 19.10.2008
# Date 1.51b: 6.10.2009
# Date 1.6: 21.9.2020
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
#
# Compatibility:
#
#   95% compatible with SDK 1.x. 70% compatible with SDK 2.x. Might be
#   incompatible with exotic skills and/or CBS-es. Compatible with CRLS 5.1b or
#   higher.
#
#
# Explanation:
#
#   This add-on will allow that skills, weapons and enemies attack more than
#   once.
#
# new in v1.3b:
#   - now you can define weapons/skills/enemies which's other attacks will
#     target a random target instead of the originally chosen target
#   - now beta
#
# new in v1.4b:
#   - better compatibility with SP Cost Mod
#   - improved coding
#   
# new in v1.5b:
#   - added Multi-Hit items
#
# new in v1.6
#   - option to play animation only once instead of per hit
#   - prevents help window from popping up per hit
#   - can randomize the number of hits via using a Range
#   - compatible with LockeZ Sacrifice HP script
#   - bug fixes
#   
#   
# Configuration:
#   
#   Set up the following constants to configure the script:
#   
#   WEAPON_RANDOM - add any weapon IDs here and separate them with commas to
#                   make those specific weapons attack another random target
#                   for each other hit than the first
#   SKILL_RANDOM  - add any skill IDs here and separate them with commas to
#                   make those specific skills attack another random target
#                   for each other hit than the first
#   ITEM_RANDOM   - add any item IDs here and separate them with commas to
#                   make those specific items attack another random target
#                   for each other hit than the first
#   ENEMY_RANDOM  - add any enemy IDs here and separate them with commas to
#                   make those specific enemies attack another random target
#                   for each other hit than the first
#   
#   Further there are 4 configurations. Configuration 1 is for weapons,
#   Configuration 2 is for skills, Configuration 3 is for items and
#   Configuration 3 is for normal enemy attacks. Use following template to set
#   up how many hits should be done:
#
#     when ID then return HITS
#
#   ID   - ID of weapon, skill, item or enemy, depending on the configuration
#          number
#   HITS - number of hits; can be a single integer or a range of min..max
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=

#==============================================================================
# module BlizzCFG
#==============================================================================

module BlizzCFG
 
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# START Basic Configuration
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  WEAPON_RANDOM = []
  SKILL_RANDOM = [57]
  ITEM_RANDOM = []
  ENEMY_RANDOM = [1]
  SHOW_ANIMATION_PER_HIT = true
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# END Basic Configuration
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

  def self.weapon_hits(id)
    case id
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# START Configuration 1
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    when 1 then return 2
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# END Configuration 1
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    end
    return 1
  end
 
  def self.skill_hits(id)
    case id
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# START Configuration 2
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    when 57 then return 2..5
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# END Configuration 2
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    end
    return 1
  end
 
  def self.item_hits(id)
    case id
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# START Configuration 3
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    when 1 then return 3
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# END Configuration 3
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    end
    return 1
  end
 
  def self.enemy_hits(id)
    case id
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# START Configuration 4
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    when 1 then return 2
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# END Configuration 4
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    end
    return 1
  end
 
end

#==============================================================================
# Scene_Battle
#==============================================================================

class Scene_Battle

  def rand_hits(value)
    return value if value.is_a?(Integer)
    rand(value.max - value.min + 1) + value.min
  end

  def repeating_action?
    (@repeat[1] - @repeat[0]) > 0
  end

  alias update_phase4_step1_multi_hit_later update_phase4_step1
  def update_phase4_step1(battler = nil)
    if battler != nil
      update_phase4_step1_multi_hit_later(battler)
      return
    end
    update_phase4_step1_multi_hit_later
    @repeat = [1, 1, 0]
    return unless @active_battler != nil
    if @active_battler.current_action.kind == 0
      if @active_battler.current_action.basic == 0
        if @active_battler.is_a?(Game_Actor)
          hits = rand_hits(BlizzCFG.weapon_hits(@active_battler.weapon_id))
        elsif @active_battler.is_a?(Game_Enemy)
          hits = rand_hits(BlizzCFG.enemy_hits(@active_battler.id))
        end
        @repeat = [hits, hits, 2]
      end
    elsif @active_battler.current_action.kind == 1
      @repeat[2] = 3
    elsif @active_battler.current_action.kind == 2
      @repeat[2] = 4
    end
  end

  alias update_phase4_step2_multi_hit_later update_phase4_step2
  def update_phase4_step2(battler = nil)
    if battler != nil
      update_phase4_step2_multi_hit_later(battler)
      return
    end
    update_phase4_step2_multi_hit_later
    if @phase4_step != 1
      if @repeat[2] == 3
        hits = rand_hits(BlizzCFG.skill_hits(@skill.id))
        @repeat = [hits, hits, 5]
      elsif @repeat[2] == 4
        hits = rand_hits(BlizzCFG.item_hits(@item.id))
        @repeat = [hits, hits, 5]
      end
    end
    if repeating_action?
      unless BlizzCFG::SHOW_ANIMATION_PER_HIT
        @animation1_id = 0
        @animation2_id = 0
      end
      @help_window.visible = false
    end
  end

  alias update_phase4_step3_multi_hit_later update_phase4_step3
  def update_phase4_step3
    update_phase4_step3_multi_hit_later
    @active_battler.white_flash = false  if repeating_action?
  end

  alias update_phase4_step4_multi_hit_later update_phase4_step4
  def update_phase4_step4
    update_phase4_step4_multi_hit_later
    @wait_count = 0 if repeating_action? && !BlizzCFG::SHOW_ANIMATION_PER_HIT
  end

  alias update_phase4_step5_multi_hit_later update_phase4_step5
  def update_phase4_step5(battler = nil)
    if battler != nil
      update_phase4_step5_multi_hit_later(battler)
      return
    end
    update_phase4_step5_multi_hit_later
    if @active_battler.current_action.kind == 1
      if BlizzCFG::SKILL_RANDOM.include?(@skill.id)
        if @active_battler.is_a?(Game_Actor)
          @active_battler.current_action.decide_random_target_for_actor
        elsif @active_battler.is_a?(Game_Enemy)
          @active_battler.current_action.decide_random_target_for_enemy
        end
      else
        if @active_battler.is_a?(Game_Actor)
          @active_battler.current_action.decide_last_target_for_actor
        elsif @active_battler.is_a?(Game_Enemy)
          @active_battler.current_action.decide_last_target_for_enemy
        end
      end
    elsif @active_battler.current_action.kind == 2
      if BlizzCFG::ITEM_RANDOM.include?(@item.id)
        if @active_battler.is_a?(Game_Actor)
          @active_battler.current_action.decide_random_target_for_actor
        elsif @active_battler.is_a?(Game_Enemy)
          @active_battler.current_action.decide_random_target_for_enemy
        end
      else
        if @active_battler.is_a?(Game_Actor)
          @active_battler.current_action.decide_last_target_for_actor
        elsif @active_battler.is_a?(Game_Enemy)
          @active_battler.current_action.decide_last_target_for_enemy
        end
      end
    elsif @active_battler.is_a?(Game_Actor)
      if BlizzCFG::WEAPON_RANDOM.include?(@active_battler.weapon_id)
        @active_battler.current_action.decide_random_target_for_actor
      else
        @active_battler.current_action.decide_last_target_for_actor
      end
    elsif @active_battler.is_a?(Game_Enemy)
      if BlizzCFG::ENEMY_RANDOM.include?(@active_battler.id)
        @active_battler.current_action.decide_random_target_for_enemy
      else
        @active_battler.current_action.decide_last_target_for_enemy
      end
    end
    @phase4_step = 2 if @repeat[0] > 1 && @repeat[2] > 0
    @repeat[0] -= 1
  end

  alias make_skill_action_result_multi_hit_later make_skill_action_result
  def make_skill_action_result(battler = nil, plus_id = nil)
    if battler != nil
      if plus_id != nil
        make_skill_action_result_multi_hit_later(battler, plus_id)
      else
        make_skill_action_result_multi_hit_later(battler)
      end
      return
    end
    make_skill_action_result_multi_hit_later
    if @repeat[2] == 5
      sp_cost = @skill.sp_cost
      @active_battler.sp += sp_cost
      @status_window.refresh
    end
  end
 
  # Compatibility fix for LockeZ Sacrifice HP
  if method_defined?(:sacrifice_hp)
    alias sacrifice_hp_if_not_repeating sacrifice_hp
    def sacrifice_hp(battler, action)
      sacrifice_hp_if_not_repeating(battler, action) unless @repeat[2] == 5
    end
  end
 
end

EDIT by Blizzard: I updated Tons with this. I added this message here so that I don't needlessly grave-dig the topic.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Simon Greedwell

September 30, 2013, 11:32:18 am #2 Last Edit: September 30, 2013, 06:03:56 pm by Simon Greedwell
Works perfectly. A thousand thanks are on the way.  :)

Edit: I meant to ask earlier but my Internet has been unstable all day: is there a way to make the name of the skill to show up once and not in every hit?
Bury with my...money!

KK20

Untested total guess.

  alias make_skill_action_result_multi_hit_later make_skill_action_result
  def make_skill_action_result(battler = nil, plus_id = nil)
    if battler != nil
      if plus_id != nil
        make_skill_action_result_multi_hit_later(battler, plus_id)
      else
        make_skill_action_result_multi_hit_later(battler)
      end
      return
    end
    make_skill_action_result_multi_hit_later
    @help_window.visible = false if (@repeat[1] - @repeat[0]) > 1 #<======================================= Add this here
    if @repeat[2] > 3
      sp_cost = @skill.sp_cost
      #----- you can remove these 3 lines if you want----
      if $game_system.SP_COST_MOD
        sp_cost = BlizzCFG.get_cost_mod(@active_battler.states, sp_cost)
      end
      #--------------------------------------------------
      @active_battler.sp += sp_cost
      @status_window.refresh
    end
  end

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Simon Greedwell

Bury with my...money!

KK20

Tested and it worked for me. You sure you did it right?

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Simon Greedwell

... Seems I didn't. Now it works perfectly. Another thousand thanks are on the way.  ;)
Bury with my...money!