[XP] Tons of Add-ons

Started by Blizzard, January 09, 2008, 08:50:47 am

Previous topic - Next topic

Wraith89

There might be a bug with this particular fix and I haven't quite pinpointed it yet but it only affects the blue magic user. At some points, using any skill may direct the wrong targets. For example, using an item gets used on the enemy (imagine my surprise using a 100% HP/MP item on a major boss!) or using an offensive skill attacks your party instead! It seems to have only happened since this fix was implemented, but I'll keep testing to see what exactly triggers this. It's not as noticeable as the 'not enough MP' bug from earlier.

KK20

The targets.any? addition should only be applied to Blue Magic Skill IDs, not just any skill. You should be able to confirm this easily by putting a print statement below it
    if BLUE_MAGIC_IDS.include?(battler.current_action.skill_id) && targets.any?
      print 'blue magic used!'
      targets.each {|target| target.damage = nil}
If you ever figure out how to reproduce it (even if not consistently), you should provide your scripts file. I'm leaning towards a different script being the problem.

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!

Blizzard

July 11, 2022, 05:55:07 am #1002 Last Edit: July 12, 2022, 05:25:48 am by Blizzard
Quote from: KK20 on June 26, 2022, 08:39:02 pm
Quote from: Blizzard on June 26, 2022, 05:16:47 pmDo I need to fix anything on my end in the original script?
I think only the targets.any? fix. If the user is unable to use the skill in make_skill_action_result, the alias still returns an empty list of targets, I think.

I guess I can take a look at it. Or feel free to just post a fixed version here and I'll update the main script with it.

Also, what about this:

Quote from: KK20 on June 02, 2021, 03:29:39 am
Quote from: SolarisSpell on June 01, 2021, 04:52:07 pmIf I change these vales, nothing happen. I even tried using script calls as it says in the instructions with no result.
-squints-
-CTRL + F's the script-

...Blizzard what the fuck. How did no one ever report this?


Good question. O_o I never tried changing those colors. Maybe I just defined the constants and never really implemented their usage.

EDIT: Ok, I will add the targets.any? fix and add the unlearnable skills array for Blue Magic Status. I will also fix the Minimap colors. The new version will be up later today.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

Wraith89

Quote from: KK20 on June 30, 2022, 12:13:27 amThe targets.any? addition should only be applied to Blue Magic Skill IDs, not just any skill. You should be able to confirm this easily by putting a print statement below it
    if BLUE_MAGIC_IDS.include?(battler.current_action.skill_id) && targets.any?
      print 'blue magic used!'
      targets.each {|target| target.damage = nil}
If you ever figure out how to reproduce it (even if not consistently), you should provide your scripts file. I'm leaning towards a different script being the problem.

Actually, yeah I don't think it has anything to do with Tons so it probably doesn't belong here. I think I found the culprit. It was the 'Target Anyone' script that I put in and I made it so that the Blue Magic skill can target either ally or foe. I also made some adjustments to make it usable with Wecoc's VX Ace Target Scope. I haven't found a way to fix it but there definitely are weird things that happen sometimes with the blue magic user, and I think it happens when I am using a potion at low HP or something and it goes to the enemy. Still inconsistent with replicating the bug however but I'll probably post some other thread if I figure it out completely.

=begin
===============================================================================
Target Anyone Scope
Version 1.0

By KK20
===============================================================================
 -[ Introduction ]-
 This small script allows the player to make single target scopes reverse its
 intended target. In other words, you can now choose to Heal a monster or one
 of your allies.
 
 -[ Instructions ]-
 1.) Scroll down to the configurations and locate Constant TARGET_ANYONE_TAG.
     Change the string associated with it if you like.
 2.) Create a new element in the Database. Name this new element the same as you
     have TARGET_ANYONE_TAG assigned to.
 3.) Apply this new element to skills or items that you wish to have this
     effect.
 
     ~ NOTE: The effect will only work if you set the scope to "One Enemy"
             or "One Ally".

 -[ Compatibility ]-
 * This script was made with the default battle system in mind. Custom battle
   scripts will most likely not work with this script without edits.
 * Not tested with SDK
 * Changes made to Game_Actor, Game_Battler, and Scene_Battle
 
Heretic Additions:

 Bugfixes:  Fixed a bug that selected wrong Target Type by cancelling, then
   reselecting the same Item or Skill.
 
 
===============================================================================
Credits:
KK20 - Writing this script
Charlie Fleed - For the idea
===============================================================================
=end

#===========#
# Configure #
#===========#

# The element ID's name that allows the user to target any one battler
TARGET_ANYONE_TAG = "DoubleTarget"

#===============#
# End Configure #
#===============#

#-------------------------------------------------------------------------
# Class Game Actor
#-------------------------------------------------------------------------
class Game_Actor < Game_Battler
  attr_accessor :changed_scope
 
  alias call_init_again initialize
  def initialize(actor_id)
    @changed_scope = false
    call_init_again(actor_id)
  end
 
  def clear
    super
    @changed_scope = false
    @target_type = nil
  end 
 
end

#-------------------------------------------------------------------------
# Class Game Battler
#-------------------------------------------------------------------------
class Game_Battler
  #--------------------------------------------------------------------------
  # * Calculating Element Correction
  #     element_set : element
  #--------------------------------------------------------------------------
  def elements_correct(element_set)
    # If not an element
    if element_set == []
      # Return 100
      return 100
    end
    # Return the weakest object among the elements given
    # * "element_rate" method is defined by Game_Actor and Game_Enemy classes,
    #    which inherit from this class.
    weakest = -100
    for i in element_set
      # Skips the "Target anyone" element to avoid damage miscalculations
      next if i == $data_system.elements.index(TARGET_ANYONE_TAG)
      weakest = [weakest, self.element_rate(i)].max
    end
    return weakest
  end
end

#-------------------------------------------------------------------------
# Class Scene Battle
#-------------------------------------------------------------------------
class Scene_Battle
  #--------------------------------------------------------------------------
  # * Frame Update (actor command phase : skill selection)
  #--------------------------------------------------------------------------
  def update_phase3_skill_select
    # Make skill window visible
    @skill_window.visible = true
    # Update skill window
    @skill_window.update
    # If B button was pressed
    if Input.trigger?(Input::B)
      # Play cancel SE
      $game_system.se_play($data_system.cancel_se)
      # End skill selection
      end_skill_select
      return
    end
    # If C button was pressed
    if Input.trigger?(Input::C)
      # Get currently selected data on the skill window
      @skill = @skill_window.skill
      # If it can't be used
      if @skill == nil or not @active_battler.skill_can_use?(@skill.id)
        # Play buzzer SE
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      # Play decision SE
      $game_system.se_play($data_system.decision_se)
      # Set action
      @active_battler.current_action.skill_id = @skill.id
      # Make skill window invisible
      @skill_window.visible = false
      # If effect scope is single enemy or single ally and can target anyone
      if @skill.element_set.include?($data_system.elements.index(TARGET_ANYONE_TAG)) and
      (@skill.scope == 1 or @skill.scope == 3)
        # Define starting position of the arrow
        @orig_scope = @skill.scope
        start_enemy_select if @skill.scope == 1
        start_actor_select if @skill.scope == 3
        @any_target = true
      elsif @skill.scope == 1 
        # Start enemy selection
        start_enemy_select
      # If effect scope is single ally
      elsif @skill.scope == 3 or @skill.scope == 5
        # Start actor selection
        start_actor_select
      # If scope is all enemies or allies
      elsif [2,4,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28].include?(@skill.scope)
        start_select_all(@skill.scope)
        @any_target = true if @skill.element_set.include?($data_system.elements.index(TARGET_ANYONE_TAG))
      # If effect scope is not single
      else
        # End skill selection
        end_skill_select
        # Go to command input for next actor
        phase3_next_actor
      end
      return
    end
  end
  #--------------------------------------------------------------------------
  # * Frame Update (actor command phase : item selection)
  #--------------------------------------------------------------------------
  def update_phase3_item_select
    # Make item window visible
    @item_window.visible = true
    # Update item window
    @item_window.update
    # If B button was pressed
    if Input.trigger?(Input::B)
      # Play cancel SE
      $game_system.se_play($data_system.cancel_se)
      # End item selection
      end_item_select
      return
    end
    # If C button was pressed
    if Input.trigger?(Input::C)
      # Get currently selected data on the item window
      @item = @item_window.item
      # If it can't be used
      unless $game_party.item_can_use?(@item.id)
        # Play buzzer SE
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      # Play decision SE
      $game_system.se_play($data_system.decision_se)
      # Set action
      @active_battler.current_action.item_id = @item.id
      # Make item window invisible
      @item_window.visible = false
      # If effect scope is single enemy or single ally and can target anyone
      if @item.element_set.include?($data_system.elements.index(TARGET_ANYONE_TAG)) and
      (@item.scope == 1 or @item.scope == 3)
        # Define starting position of the arrow
        @orig_scope = @item.scope
        start_enemy_select if @item.scope == 1
        start_actor_select if @item.scope == 3
        @any_target = true
      # If effect scope is single enemy
      elsif @item.scope == 1 
        # Start enemy selection
        start_enemy_select
      # If effect scope is single ally
      elsif @item.scope == 3 or @item.scope == 5
        # Start actor selection
        start_actor_select
      # If scope is all enemies or allies
      elsif [2,4,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28].include?(@item.scope)
        start_select_all(@item.scope)
        @any_target = true if @item.element_set.include?($data_system.elements.index(TARGET_ANYONE_TAG))
      # If effect scope is not single
      else
        # End item selection
        end_item_select
        # Go to command input for next actor
        phase3_next_actor
      end
      return
    end
  end
  #--------------------------------------------------------------------------
  # * Frame Update (actor command phase : enemy selection)
  #--------------------------------------------------------------------------
  def update_phase3_enemy_select
    # Update enemy arrow
    @enemy_arrow.update
    # If this skill/item can target anyone
    if @any_target == true
      # If player pressed the key to change targets
      if Input.trigger?(Input::DOWN)
        # Play decision SE
        $game_system.se_play($data_system.cursor_se)
        # Initialize actor select, end enemy select
        end_enemy_select
        if [2,4].include?(@skill_window != nil ? @skill.scope : @item.scope)
          start_select_all(4)
        else
          start_actor_select
        end
        @active_battler.changed_scope = !@active_battler.changed_scope
        # Stop processing
        return
      end
    end
    # If B button was pressed
    if Input.trigger?(Input::B)
      # Play cancel SE
      $game_system.se_play($data_system.cancel_se)
      # End enemy selection
      end_enemy_select
      @active_battler.changed_scope = false     
      @any_target = false
      return
    end
    # If C button was pressed
    if Input.trigger?(Input::C)
      # Play decision SE
      $game_system.se_play($data_system.decision_se)
      # Set action
      @active_battler.current_action.target_index = @enemy_arrow.index
      # End enemy selection
      end_enemy_select
      # If skill window is showing
      if @skill_window != nil
        # End skill selection
        end_skill_select
      end
      # If item window is showing
      if @item_window != nil
        # End item selection
        end_item_select
      end
      @any_target = false
      # Go to command input for next actor
      phase3_next_actor
    end
  end
  #--------------------------------------------------------------------------
  # * Frame Update (actor command phase : actor selection)
  #--------------------------------------------------------------------------
  def update_phase3_actor_select
    # Update actor arrow
    @actor_arrow.update
    # If this skill/item can target anyone
    if @any_target == true
      # If player pressed the key to change targets
      if Input.trigger?(Input::UP)
        # Play decision SE
        $game_system.se_play($data_system.cursor_se)
        # Initialize actor select, end enemy select
        end_actor_select
        if [2,4].include?(@skill_window != nil ? @skill.scope : @item.scope)
          start_select_all(2)
        else
          start_enemy_select
        end
        @active_battler.changed_scope = !@active_battler.changed_scope
        # Stop processing
        return
      end
    end
    # If B button was pressed
    if Input.trigger?(Input::B)
      # Play cancel SE
      $game_system.se_play($data_system.cancel_se)
      # End actor selection
      end_actor_select
      @active_battler.changed_scope = false     
      @any_target = false
      return
    end
    # If C button was pressed
    if Input.trigger?(Input::C)
      # Play decision SE
      $game_system.se_play($data_system.decision_se)
      # Set action
      @active_battler.current_action.target_index = @actor_arrow.index
      # End actor selection
      end_actor_select
      # If skill window is showing
      if @skill_window != nil
        # End skill selection
        end_skill_select
      end
      # If item window is showing
      if @item_window != nil
        # End item selection
        end_item_select
      end
      @any_target = false
      # Go to command input for next actor
      phase3_next_actor
    end
  end
  #--------------------------------------------------------------------------
  # * Set Targeted Battler for Skill or Item
  #     scope : effect scope for skill or item
  #--------------------------------------------------------------------------
  alias modded_scopes_change_targets set_target_battlers
  def set_target_battlers(scope)
    # If the actor has changed the scope of the skill/item
    if @active_battler.is_a?(Game_Actor) and @active_battler.changed_scope
      # Reset the variable
      @active_battler.changed_scope = false
      # Determine targets
      case scope
      when 1 # single ally
        index = @active_battler.current_action.target_index
        @target_battlers.push($game_party.smooth_target_actor(index))
      when 2 # allies
        for actor in $game_party.actors
          if actor.exist?
            @target_battlers.push(actor)
          end
        end
      when 3 # single enemy
        index = @active_battler.current_action.target_index
        @target_battlers.push($game_troop.smooth_target_enemy(index))
      when 4 # troop
        for enemy in $game_troop.enemies
          if enemy.exist?
            @target_battlers.push(enemy)
          end
        end
      end
    else
      # Call original method
      modded_scopes_change_targets(scope)
    end
  end
  #--------------------------------------------------------------------------
  # * Battle Ends
  #     result : results (0:win 1:lose 2:escape)
  #--------------------------------------------------------------------------
  alias reset_changed_scopes battle_end
  def battle_end(result)
    # Reset all the actors' changed_scope variable
    for actor in $game_party.actors
      actor.changed_scope = false
    end
    # Call alias
    reset_changed_scopes(result)
  end
 
end

#===========================


#==============================================================================
# ** Arrow_Base
#------------------------------------------------------------------------------
#  This sprite is used as an arrow cursor for the battle screen. This class
#  is used as a superclass for the Arrow_Enemy and Arrow_Actor classes.
#==============================================================================

class Arrow_Base < Sprite
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_accessor   :target_all                    # Cursor Targets All
  #--------------------------------------------------------------------------
  # * Object Initialization
  #     viewport : viewport
  #--------------------------------------------------------------------------
  alias arrow_all_initialize initialize
  def initialize(viewport)
    # Call Original
    arrow_all_initialize(viewport)
    # New Variable
    @target_all = false
  end
end

#==============================================================================
# ** Scene_Battle (part 1)
#------------------------------------------------------------------------------
#  This class performs battle screen processing.
#==============================================================================

class Scene_Battle
  #--------------------------------------------------------------------------
  # * Start All Selection
  #--------------------------------------------------------------------------
  def start_select_all(scope)
    # If Scope is All Enemies
    if scope == 2 or scope == 8 or scope == 9 or scope == 10 or scope == 11 or scope == 12 or scope == 13 or scope == 14
      # Make enemy arrow
      @enemy_arrow = Arrow_Enemy.new(@spriteset.viewport1)
      # Cycle Arrow over each Enemy     
      @enemy_arrow.target_all = true
      # Associate help window
      @enemy_arrow.help_window = @help_window
      # Disable actor command window
      @actor_command_window.active = false
      @actor_command_window.visible = false 
    # IF Scope is All Allies
    elsif scope == 4 or scope == 15 or scope == 16 or scope == 17 or scope == 18 or scope == 19 or scope == 20 or scope == 21
      # Make actor arrow
      @actor_arrow = Arrow_Actor.new(@spriteset.viewport2)
      # Cycle Arrow over each Enemy
      @actor_arrow.target_all = true
      # Associate help window
      @actor_arrow.help_window = @help_window
      # Disable actor command window
      @actor_command_window.active = false
      @actor_command_window.visible = false
    end
  end 
end

#==============================================================================
# ** Arrow_Actor
#------------------------------------------------------------------------------
#  This arrow cursor is used to choose an actor. This class inherits from the
#  Arrow_Base class.
#==============================================================================

class Arrow_Actor < Arrow_Base
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  def update
    super
    # If Entire Party
    if @target_all
      self.visible = true
      @index += 1
      @index %= $game_party.actors.size
      # Set sprite coordinates
      if self.actor != nil
        self.x = self.actor.screen_x
        self.y = self.actor.screen_y
      end
      # Prevent Input
      return
    end
    # Cursor right
    if Input.repeat?(Input::RIGHT)
      $game_system.se_play($data_system.cursor_se)
      @index += 1
      @index %= $game_party.actors.size
    end
    # Cursor left
    if Input.repeat?(Input::LEFT)
      $game_system.se_play($data_system.cursor_se)
      @index += $game_party.actors.size - 1
      @index %= $game_party.actors.size
    end
    # Set sprite coordinates
    if self.actor != nil
      self.x = self.actor.screen_x
      self.y = self.actor.screen_y
    end
  end
  #--------------------------------------------------------------------------
  # * Help Text Update
  #--------------------------------------------------------------------------
  def update_help
    # If targetting All Allies
    if @target_all
      # Display Entire Party in Help Window, 1 = Center
      @help_window.set_text("All Allies", 1)
    else
      # Display actor status in help window
      @help_window.set_actor(self.actor)
    end
  end
end

#==============================================================================
# ** Arrow_Enemy
#------------------------------------------------------------------------------
#  This arrow cursor is used to choose enemies. This class inherits from the
#  Arrow_Base class.
#==============================================================================

class Arrow_Enemy < Arrow_Base
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  def update
    super
    # If All Enemies
    if @target_all
      self.visible = true
      @index += 1
      @index %= $game_troop.enemies.size
      # Skip if indicating a nonexistant enemy
      $game_troop.enemies.size.times do
        break if self.enemy.exist?       
        @index += 1
        @index %= $game_troop.enemies.size
      end     
      # Set sprite coordinates
      if self.enemy != nil
        self.x = self.enemy.screen_x
        self.y = self.enemy.screen_y
      end
      # Prevent Input
      return
    end
   
    # Skip if indicating a nonexistant enemy
    $game_troop.enemies.size.times do
      break if self.enemy.exist?
      @index += 1
      @index %= $game_troop.enemies.size
    end
    # Cursor right
    if Input.repeat?(Input::RIGHT)
      $game_system.se_play($data_system.cursor_se)
      $game_troop.enemies.size.times do
        @index += 1
        @index %= $game_troop.enemies.size
        break if self.enemy.exist?
      end
    end
    # Cursor left
    if Input.repeat?(Input::LEFT)
      $game_system.se_play($data_system.cursor_se)
      $game_troop.enemies.size.times do
        @index += $game_troop.enemies.size - 1
        @index %= $game_troop.enemies.size
        break if self.enemy.exist?
      end
    end
    # Set sprite coordinates
    if self.enemy != nil
      self.x = self.enemy.screen_x
      self.y = self.enemy.screen_y
    end
  end
  #--------------------------------------------------------------------------
  # * Help Text Update
  #--------------------------------------------------------------------------
  def update_help
    # If targetting All Enemies
    if @target_all
      # Display Entire Party in Help Window, 1 = Center
      @help_window.set_text("All Enemies", 1)
    else   
      # Display enemy name and state in the help window
      @help_window.set_enemy(self.enemy)
    end
  end
end

goblinhoney

Hello, I think I'd like to report a bug or just have a question? I added the 3 scripts as instructed, and basically only had a couple of the addons set to true. Caterpillar, full screen, and custom controls. My issue was when trying to go full screen... When I hit f12, the game crashes. I don't actually know if that is the button to go full screen, or why I thought it would be. On a blank project with no add-ons, f12 just refreshes the game to title screen?

I tried removing some of my other custom scripts or addons and got the same error. I made a blank project with only the three scripts in the OP, and the project crashes when pressing f12.

So two things, first: how am I supposed to enable to fullscreen add-on once I set it to true?

Second, why does the game crash when pressing f12 with these scripts added to a project?

Script 'bliz2' (second script from OP) line 1329: SystemStackError occurred. stack level too deep.

The script line in question seems to be related to font? I am using Recoleta font for the game, but it throws up this error on a new project with default fonts too. Don't have the super override feature of this pack enabled anyway.

class Bitmap

  alias init_font_override_later initialize
  def initialize(w, h = nil)
    if w.is_a?(Numeric) && h.is_a?(Numeric)
      init_font_override_later(w, h)
    else
      init_font_override_later(w)
    end
    if TONS_OF_ADDONS::ULTIMATE_FONT_OVERRIDE
      if $game_system != nil && $game_system.fontname != nil &&
          !$scene.is_a?(Scene_Title)
        self.font.name = $game_system.fontname
        self.font.size = $game_system.fontsize
      else
        self.font.name = Font.default_name
        self.font.size = Font.default_size
      end
    end
  end
 
end
 

KK20


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!

RhineQueen

So it looks like I'm not the first person to hit this point, but I had a question about Multi-Hit that was asked a while ago, but no clear answer was given.

What is the syntax to make successive hits target the same monster? It says to separate with commas to make them hit different targets, but I don't know what to use otherwise since other punctuation throws a syntax error. Still kinda new to Ruby but I thought it only accepted commas to separate array items so I'm a bit lost.

Also, I was wondering if there was any way to make Absorb Skills and Multi-Hit play nicely? KK20 said it didn't seem like it, but that was 2017 and I know it's a long shot, but I'm nothing if not an optimist and maybe there's been a change or update since then.

KK20

You're talking about this?
#   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
That's if you want attacks to randomly hit a different target. If you want all the attacks to hit the same target, you don't put anything in those arrays.

I also believe you're referring to this post regarding multi-hit, but that's actually a completely different script. Wraith was using "DerVVulfman Multi-Strike", not Multi-Hit in Tons of Add-ons.

With that said, I don't think I've ever tried using multi-hit and absorb together, but knowing Blizz I can't imagine them being incompatible.

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!

RhineQueen

Thanks for the prompt reply! Sorry I'm not as prompt with this myself. I've been a bit busy recently.

Thanks for helping clarify the syntax there regarding the multi-hit. I must have misread something along the way.

As for the Multi-Hit/Absorb, just enabling the Absorb addon, even without any absorb skills declared in the script causes all of the Multi-Hit weapons, skills etc. to stop multihitting. No errors or anything else, just one hit.

KK20

So it would seem that the absorb script does not call upon the aliased phase4_step5 methods before it:
Code: ruby
  alias update_phase4_step5_hpsp_absorb_later update_phase4_step5
  def update_phase4_step5(battler = nil)
    if $game_system.ABSORB_HP_SP
      @status_window.refresh
      @help_window.visible, damages = false, 0
      @target_battlers.each {|target|
          if target.damage != nil
            target.damage_pop = true
            damages += target.damage if target.damage.is_a?(Numeric)
          end}
      if check_absorb(@active_battler, @active_battler.current_action.skill_id,
          damages)
        @status_window.refresh
      end
      @skill, @phase4_step = nil, 6
    elsif battler == nil
      update_phase4_step5_hpsp_absorb_later
    else
      update_phase4_step5_hpsp_absorb_later(battler)
    end
  end
In this snip above, we satisfy the first conditional if $game_system.ABSORB_HP_SP because we turned it on. We execute all the code after it up until elsif battler == nil. Nowhere in between do we ever call upon the alias update_phase4_step5_hpsp_absorb_later, which is necessary since the Multi-Hit script modifies the method update_phase4_step5 as well.

What you can try doing is making the edit here:
Code: ruby
      @skill, @phase4_step = nil, 6
      update_phase4_step5_hpsp_absorb_later(battler) # <=====
    elsif battler == nil
That seemed to work fine with Multi-Hit, but I didn't test it with any of the other scripts in Tons.

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!

RhineQueen

Looks like that's worked a treat. I'm gonna do some more thorough testing after a good night's sleep, but there's no errors or anything else obviously broken. Thanks for your help!

KK20

Another bug fix for Multi-Hit (replace Scene_Battle within the script):
Code: ruby
class Scene_Battle

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

  def repeating_action?
    return (@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 if @active_battler == nil || !$game_system.MULTI_HIT
    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
    return if !$game_system.MULTI_HIT
    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
    return if !$game_system.MULTI_HIT
    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
    if @repeat[2] == 5
      sp_cost = @skill.sp_cost
      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
    make_skill_action_result_multi_hit_later
  end
 
  alias make_item_action_result_multi_hit_later make_item_action_result
  def make_item_action_result
    if @repeat[2] == 5
      $game_party.gain_item(@item.id, 1)
      @status_window.refresh
    end
    make_item_action_result_multi_hit_later
  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
It addresses MP cost issues and consuming items multiple times.
Original thread: https://forums.rpgmakerweb.com/index.php?threads/xp-tons-of-add-ons-multi-hit-bug.171550/

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!

Tamarin

The Status Effects as Icons script has a bug where the icons sometimes don't update properly when selecting between enemies that have different effects.  This happens when switching between two identical enemies with the same amount of status effects.  The icons also display on top of the enemy's name instead of being adjacent to it.

I posted screenshots of the bug in the original thread: https://forums.rpgmakerweb.com/index.php?threads/xp-tons-of-add-ons-status-icon-bugs.171954/

Aunknown_Artist

I don't know if you still update this script, but I was wondering if you could possibly consider adding the ability to animate battlebacks with effects in engine (such as swirl,scrolling, and wave effects) to achieve earthbound like battlebacks without having to hand make each frame.   
-------------------------------------------------------------------------------------------------------
I make game (:
game have bug ):
I fix bug (:
-------------------------------------------------------------------------------------------------------

KK20

Quote from: Aunknown_Artist on July 14, 2026, 06:18:45 pmI don't know if you still update this script, but I was wondering if you could possibly consider adding the ability to animate battlebacks with effects in engine (such as swirl,scrolling, and wave effects) to achieve earthbound like battlebacks without having to hand make each frame.   
Tons will only get updated if there's any major bugs reported and Blizzard finds the time to do it.

As for your request, those kind of effects are more akin to using shaders, which XP does not natively support. It would require a DLL (C/C++ code) to modify the image's bitmap data in memory, and having the script call this method every frame to update it. This is quite complex to do and is beyond the scope of what Tons aims to be.

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!

Aunknown_Artist

I believe I have found a typo on line 3722 of the first part of the script, its says " Not that this works for actors AND for enemies." when i believe it is supposed to say " "Note" that this works for actors AND for enemies." 
-------------------------------------------------------------------------------------------------------
I make game (:
game have bug ):
I fix bug (:
-------------------------------------------------------------------------------------------------------