[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