Target Anyone
Authors: KK20
Version: 1.02
Type: Unique Skills
Key Term: Battle Add-on
IntroductionThis small script allows the player to make single target scopes reverse its intended target. In other words, you can now choose to Heal or cast Fire on a monster or one of your allies.
Yes, you can make enemies undead and attack them with Heal. Likewise, you can create armor that absorbs fire and cast Fire on your allies.
Features
- Player can choose to attack an enemy or an ally with skills that target One Actor/One Enemy
- ...that's pretty much it.
ScreenshotsNone--Can't really screenshot this.
DemoNone
ScriptBelow the default scripts and above Main.
If wishing to test for compatibility with another battle system, place this below it.
=begin
===============================================================================
Target Anyone Scope
Version 1.02
9/4/2013
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
===============================================================================
Credits:
KK20 - Writing this script
Charlie Fleed - For the idea
Heretic86 - Requesting and bug fixing/finding
===============================================================================
=end
#===========#
# Configure #
#===========#
# The element ID's name that allows the user to target any one battler
TARGET_ANYONE_TAG = "Target Any"
#===============#
# 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)
element_set = element_set.clone
# Remove any Excluded Elements from the element_set arg array
for i in element_set
if i == $data_system.elements.index(TARGET_ANYONE_TAG)
element_set.delete(i)
end
end
# 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
# Element with the Highest Rate means it is the Weakest
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 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 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 Updat (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
start_actor_select
@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
start_enemy_select
@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 3 # single enemy
index = @active_battler.current_action.target_index
@target_battlers.push($game_troop.smooth_target_enemy(index))
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
InstructionsIt should all be there in the script, right near the beginning of it.
To change scopes/target, use the UP and DOWN arrow keys.
CompatibilityMade with the default battle system in mind. Probably won't work with custom battle systems.
Not tested with SDK.
Modifies methods in Game_Battler, Game_Actor, and Scene_Battle.
Credits and Thanks
- KK20 - Creator
- Charlie Fleed - For the idea on how to implement this
- Heretic86 - Requesting, fixing a couple of bugs, and encouraging me to database it
Author's NotesNote that this only works for actors and not for enemies. In other words, the enemy is not programmed to heal your allies or attack its troop.
I have to point out how this script can be quite useful.
One idea I had was to use this script in conjunction with Blizzards Reflect Spell. Make an Boss Enemy that constantly casts very strong heals on itself. Use this script to cast Reflect on the Enemy instead of the Party. This very powerful Boss Enemy will be powerless if all of its efforts to heal itself only heal the party!
I have tried it, and it works just fine.
Another idea I had was to use Healing Items and Spells to Harm Undead. Since Undead are, well, Undead, Heals have the Opposite Effect! That works too, but I'll have to do some work to show how that is done.
Level Up!
This small script seems good and add nice feature to the battles.
it would give me good ideas for my project.
Level Up my FRIEND KK20 !
Minor bug.
decide_random_target_for_actor / enemy needs to match scope assigned by player. Otherwise, target an enemy with a friendly spell, and if the enemy is dead, it targets the party.
Not sure by what you mean. Give me an example of what happened.
This happens during Scope Change.
Set an actor to use an item or spell on an enemy that normally defaults to the Actors. Then kill that enemy before the spell is cast, and it will default back to Actors, not enemies.
Likewise with enemies (using Blizz's reflect spell to bounce effects), select Fire, target an Actor (with reflect)with Fire (because Enemy has Reflect also, and Fire defaults to Enemies), and spell targets Enemies by default if that Actor dies before the spell is cast.
IE, when the Target is killed prior to spell / item usage, a random target will be selected, but that random target is always the Original Scope (actors or enemies), not the Changed Scope. What I am suggesting is that if you try to cast Fire, change scope to cast on an Ally, then the Ally is killed, the randomly selected target should be the same scope, which, in this case would have Fire cast on a randomly selected Ally due to the scope change.
Does that make more sense?
At first I was like "Uh...no, it's attacking another enemy..." but it wasn't until I went into another battle that I saw the problem: Reset the @changed_scope variable back to false at the end of the battle.
Fixed and updated.
One of the reasons I pushed for this script to get put in the Database was so I could do this:
Early Version (so ignore 1.0), I suspect there are a couple of bugs, but basically it allows Healing and Resurrection to be treated as Elemental Effects. It took some extra work to allow for Elemental Resistances by inverting the effects on Undead. So now casting Heal on an Undead does Damage. Casting Resurrect on an Undead can cause Instant Death. I always thought this was a cool effect in old Final Fantasy games.
#===============================================================================
# Heal Harms Undead and Resurrect can cause Instant Death
# Target Anyone Scope Enhancement
#
# Author: Heretic
# Version: 1.0
#
# This script is most useful when combined with KK20's Target Anyone Script
# http://forum.chaos-project.com/index.php/topic,12640.0.html
#
#===============================================================================
#
# This script will cause Undead to have the opposite reaction to Healing and
# Resurrection Spells and Items. It is based on Elemental Resistance, so you
# can give Actors and Enemies Resistance to being healed. If you decide to
# have an Undead Actor, your Armor will use Elemental Defense and cut the
# effective rate by Half for each piece of Armor with Defense against your
# specified Elements. If you don't plan on having an Undead Actor, then
# you'll be better off by not putting on an Elemental Resistance to
# Healing as it just cuts its effectiveness.
#
# In plain English, Healing and Resurrection are now Elemental Effects and will
# work the same as Fire and what not. Healing will cause Damage. Resurrection
# has a chance to cause Instant Death. If you don't like the idea of Instant
# Death, dont use Resurrection as an Element and just replace it with Healing
# if you wish.
#
# To get this going takes some work.
#
# First, go to your Database -> System, Element Names and add Healing and / or
# Resurrection. Name them as you wish. Then you'll want to edit your Items
# Armor, Weapons, and Enemies and set them up as you wish. Check Resurrection
# (if you use it) for Items and Spells that Resurrect. Same goes for Healing.
# Give your Enemies (or Actors) Resistances to these Elements.
#
# A Rank of "A" will be the most effective. So if you use Healing on an Undead
# that has a Healing Rank of "A", it will do Maximum Damage. Ranks "B" to "D"
# will cause less and less damage.
#
# A Rank of "E" will do nothing. It results in 0 points of Damage. Nuff said.
#
# If the Rank is "F", it will cause the Opposite Effect. That is to say using
# a Rank of "F" on an Enemy for Healing will cause an Enemy to be Healed.
#
# --- CONFIGURATION ---
#
# Just in case you want to name your Healing and Resurrection Tags to something
# else, you can change the Tags below to whatever you want. I hope this will
# be helpful for Non English users of this little add on.
UNDEAD_ELEMENT_TAG = "vs Undead"
HEALING_ELEMENT_TAG = "Healing"
RESURRECTION_ELEMENT_TAG = "Resurrection"
#==============================================================================
# ** Game_Actor
#==============================================================================
class Game_Actor < Game_Battler
#--------------------------------------------------------------------------
# * Get Element Effectiveness
#--------------------------------------------------------------------------
def element_ranks
return $data_classes[@class_id].element_ranks
end
end
#==============================================================================
# ** Game_Enemy
#==============================================================================
class Game_Enemy < Game_Battler
#--------------------------------------------------------------------------
# * Get Element Effectiveness
#--------------------------------------------------------------------------
def element_ranks
return $data_enemies[@enemy_id].element_ranks
end
end
#-------------------------------------------------------------------------
# Class Game Battler
#-------------------------------------------------------------------------
class Game_Battler
#--------------------------------------------------------------------------
# * State Knockout - True if State has Knockout Properties
#--------------------------------------------------------------------------
def state_knockout?(state)
# If State Restriction Can't Move, Cant Get EXP and Regard as HP 0
if state.restriction == 4 and state.cant_get_exp and state.zero_hp
# True to State has Knockout Properties
return true
end
end
#--------------------------------------------------------------------------
# * Undead? - True if "vs Undead" is A or B (weak against)
#--------------------------------------------------------------------------
def undead?
# Get Element ID by Index of Element Tag
undead_index = $data_system.elements.index(UNDEAD_ELEMENT_TAG)
# If UNDEAD_ELEMENT_TAG doesn't exist in Database in System -> Element Names
return false if not undead_index
# Return True if "vs Undead" has a Element Rate of A or B (weak against)
return true if element_rate(undead_index) >= 150
end
#--------------------------------------------------------------------------
# * Healing? - True if Skill or Item has a Healing Element checked
#--------------------------------------------------------------------------
def healing?(element_cast)
# Get Element ID used for Element with Healing Tag
element_id = $data_system.elements.index(HEALING_ELEMENT_TAG)
# If Element does not exist in Database in System -> Element Names
return false if not element_id
# If Skill or Item has a Element ID of Healing
return true if element_cast.element_set.include?(element_id)
# Return that Element does not have Healing
return false
end
#--------------------------------------------------------------------------
# * Healing Rank Resistance by Undead
#--------------------------------------------------------------------------
def healing_rank
# Get Element ID used for Element with Healing Tag
element_id = $data_system.elements.index(HEALING_ELEMENT_TAG)
# Chance to resist Healing based on Element Efficiency
rank = [0,200,80,60,40,20,-100][self.element_ranks[element_id]]
# Undead / Unholy States make Actor Resistant to Healing
for i in @states
# If protected by state, this element is reduced by half
if $data_states[i].guard_element_set.include?(element_id)
rank /= 2
end
end
# If Actor is Undead, Defense Against Healing
if self.is_a?(Game_Actor) and self.undead?
for i in [@armor1_id, @armor2_id, @armor3_id, @armor4_id]
armor = $data_armors[i]
# If this element is protected by armor, then it's reduced by half
if armor != nil and armor.guard_element_set.include?(element_id)
rank /= 2
end
end
end
# Return modified Value
return rank
end
#--------------------------------------------------------------------------
# * Resurrection? - True if Skill or Item removes Knockout
#--------------------------------------------------------------------------
def resurrection?(minus_state_set)
# If Ressurect Element doesn't exist in Database in System -> Element Names
return false if not $data_system.elements.index(RESURRECTION_ELEMENT_TAG)
# For each of the States to be Removed
for state_id in minus_state_set
# If this State has Knockout Properties
return state_id if state_knockout?($data_states[state_id])
end
# Return that Knockout States not removed, Non Resurrection
return false
end
#--------------------------------------------------------------------------
# * Resurrection Rank Resistance for Undead
#--------------------------------------------------------------------------
def resurrection_rank
# Get Element ID used for Element with Resurrection Tag
element_id = $data_system.elements.index(RESURRECTION_ELEMENT_TAG)
# Chance to resist Resurrection based on Element Efficiency
rank = [0,200,80,60,40,20,-100][self.element_ranks[element_id]]
# Chance to resist Resurrection Death based on Element Efficiency
for i in @states
# If protected by state, this element is reduced by half
if $data_states[i].guard_element_set.include?(element_id)
rank /= 2
end
end
# Armor not calculated due to only Actors wear Armor
# and Resurrection not effective on the Living
# Return modified Value
return rank
end
#--------------------------------------------------------------------------
# * Undead Knockout - Add Knockout State to Undead, Opposite Effect
#--------------------------------------------------------------------------
def undead_knockout(element_cast)
# If States Removes Knockout
if self.undead? and resurrection?(element_cast.minus_state_set)
# If not Immortal
unless self.immortal
# Last Chance to Resist - Get Resurrection Resistance Rank
rank = resurrection_rank
# Add Knockout State if Effective
if (self.damage >= self.hp or rand(100) < rank) and rank > 0
# Set state change flag
@state_changed = true
# Add States that Resurrection will Remove
for i in element_cast.minus_state_set
# Force Add a State of Knockout
add_state(i, true)
end
# Return that Effect is True
return true
end
end
end
end
#--------------------------------------------------------------------------
# * Apply Skill Effects
# user : the one using skills (battler)
# skill : skill
#--------------------------------------------------------------------------
def skill_effect(user, skill)
# Clear critical flag
self.critical = false
# If skill scope is for ally with 1 or more HP, and your own HP = 0,
# or skill scope is for ally with 0, and your own HP = 1 or more or more
# and skill used on a Game Actor
if ((skill.scope == 3 or skill.scope == 4) and self.hp == 0) or
((skill.scope == 5 or skill.scope == 6) and self.hp >= 1 and
self.is_a?(Game_Actor) )
# End Method
return false
end
# Clear effective flag
effective = false
# Set effective flag if common ID is effective
effective |= skill.common_event_id > 0
# If Target is Undead
if self.undead?
# If Skill removes Knockout (found by State Changes) and is an Enemy
if resurrection?(skill.minus_state_set) and self.is_a?(Game_Enemy)
# Determine chance to hit for Resurrecting Undead
hit_result = rand(100) < resurrection_rank
# Skill Healing on Undead causes Damage (Rank F causes Heal, not Injury)
if resurrection_rank < 0
# Thanks for the Heal! I'm not even going to try to Dodge!
effective = true
end
# Invert Recovery to Damage
recover_inversion = true
# is a Healing Item - Heal will harm Undead Actors
elsif healing?(skill)
# Determine chance to hit for Healing Undead
hit_result = rand(100) < healing_rank
# Skill Healing on Undead causes Damage (Rank F causes Heal, not Injury)
if healing_rank < 0
# Thanks for the Heal! I'm not even going to try to Dodge!
effective = true
end
# Invert Recovery to Damage
recover_inversion = true
end
# Skill is Effective with a Hit Result
effective |= hit_result
end
# First hit detection
hit = skill.hit
if skill.atk_f > 0
hit *= user.hit / 100
end
hit_result = (rand(100) < hit)
# Set effective flag if skill is uncertain
effective |= hit < 100
# If hit occurs
if hit_result == true
# Calculate power
power = skill.power + user.atk * skill.atk_f / 100
if power > 0
power -= self.pdef * skill.pdef_f / 200
power -= self.mdef * skill.mdef_f / 200
power = [power, 0].max
end
# Calculate rate
rate = 20
rate += (user.str * skill.str_f / 100)
rate += (user.dex * skill.dex_f / 100)
rate += (user.agi * skill.agi_f / 100)
rate += (user.int * skill.int_f / 100)
# If Recovery Inversion - Convert Recovery to Damage
if recover_inversion
# Invert Damage to Recovery
rate *= -1
end
# Calculate basic damage
self.damage = power * rate / 20
# Element correction
self.damage *= elements_correct(skill.element_set)
self.damage /= 100
# If damage value is strictly positive
if self.damage > 0
# Guard correction
if self.guarding?
self.damage /= 2
end
end
# Dispersion
if skill.variance > 0 and self.damage.abs > 0
amp = [self.damage.abs * skill.variance / 100, 1].max
self.damage += rand(amp+1) + rand(amp+1) - amp
end
# Second hit detection
eva = 8 * self.agi / user.dex + self.eva
hit = self.damage < 0 ? 100 : 100 - eva * skill.eva_f / 100
hit = self.cant_evade? ? 100 : hit
hit_result = (rand(100) < hit)
# Set effective flag if skill is uncertain
effective |= hit < 100
end
# If hit occurs
if hit_result == true
# If physical attack has power other than 0
if skill.power != 0 and skill.atk_f > 0
# State Removed by Shock
remove_states_shock
# Set to effective flag
effective = true
end
# Substract damage from HP
last_hp = self.hp
self.hp -= self.damage
effective |= self.hp != last_hp
# State change
@state_changed = false
# Determine if Skill is Instant Death for Undead
effective |= undead_knockout(skill)
# Determine Normal Effectiveness if it is not already Effective
effective |= states_plus(skill.plus_state_set)
effective |= states_minus(skill.minus_state_set)
# If power is 0
if skill.power == 0
# Set damage to an empty string
self.damage = ""
# If state is unchanged
unless @state_changed
# Set damage to "Miss"
self.damage = "Miss"
end
end
# If miss occurs
else
# Set damage to "Miss"
self.damage = "Miss"
end
# If not in battle
unless $game_temp.in_battle
# Set damage to nil
self.damage = nil
end
# End Method
return effective
end
#--------------------------------------------------------------------------
# * Application of Item Effects
# item : item
#--------------------------------------------------------------------------
def item_effect(item)
# Clear critical flag
self.critical = false
# Ineffective if one of the following:
# If item scope is for ally with 1 or more HP, and your own HP = 0,
# or item scope is for ally with 0 HP, and your own HP = 1 or more
# and item used on a Game Actor
if ((item.scope == 3 or item.scope == 4) and self.hp == 0) or
((item.scope == 5 or item.scope == 6) and self.hp >= 1 and
self.is_a?(Game_Actor) )
# End Method
return false
end
# Clear effective flag
effective = false
# Set effective flag if common ID is effective
effective |= item.common_event_id > 0
# If Target is Undead
if self.undead?
# If item removes Knockout (found by State Changes) and is an Enemy
if resurrection?(item.minus_state_set) and self.is_a?(Game_Enemy)
# Determine chance to hit for Resurrecting Undead
hit_result = rand(100) < resurrection_rank
# Item Healing on Undead causes Damage (Rank F causes Heal, not Injury)
if resurrection_rank < 0
# Thanks for the Heal! I'm not even going to try to Dodge!
effective = true
end
# Invert Recovery to Damage
recover_inversion = true
# is a Healing Item - Heal will harm Undead Actors
elsif healing?(item)
# Determine chance to hit for Healing Undead
hit_result = rand(100) < healing_rank
# Item Healing on Undead causes Damage (Rank F causes Heal, not Injury)
if healing_rank < 0
# Thanks for the Heal! I'm not even going to try to Dodge!
effective = true
end
# Invert Recovery to Damage
recover_inversion = true
end
# Item is Effective with a Hit Result
effective |= hit_result
end
# Determine hit for Item
hit_result = (rand(100) < item.hit)
# Set effective flag is skill is uncertain and Effective not already true
effective |= item.hit < 100
# If hit occurs
if hit_result == true
# Calculate amount of recovery
recover_hp = maxhp * item.recover_hp_rate / 100 + item.recover_hp
recover_sp = maxsp * item.recover_sp_rate / 100 + item.recover_sp
# If Recovery Inversion - Convert Recovery to Damage
if recover_inversion
# Invert Damage to Recovery
recover_hp = recover_hp * -1
recover_sp = recover_sp * -1
end
# If Recovering HP
if recover_hp < 0
recover_hp += self.pdef * item.pdef_f / 20
recover_hp += self.mdef * item.mdef_f / 20
recover_hp = [recover_hp, 0].min
end
# Element correction
recover_hp *= elements_correct(item.element_set)
recover_hp /= 100
recover_sp *= elements_correct(item.element_set)
recover_sp /= 100
# Dispersion
if item.variance > 0 and recover_hp.abs > 0
amp = [recover_hp.abs * item.variance / 100, 1].max
recover_hp += rand(amp+1) + rand(amp+1) - amp
end
if item.variance > 0 and recover_sp.abs > 0
amp = [recover_sp.abs * item.variance / 100, 1].max
recover_sp += rand(amp+1) + rand(amp+1) - amp
end
# If recovery code is negative
if recover_hp < 0
# Guard correction
if self.guarding?
recover_hp /= 2
end
end
# Set damage value and reverse HP recovery amount
self.damage = -recover_hp
# HP and SP recovery
last_hp = self.hp
last_sp = self.sp
self.hp += recover_hp
self.sp += recover_sp
effective |= self.hp != last_hp
effective |= self.sp != last_sp
# State change
@state_changed = false
# Determine if Item is Instant Death for Undead
effective |= undead_knockout(item)
# Determine Normal Effectiveness if it is not already Effective
effective |= states_plus(item.plus_state_set)
effective |= states_minus(item.minus_state_set)
# If parameter value increase is effective
if item.parameter_type > 0 and item.parameter_points != 0
# Branch by parameter
case item.parameter_type
when 1 # Max HP
@maxhp_plus += item.parameter_points
when 2 # Max SP
@maxsp_plus += item.parameter_points
when 3 # Strength
@str_plus += item.parameter_points
when 4 # Dexterity
@dex_plus += item.parameter_points
when 5 # Agility
@agi_plus += item.parameter_points
when 6 # Intelligence
@int_plus += item.parameter_points
end
# Set to effective flag
effective = true
end
# If HP recovery rate and recovery amount are 0
if item.recover_hp_rate == 0 and item.recover_hp == 0
# Set damage to empty string
self.damage = ""
# If SP recovery rate / recovery amount are 0, and parameter increase
# value is ineffective.
if item.recover_sp_rate == 0 and item.recover_sp == 0 and
(item.parameter_type == 0 or item.parameter_points == 0)
# If state is unchanged
unless @state_changed
# Set damage to "Miss"
self.damage = "Miss"
end
end
end
# If miss occurs
else
# Set damage to "Miss"
self.damage = "Miss"
end
# If not in battle
unless $game_temp.in_battle
# Set damage to nil
self.damage = nil
end
# End Method
return effective
end
end
One more thing to request for the Target Anyone script. Is there any chance to allow for Target Any Items or Spells with All Allies or All Enemeies to allow selecting a Target Side? The pain I think would be to have the Target Arrow point to All Enemies or All Allies...
I actually did contemplate something like that before. By RMXP default, whenever you use a skill that targets an entire party/troop, it entirely skips the actor/enemy selection (for obvious reasons). Thus, I'd have to create another phase in the Scene_Battle that mimics this selection process.
I've seen some scripts do this already (in fact, I believe this script already exists in Charliee Fleed's CBS), but I guess I can make an add-on to this.
The whole "healing undead to deal damage" part of your script is unneccessary as I can recreate that easily already. But the "revival deals instant death on undead" is much more interesting.
Quote from: KK20 on December 14, 2012, 07:35:17 pm
I actually did contemplate something like that before. By RMXP default, whenever you use a skill that targets an entire party/troop, it entirely skips the actor/enemy selection (for obvious reasons). Thus, I'd have to create another phase in the Scene_Battle that mimics this selection process.
I've seen some scripts do this already (in fact, I believe this script already exists in Charliee Fleed's CBS), but I guess I can make an add-on to this.
The whole "healing undead to deal damage" part of your script is unneccessary as I can recreate that easily already. But the "revival deals instant death on undead" is much more interesting.
Okay, how else would you do it? I figure you might come up with something better...
The intent I had was to allow Elemental Defense against Healing as an Element. That means Rank A does Max Dmg, but Ranks B thru D also still do damage. The "normal" way would normally just heal an Undead with Ranks A thru D, nada on E, and F would do Damage. Thus, it would not allow varying degrees of effectiveness. Also, States that provide Elemental Defense against Healing as an Element can cause more variations in the outcome. I am curious how else this could be accomplished differently, as what I came up with is definitely far too limiting in regards to scripting for specific elements.
#==============================================================================
# ** 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
# 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
# Make actor arrow
@actor_arrow = Arrow_Actor.new(@spriteset.viewport_actor_arrow)
# 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
@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
@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
I dont know if you'll like it because it flashes the arrow over each Actor / Enemy.
QuoteThe intent I had was to allow Elemental Defense against Healing as an Element. That means Rank A does Max Dmg, but Ranks B thru D also still do damage. The "normal" way would normally just heal an Undead with Ranks A thru D, nada on E, and F would do Damage. Thus, it would not allow varying degrees of effectiveness.
Since you put it that way...Traditionally, there aren't levels of effectiveness for undead being healed, but I guess some people would want that. Alright, go ahead with the script.
Played around a bit and this is what I got:
=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 = "Any Target"
#===============#
# 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].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].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 Updat (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
# 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
# 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 = false
@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 = false
@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
I went ahead and turned the arrows invisible just to see what it looks like. Made me think of just drawing arrows over all the party/troop members.
Seems to work quite well!
Only thing I see that could be changed is Asthetics. In def start_select_all(scope) I added @enemy and @actor_arrow.visible = false That takes care of that initial flash of the arrow before it disappears.
Hey, I noticed that this script was unable to attack party members with a physical attack. So, I modified it so that it can. It is not necessary to add the "Target Any" element to a weapon or anything, this is global for the basic attack.
=begin
===============================================================================
Target Anyone Scope
Version 1.01
12/11/12
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
===============================================================================
Credits:
KK20 - Writing this script
Charlie Fleed - For the idea
Heretic86 - Requesting and bug fixing/finding
===============================================================================
=end
#===========#
# Configure #
#===========#
# The element ID's name that allows the user to target any one battler
TARGET_ANYONE_TAG = "Target Any"
#===============#
# 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 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 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 Updat (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
start_actor_select
################################################################################
@active_battler.physical_attack_my_party = true #ADDED STUFF
################################################################################
@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 = @actor_arrow.index
@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
start_enemy_select
################################################################################
@active_battler.physical_attack_my_party = false #ADDED STUFF
################################################################################
@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 3 # single enemy
index = @active_battler.current_action.target_index
@target_battlers.push($game_troop.smooth_target_enemy(index))
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
################################################################################
# MORE ADDED BELOW
################################################################################
class Game_Battler
alias add_stuff_initialize initialize
def initialize
add_stuff_initialize
@physical_attack_my_party = false
end
attr_accessor :physical_attack_my_party
def physical_attack_my_party
return @physical_attack_my_party
#switch that will decide whether a party member or an enemy party member
#should be the one receiving the damage.
end
end
################################################################################
################################################################################
class Scene_Battle
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
def update_phase3_basic_command
# If B button was pressed
if Input.trigger?(Input::B)
# Play cancel SE
$game_system.se_play($data_system.cancel_se)
# Go to command input for previous actor
phase3_prior_actor
return
end
# If C button was pressed
if Input.trigger?(Input::C)
# Branch by actor command window cursor position
case @actor_command_window.index
when 0 # attack
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Set action
@active_battler.current_action.kind = 0
@active_battler.current_action.basic = 0
# Start enemy selection
##############################################################
@any_target = true
##############################################################
start_enemy_select
when 1 # skill
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Set action
@active_battler.current_action.kind = 1
# Start skill selection
start_skill_select
when 2 # guard
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Set action
@active_battler.current_action.kind = 0
@active_battler.current_action.basic = 1
# Go to command input for next actor
phase3_next_actor
when 3 # item
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Set action
@active_battler.current_action.kind = 2
# Start item selection
start_item_select
end
return
end
end
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
#--------------------------------------------------------------------------
# * Make Basic Action Results
#--------------------------------------------------------------------------
def make_basic_action_result
# If attack
if @active_battler.current_action.basic == 0
# Set anaimation ID
@animation1_id = @active_battler.animation1_id
@animation2_id = @active_battler.animation2_id
# If action battler is enemy
if @active_battler.is_a?(Game_Enemy)
if @active_battler.restriction == 3
target = $game_troop.random_target_enemy
elsif @active_battler.restriction == 2
target = $game_party.random_target_actor
else
index = @active_battler.current_action.target_index
target = $game_party.smooth_target_actor(index)
end
end
# If action battler is actor
if @active_battler.is_a?(Game_Actor)
if @active_battler.restriction == 3
target = $game_party.random_target_actor
elsif @active_battler.restriction == 2
target = $game_troop.random_target_enemy
################################################################################
#------------------------------------------------------------------------------
# Physical Target Selection
#------------------------------------------------------------------------------
elsif @active_battler.physical_attack_my_party == true
index = @active_battler.current_action.target_index
target = $game_party.smooth_target_actor(index)
@active_battler.physical_attack_my_party = false
################################################################################
else
index = @active_battler.current_action.target_index
target = $game_troop.smooth_target_enemy(index)
end
end
# Set array of targeted battlers
@target_battlers = [target]
# Apply normal attack results
for target in @target_battlers
target.attack_effect(@active_battler)
end
return
end
# If guard
if @active_battler.current_action.basic == 1
# Display "Guard" in help window
@help_window.set_text($data_system.words.guard, 1)
return
end
# If escape
if @active_battler.is_a?(Game_Enemy) and
@active_battler.current_action.basic == 2
# Display "Escape" in help window
@help_window.set_text("Escape", 1)
# Escape
@active_battler.escape
return
end
# If doing nothing
if @active_battler.current_action.basic == 3
# Clear battler being forced into action
$game_temp.forcing_battler = nil
# Shift to step 1
@phase4_step = 1
return
end
end
end #end Scent_Battle class
It was originally intended for skills, but I guess that makes sense to do that too. I should update this script again with the Target All Enemies/Allies toggle and add your snippet too. ;)
But literally leaving for work in 5 minutes. brb
Yeah, I didn't really bother being clean about it so sorry if it's messy, but you get the idea. I did notice that your script is compatible with the Tanketai script but my addition is not :( If I figure out a way to make it more universally compatible I'll let you know or maybe you'll just figure it out :)
BUGFIX
Minor bug in the code in Game_Battler Elements Correct
#-------------------------------------------------------------------------
# Class Game Battler
#-------------------------------------------------------------------------
class Game_Battler
#--------------------------------------------------------------------------
# * Calculating Element Correction
# element_set : element
#--------------------------------------------------------------------------
def elements_correct(element_set)
# Important! - Remove direct access to $data so $data is not altered
element_set = element_set.clone
# Remove any Excluded Elements from the element_set arg array
for i in element_set
if i == $data_system.elements.index(TARGET_ANYONE_TAG)
element_set.delete(i)
end
end
# 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
# Element with the Highest Rate means it is the Weakest
weakest = [weakest, self.element_rate(i)].max
end
return weakest
end
end
I came across this using Basil's Leg Sweep. In the Database, I set it to be able to Target Anyone, but it has no other associated Elements. Normally that would be considered to be an Empty Element Set which would return 100, but since Target Anyone was applied, the ELement Set is not considered Empty, and weakest is set to -100, not 100, which caused Basil's Leg Sweep to actually have the Opposite Effect. I changed it around so the Element Rate for Target Any would be set to 100 to prevent -100 from ever seeing the light of day.
Cant really consider this a Necropost, although the thread is old, it is a bugfix for an existing bug that was a pain to discover and may still plauge other users of this script.
Okay, fix #1 didnt work. It caused ELements that would normally be absorbed to be treated as Hits. I changed around the bugfix so that the element_id is removed from the element_set argument before going further.
Duly noted and fixed in main post. Thanks~
My god, this thing is old and you just now found this? lol
I screwed up again. Okay, third time is a charm.
element_set returns Reference to $data
Need to add this as the first line of def elements_correct:
# Important! - Remove direct access to $data so $data is not altered
element_set = element_set.clone
Since the code I altered deletes info from the element_set, being that it passes by Reference not Value, it causes the $data variable to be edited, not just the argument passed. What happens is you'll end up being able to use an Item or Skill just once after switching from Enemy to Actors or Actors to Enemy, but the next time you try to use that same Item or Skill, you wont be able to switch from Actors to Enemies and vice versa.
This was a pain to figure out. My fault. Sorry for the inconvenience.