#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
# Ar Tonelico Custom Battle System
# Author: Kread-EX
# Version 1.1
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
# TERMS OF USAGE
# #------------------------------------------------------------------------------------------------------------------
# # You are free to adapt this work to suit your needs.
# #
# # You cannot use this work for commercial purposes.
# #
# # This work can only be distributed by the following websites:
# # http://www.creationasylum.net/
# # http://www.rpgrevolution.com/ --> Standalone Scripts ONLY (not the demo !)
# # http://www.rmvxp.com/
# # If you want to distribute it elsewhere, contact me first. I'll most likely accept (unless I have
# # some kind of grudge against a certain place), but I want to keep track of the places.
# # Note that I will support and update this script on the above places ONLY.
# #------------------------------------------------------------------------------------------------------------------
#===========================================================
# INTRODUCTION
#
# This script is a custom battle system (CBS) destined to replicate more or less the system used
# in the game "Ar Tonelico - Sekai no Owari de Shi Tsudukeru Shoujo". I say more or less because
# I changed some things.
#
#
# HOW TO USE
# This script is designed to be used with Minkoff/DerVVulfman's Animated Battlers. It won't work
# with the default layout neither will it with Xiderowg's FullMotion script.
# If you downloaded the script from RRR, you'll have to get the Animated Battlers script.
# You can find it there: http://www.creationasylum.net/forum/index.php?showtopic=11827
# Put the main script above the Animated Battlers, and the patch below.
# Read carefully the configuration steps in the KreadCFG section and if the Animated Battlers if
# necessary.
#
# COMPATIBILITY ISSUES
#
# Will clash with the SDK, but not with the MACL.
# In order to avoid lag, I have overwritten most methods insteads of aliasing them, which means
# most battle add-ons will clash with this script.
# If will write add-ons for the next releases depending of user feedback.
#
# CREDITS
#
# Gust Entertainment and Banpresto for making Ar Tonelico in the first place.
# Minkoff and DerVVulfman for their Animated Battlers script.
# MoyasiWhite for the icons.
# Dollmage, Nakka and Grin for the battler graphics.
# Gozaru for the face graphics.
#===========================================================
#===========================================================
# ** KreadCFG
#------------------------------------------------------------------------------
# Configuration module.
#===========================================================
module KreadCFG
# Name of Reyvateil class.
ReyvateilClass = 'Reyvateil'
# Name of Song Magic.
SongMagicName = 'Song Magic'
# Name of Song Activation.
SongActivate = 'Activate Song'
# Name of Song Cancellation.
SongCancel = 'Cancel Song'
# Animation ID for Song Activation
SongActivateAnimID = 105
# Animation ID for Song Cancellation
SongCancelAnimID = 104
# Name of Red Magic and Blue Magic
SongRed = 'Red Magic'
SongBlue = 'Blue Magic'
# List of charging animation for Song Magic (Red type only).
# Format: {Skill ID => Animation ID}
SongMagicChargeAnim = {82 => 102, 83 => 107}
# Max Burst value before Song Magic evolution.
# Format: {Skill ID => value}
SongMagicMaxBurst = {82 => 700, 83 => 3000, 89 => 6000}
# Skill Evolution Pattern. Determine in which skill a previous skill will evolve when the
# Max Burst value has been reached.
# Format: {Old Skill ID => New Skill ID}
SongMagicEvolve = {82 => 83}
# Harmo Overdrive Skills ID (skills available using Harmonics gauge)
# Format: [Skill ID, Skill ID, ...]
HarmoOverdriveSkills = [85, 86]
# Set here the IDs for Fire, Ice and Wind elements.
FireElement = 1
IceElement = 2
WindElement = 6
# Hit number for skills.
# Format: when Skill ID then #nb of hits. Default is 1.
def self.skill_hits(skill_id)
case skill_id
when 57 then 2
when 60, 82, 83 then 5
when 68 then 3
else
1
end
end
# Hit timings. Goes with Hit numbers.
# Enter here the Frame number that triggers the hit.
# If the skill has 1 hit, then you don't have to configure this.
# Format: {Skill ID => [frame, frame, frame...]}
HitTimings = {
57 => [3, 6],
60 => [2, 5, 8, 11, 14],
68 => [2, 7, 12],
82 => [54, 56, 58, 60, 62],
83 => [54, 56, 58, 60, 62]
}
# Skill speed multiplier.
# Format: when Skill ID then Float number. Default is 0.8.
def self.skill_speed(skill_id)
case skill_id
when 58, 59, 66, 67, 70, 71 then 0.6
when 30, 60, 68, 72 then 0.3
when 85 then 0.2
when 86 then 0.1
else
0.8
end
end
# Item speed multiplier.
ItemSpeed = 1.5
# Battle speed. The higher, the faster. Minimum is 2 and maximum is 100.
BattleSpeed = 10
#--------------------------------------------------------------------------
# * Checks if the given actor is a Reyvateil
#--------------------------------------------------------------------------
def self.is_reyvateil?(actor)
return false if !actor.is_a?(Game_Actor)
return $data_classes[actor.class_id].name == ReyvateilClass
end
#--------------------------------------------------------------------------
# * Checks if there is a Reyvateil in the party at all
#--------------------------------------------------------------------------
def self.reyvateil_party?
$game_party.actors.each {|actor|
return true if self.is_reyvateil?(actor)
}
return false
end
#--------------------------------------------------------------------------
# * Returns the Reyvateil in the party
#--------------------------------------------------------------------------
def self.return_reyvateil
$game_party.actors.each {|actor|
return actor if self.is_reyvateil?(actor)
}
return nil
end
#--------------------------------------------------------------------------
# * Checks if there are two Reyvateils
#--------------------------------------------------------------------------
def self.too_many_reyvateils?
rev_count = 0
$game_party.actors.each {|actor|
rev_count += 1 if self.is_reyvateil?(actor)
}
return rev_count >= 2
end
#--------------------------------------------------------------------------
end
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
# Ar Tonelico Custom Battle System
# Author: Kread-EX
# Version 1.1
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
#===========================================================
# ** Scene_Battle
#------------------------------------------------------------------------------
# This class performs battle screen processing.
#===========================================================
class Scene_Battle
#--------------------------------------------------------------------------
# * Public instance variables
#--------------------------------------------------------------------------
attr_reader :skill
attr_accessor :vanguards_harmonics
attr_accessor :reyvateil_harmonics
#--------------------------------------------------------------------------
# * Main Processing
#--------------------------------------------------------------------------
def main
# Checks if too many reyvateils
if KreadCFG.too_many_reyvateils?
print("You cannot have more than 1 Reyvateil in your party !\n" +
"Please take this into account when designing your game.")
exit
end
# Checks for alone reyvateil
if $game_party.actors.size == 1 && KreadCFG.reyvateil_party?
print("You cannot have a lone Reyvateil in your party !")
exit
end
set_global_variables
set_troop_data
set_initial_action_meters
create_sprites_and_windows
# Initialize wait count
@wait_count = 0
# Assign Reyvateil
@reyvateil = KreadCFG.return_reyvateil
if @reyvateil != nil
@reyvateil.song_chant = false
@reyvateil.song_blue = false
@reyvateil.harmonics = 0
@reyvateil.burst_value = 0
end
# Prepare Vanguards Harmonics
@vanguards_harmonics = 0
# Prepare Reyvateil Harmonics
@reyvateil_harmonics = 0
# Initialize delayed command
@delayed_command = false
# Start pre-battle phase
start_phase1
# But switch to Reyvateil command menu if there is a Reyvateil
start_phase6 if KreadCFG.reyvateil_party?
execute_transition
execute_basic_loop
terminate_scene
end
#--------------------------------------------------------------------------
# * Fake judge
#--------------------------------------------------------------------------
def fake_judge
# If all dead determinant is true, or number of members in party is 0
if $game_party.all_dead? or $game_party.actors.size == 0
# If possible to lose
if $game_temp.battle_can_lose
# Desactive Reyvateil Menu
@reyvateil_menu = 'desactivated'
@delayed_command = false
# Return true
return true
end
# Desactive Reyvateil Menu
@reyvateil_menu = 'desactivated'
@delayed_command = false
# Return true
return true
end
# Return false if even 1 enemy exists
for enemy in $game_troop.enemies
if enemy.exist?
return false
end
end
# Desactive Reyvateil Menu
@reyvateil_menu = 'desactivated'
@delayed_command = false
# Return true
return true
end
#--------------------------------------------------------------------------
# * Initialize all globals
#--------------------------------------------------------------------------
def set_global_variables
# Initialize each kind of temporary battle data
$game_temp.in_battle = true
$game_temp.battle_turn = 0
$game_temp.battle_event_flags.clear
$game_temp.battle_abort = false
$game_temp.battle_main_phase = false
$game_temp.battleback_name = $game_map.battleback_name
$game_temp.forcing_battler = nil
$game_temp.max_harmonics = 1000
# Initialize battle event interpreter
$game_system.battle_interpreter.setup(nil, 0)
$game_party.harmonics = 0
end
#--------------------------------------------------------------------------
# * Prepare troop
#--------------------------------------------------------------------------
def set_troop_data
@troop_id = $game_temp.battle_troop_id
$game_troop.setup(@troop_id)
end
#--------------------------------------------------------------------------
# * Computes the initial Action Meters for all battlers
#--------------------------------------------------------------------------
def set_initial_action_meters
($game_party.actors + $game_troop.enemies).each {|battler|
battler.action_meter = battler.agi + rand(battler.agi / 50)
}
end
#--------------------------------------------------------------------------
# * Create the permanently used sprites and windows
#--------------------------------------------------------------------------
def create_sprites_and_windows
# Make sprite set
@spriteset = Spriteset_Battle.new
# Status windows for each actor
@status_windows = []
i = 0
old_y = 350
(0...$game_party.actors.size).each {|j|
i = (($game_party.actors.size - 1) - j)
@status_windows[i] = Battle_Status.new(i)
@status_windows[i].y = old_y
old_y -= 58
}
# Reyvateil command sprite (if there is a Reyvateil in the party)
if KreadCFG.reyvateil_party?
@reyvateil_command = Reyvateil_Command.new(@spriteset.viewport5)
end
# Action system graphic interface
@action_system = Action_System.new(@spriteset.viewport5)
# Create message window
@message_window = Window_Message.new
# Create the Harmonics gauge
@harmonics_gauge = Harmonics_Gauge.new(@spriteset.viewport5, KreadCFG.return_reyvateil)
end
#--------------------------------------------------------------------------
# * Perform the start-battle transition
#--------------------------------------------------------------------------
def execute_transition
if $data_system.battle_transition == ''
Graphics.transition(20)
else
Graphics.transition(40, 'Graphics/Transitions/' + $data_system.battle_transition)
end
end
#--------------------------------------------------------------------------
# * Basic scene loop
#--------------------------------------------------------------------------
def execute_basic_loop
# Main loop
loop {
# Update game screen
Graphics.update
# Update input information
Input.update
# Frame update
update
# Abort loop if screen is changed
break if $scene != self
}
end
#--------------------------------------------------------------------------
# * Destroy all objects
#--------------------------------------------------------------------------
def dispose_objects
@message_window.dispose
@spriteset.dispose
@status_windows.each {|spr| spr.dispose}
if @reyvateil_command != nil
@reyvateil_command.bitmap.dispose
@reyvateil_command.dispose
end
if @levelup_sprites != nil
@levelup_sprites.each {|spr| spr.dispose}
end
@reyvateil_ring.dispose if @reyvateil_ring != nil
@result_window.dispose if @result_window != nil
@action_system.dispose
end
#--------------------------------------------------------------------------
# * Link to next scene
#--------------------------------------------------------------------------
def terminate_scene
# Refresh map
$game_map.refresh
# Prepare for transition
Graphics.freeze
# Dispose of all objects
dispose_objects
# Clear cache
RPG::Cache.clear
# If switching to title screen
if $scene.is_a?(Scene_Title)
# Fade out screen
Graphics.transition
Graphics.freeze
end
# If switching from battle test to any screen other than game over screen
if $BTEST and not $scene.is_a?(Scene_Gameover)
$scene = nil
end
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
update_battle_interpreter
update_globals
update_harmonics
update_sprites_and_windows
update_transition
update_reyvateil_command
if @reyvateil != nil && @blue_launch
update_phase6_blue_magic unless (@reyvateil.dead? || !@reyvateil.song_blue)
@blue_launch = false
end
# If message window is showing, then stops
return if $game_temp.message_window_showing
# If effect is showing, then stops
return if @spriteset.effect?
# If game over
if $game_temp.gameover
# Switch to game over screen
$scene = Scene_Gameover.new
return
end
# If returning to title screen
if $game_temp.to_title
# Switch to title screen
$scene = Scene_Title.new
return
end
# If battle is aborted
if $game_temp.battle_abort
# Return to BGM used before battle started
$game_system.bgm_play($game_temp.map_bgm)
# Battle ends
battle_end(1)
return
end
# If waiting
if @wait_count > 0
# Decrease wait count
@wait_count -= 1
return
end
# If battler forcing an action doesn't exist, and battle event is running, then stops
return if $game_temp.forcing_battler == nil && $game_system.battle_interpreter.running?
update_phases
end
#--------------------------------------------------------------------------
# * Update the battle interpreter
#--------------------------------------------------------------------------
def update_battle_interpreter
# If battle event is running
if $game_system.battle_interpreter.running?
# Update interpreter
$game_system.battle_interpreter.update
# If a battler which is forcing actions doesn't exist
if $game_temp.forcing_battler == nil
# If battle event has finished running
unless $game_system.battle_interpreter.running?
# Rerun battle event set up if battle continues
setup_battle_event unless judge
end
end
end
end
#--------------------------------------------------------------------------
# * Update the global variables
#--------------------------------------------------------------------------
def update_globals
# Update system (timer) and screen
$game_system.update
$game_screen.update
# If timer has reached 0
if $game_system.timer_working && $game_system.timer == 0
# Abort battle
$game_temp.battle_abort = true
end
end
#--------------------------------------------------------------------------
# * Update Harmonics
#--------------------------------------------------------------------------
def update_harmonics
return if @phase == 4 && @phase4_step.between?(2, 4)
# If there is a change, perform it.
if @vanguards_harmonics > 0
if @reyvateil != nil
$game_party.harmonics = [($game_party.harmonics + 2),
($game_temp.max_harmonics - @reyvateil.harmonics)].min
else
$game_party.harmonics = [($game_party.harmonics + 2),
($game_temp.max_harmonics)].min
end
@vanguards_harmonics -= 2
elsif @vanguards_harmonics < 0
$game_party.harmonics = [($game_party.harmonics - 5), 0].max
@vanguards_harmonics += 5
end
if @reyvateil_harmonics < 0
@reyvateil.harmonics = [(@reyvateil.harmonics - 5), 0].max
@reyvateil_harmonics += 5
end
end
#--------------------------------------------------------------------------
# * Simply updates all permanent sprites and windows
#--------------------------------------------------------------------------
def update_sprites_and_windows
@message_window.update
@spriteset.update
@status_windows.each {|spr| spr.update}
@action_system.update
@help_window.update if @help_window != nil
@burst_gauge.update if @burst_gauge != nil
@harmonics_gauge.update
end
#--------------------------------------------------------------------------
# * Update the transition effects
#--------------------------------------------------------------------------
def update_transition
# If transition is processing
if $game_temp.transition_processing
# Clear transition processing flag
$game_temp.transition_processing = false
# Execute transition
execute_transition
end
end
#--------------------------------------------------------------------------
# * Update the activation of Reyvateil menu
#--------------------------------------------------------------------------
def update_reyvateil_command
# Quit if there isn't any reyvateil or already active
return if !KreadCFG.reyvateil_party? || !@reyvateil_command.visible || @reyvateil.dead?
# Activates by pressing B
if Input.trigger?(Input::B)
# Effect depends of the current situation
case @reyvateil_menu
when 'immediate'
# Stores previous phase
@previous_phase = @phase
# Switch to phase 6
start_phase6
when 'delayed'
@delayed_command = true
@reyvateil_command.visible = false
when 'desactivated'
$game_system.se_play($data_system.buzzer_se)
end
end
end
#--------------------------------------------------------------------------
# * Update the various battle phases
#--------------------------------------------------------------------------
def update_phases
# Branch according to phase
case @phase
when 1 # pre-battle phase
update_phase1
when 2 # party command phase
update_phase2
when 3 # actor command phase
update_phase3
when 4 # main phase
update_phase4
when 5 # after battle phase
update_phase5
when 6 # Reyvateil command phase
update_phase6
end
end
#--------------------------------------------------------------------------
# * Start Pre-Battle Phase
#--------------------------------------------------------------------------
def start_phase1
# Shift to phase 1
@phase = 1
# Clear active battler
@active_battler = nil
# Reyvateil command is immediate
@reyvateil_menu = 'immediate'
# Set up battle event
setup_battle_event
end
#--------------------------------------------------------------------------
# * Frame Update (pre-battle phase)
#--------------------------------------------------------------------------
def update_phase1
# Determine win/loss situation
if judge
# If won or lost: end method
return
end
# Switch to phase 4 in case of forcing battler
if $game_temp.forcing_battler != nil
@active_battler = $game_temp.forcing_battler
@reyvateil_menu = 'desactivated'
start_phase4
return
end
# Update Burst value SP consumption and Reyvateil Harmonics
update_phase1_reyvateil_system
# Update Action Meters
update_phase1_action_meters
# Try to select an active battler
update_phase1_battler_selection
# Switch to next phase if there is an active battler
if @active_battler != nil
# If it's an enemy
if @active_battler.is_a?(Game_Enemy)
# Decrease Ambiance Field of all enemies, and set this one to 0.
$game_troop.enemies.each {|enemy|
enemy.ambiance_field = [(enemy.ambiance_field - 1), 0].max
}
@active_battler.ambiance_field = 0
# Clear skill
@skill = nil
# Program action
@active_battler.make_action
# Switch to phase 4
start_phase4
# Else, it's a standard actor
else
if !@active_battler.inputable?
@active_battler.action_meter = @active_battler.agi
start_phase4
return
end
# Switch to phase 3
start_phase3
end
end
end
#--------------------------------------------------------------------------
# * Frame Update (phase 1: Burst value, SP and R. Harmo update)
#--------------------------------------------------------------------------
def update_phase1_reyvateil_system
# Quit if there's no Reyvateil in party.
return unless KreadCFG.reyvateil_party?
# Update Reyvateil death
if @reyvateil.dead?
@reyvateil.harmonics = 0
@reyvateil.burst_value = 0
@reyvateil.song_chant = false
@reyvateil.song_blue = false
@reyvateil.current_action.clear
if @burst_gauge != nil
@burst_gauge.dispose
@burst_gauge = nil
end
return
end
# Update Harmonics
@reyvateil.harmonics = [(@reyvateil.harmonics + 1),
($game_temp.max_harmonics - $game_party.harmonics)].min
# Restores SP if not chanting
if !@reyvateil.song_chant
@reyvateil.sp += (10 * (1 + $game_party.global_harmonics / 1000.00)).round
@status_windows[@reyvateil.index].refresh_sp_only
return
end
# Updates SP consumption
@reyvateil.sp -= ($data_skills[@reyvateil.current_action.skill_id].sp_cost *
(1 - $game_party.global_harmonics / 900.00)).round
# Cancels the song if ran out of SP
if @reyvateil.sp <= 0
@reyvateil.sp = 0
# Play animation
@reyvateil.animation_id = KreadCFG::SongCancelAnimID
# Destroy Burst
@burst_gauge.dispose
@burst_gauge = nil
# Clear action
@reyvateil.song_chant = false
@reyvateil.song_blue = false
@reyvateil.loop_animation_id = 0
@reyvateil.current_action.clear
end
@status_windows[@reyvateil.index].refresh_sp_only
# Updates value
@reyvateil.burst_value += (5 + $game_party.global_harmonics / 100)
# If the burst match the Evolve stage, then the spell evolve
current_song = @reyvateil.current_action.skill_id
if KreadCFG::SongMagicEvolve[current_song] != nil
if KreadCFG::SongMagicMaxBurst[current_song] <= @reyvateil.burst_value
@reyvateil.current_action.skill_id = KreadCFG::SongMagicEvolve[current_song]
@reyvateil.loop_animation_id = KreadCFG::SongMagicChargeAnim[@reyvateil.current_action.skill_id]
@reyvateil.animation_id = KreadCFG::SongActivateAnimID
end
end
end
#--------------------------------------------------------------------------
# * Frame Update (phase 1: Action Meters update)
#--------------------------------------------------------------------------
def update_phase1_action_meters
# Adds the BattleSpeed value to AMs. Corrects if under 2 or over 100.
inc = [[KreadCFG::BattleSpeed, 2].max, 100].min
($game_party.actors + $game_troop.enemies).each {|battler|
next unless battler.exist?
battler.action_meter += inc
}
end
#--------------------------------------------------------------------------
# * Frame Update (phase 1: active battler selection)
#--------------------------------------------------------------------------
def update_phase1_battler_selection
# Iterate both parties searching for a battler with full AM
($game_party.actors + $game_troop.enemies).each {|battler|
next unless battler.exist?
if battler.action_meter >= 1000 && battler == @action_system.queue.first.battler
@active_battler = battler
return
end
}
end
#--------------------------------------------------------------------------
# * Frame Update (party command phase: escape)
#--------------------------------------------------------------------------
def update_phase2_escape
# Calculate enemy agility average
enemies_agi = 0
enemies_number = 0
for enemy in $game_troop.enemies
if enemy.exist?
enemies_agi += enemy.agi
enemies_number += 1
end
end
if enemies_number > 0
enemies_agi /= enemies_number
end
# Calculate actor agility average
actors_agi = 0
actors_number = 0
for actor in $game_party.actors
if actor.exist?
actors_agi += actor.agi
actors_number += 1
end
end
if actors_number > 0
actors_agi /= actors_number
end
# Determine if escape is successful
success = rand(100) < 50 * actors_agi / enemies_agi
# If escape is successful
if success
# Play escape SE
$game_system.se_play($data_system.escape_se)
# Return to BGM before battle started
$game_system.bgm_play($game_temp.map_bgm)
# Battle ends
battle_end(1)
# If escape is failure
else
# Update Action Meters
@active_battler.action_meter = @active_battler.agi
@active_battler.blink = false
@action_system.update_order
@action_system.update_coordinates
@active_battler = nil
@wait_count = 12
# Switch to phase 4
start_phase4
end
end
#--------------------------------------------------------------------------
# * Start Actor Command Phase
#--------------------------------------------------------------------------
def start_phase3
# Shift to phase 3
@phase = 3
# Blink
@active_battler.blink = true
# Shifts to right action order
@action_system.right_shift
# Create the command ring
@command_ring = Command_Ring.new(@active_battler)
# Reyvateil command is desactivated
@reyvateil_menu = 'desactivated'
end
#--------------------------------------------------------------------------
# * Frame Update (actor command phase)
#--------------------------------------------------------------------------
def update_phase3
# Update enemy arrow
if @enemy_arrow != nil
update_phase3_enemy_select
# Update actor arrow
elsif @actor_arrow != nil
update_phase3_actor_select
# If skill window is enabled
elsif @skill_window != nil
update_phase3_skill_select
# If item window is enabled
elsif @item_window != nil
update_phase3_item_select
# Update command ring if active
elsif @command_ring.active
update_phase3_command_ring
end
end
#--------------------------------------------------------------------------
# * Frame Update (phase 3: actor command selection)
#--------------------------------------------------------------------------
def update_phase3_command_ring
# Update object
@command_ring.update
# C: Validate command
if Input.trigger?(Input::C)
# Play SE
$game_system.se_play($data_system.decision_se)
# Hide command ring
@command_ring.toggle_visibility
@command_ring.toggle_activity
# Branch by command
case @command_ring.command
when '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
# Store current action meter
@current_am = @active_battler.action_meter
# And set the next action meter value
@active_battler.action_meter = @active_battler.agi
# Enemy selection
start_enemy_select
when 'Skill'
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Skill selection
start_skill_select
when 'Item'
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Item selection
start_item_select
when '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
# And set the next action meter value
@active_battler.action_meter = @active_battler.agi * 2
# Switch to phase 4
start_phase4
when 'Flee'
update_phase2_escape
end
end
end
#--------------------------------------------------------------------------
# * Start Skill Selection
#--------------------------------------------------------------------------
def start_skill_select
# Make skill help window
@skill_help = Window_SkillHelp.new
# Make skill window
@skill_window = Window_BattleSkill.new(@active_battler)
# Associate the two
@skill_window.help_window = @skill_help
# Stores last skill and current AM value
@last_skill = nil
@current_am = @active_battler.action_meter
end
#--------------------------------------------------------------------------
# * Frame Update (actor command phase : skill selection)
#--------------------------------------------------------------------------
def update_phase3_skill_select
# Update skill window
@skill_window.update
# Virtualize next action turn
@skill = @skill_window.skill
if @last_skill != @skill
@last_skill = @skill
@active_battler.action_meter = @active_battler.agi * KreadCFG.skill_speed(@skill.id)
@action_system.update_order
@action_system.update_coordinates
end
# 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
# Restores AM
@active_battler.action_meter = @current_am
# End virtualization
@action_system.update_order
@action_system.update_coordinates(true)
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 || !@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.kind = 1
@active_battler.current_action.skill_id = @skill.id
# Make skill window and skill help window invisible
@skill_window.visible = @skill_help.visible = false
# If effect scope is single enemy
if @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
# Start phase 4
start_phase4
end
return
end
end
#--------------------------------------------------------------------------
# * End Skill Selection
#--------------------------------------------------------------------------
def end_skill_select
# Dispose of skill window
@skill_window.dispose
@skill_window = nil
# Dispose of help windiw
@skill_help.dispose
@skill_help = nil
# Retrieve command ring
@command_ring.toggle_visibility
@command_ring.toggle_activity
end
#--------------------------------------------------------------------------
# * Start Item Selection
#--------------------------------------------------------------------------
def start_item_select
# Make item help window
@item_help = Window_SkillHelp.new
# Make item window
@item_window = Window_BattleItem.new
# Associate the two
@item_window.help_window = @item_help
# Stores current AM value
@current_am = @active_battler.action_meter
# Update AM
@active_battler.action_meter = @active_battler.agi * KreadCFG::ItemSpeed
end
#--------------------------------------------------------------------------
# * Frame Update (actor command phase : item selection)
#--------------------------------------------------------------------------
def update_phase3_item_select
# 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
# Restores AM
@active_battler.action_meter = @current_am
# End virtualization
@action_system.update_order
@action_system.update_coordinates(true)
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
if @item == nil
# 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.kind = 2
@active_battler.current_action.item_id = @item.id
# Make item window and item help window invisible
@item_window.visible = @item_help.visible = false
# If effect scope is single enemy
if @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
# Start phase 4
start_phase4
end
return
end
end
#--------------------------------------------------------------------------
# * End Item Selection
#--------------------------------------------------------------------------
def end_item_select
# Dispose of item window
@item_window.dispose
@item_window = nil
# Dispose of help window
@item_help.dispose
@item_help = nil
# Retrieve command ring
@command_ring.toggle_visibility
@command_ring.toggle_activity
end
#--------------------------------------------------------------------------
# * Start Enemy Selection
#--------------------------------------------------------------------------
def start_enemy_select
# Make Ambiance Field the help window
@help_window = Ambiance_Field.new
# Make enemy arrow
@enemy_arrow = Arrow_Enemy.new(@spriteset.viewport1)
# Associate help window
@enemy_arrow.help_window = @help_window
@enemy_arrow.update
# Virtualize next action turn
@action_system.update_order
@action_system.update_coordinates
end
#--------------------------------------------------------------------------
# * Frame Update (actor command phase : enemy selection)
#--------------------------------------------------------------------------
def update_phase3_enemy_select
# Update enemy arrow
@enemy_arrow.update
# If B button was pressed
if Input.trigger?(Input::B)
# Play cancel SE
$game_system.se_play($data_system.cancel_se)
# Restore old Action Meter
@active_battler.action_meter = @current_am if @command_ring.command == 'Attack'
# End enemy selection
end_enemy_select
# End virtualization
if @command_ring.command == 'Attack'
@action_system.update_order
@action_system.update_coordinates(true)
end
# Retrieve skill window
if @skill_window != nil
@skill_window.visible = @skill_help.visible = true
# Retrieve item window
elsif @item_window != nil
@item_window.visible = @item_help.visible = true
end
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
# Switch to action phase
start_phase4
end
end
#--------------------------------------------------------------------------
# * End Enemy Selection
#--------------------------------------------------------------------------
def end_enemy_select
# Dispose of enemy arrow
@enemy_arrow.dispose
@enemy_arrow = nil
# Dispose of Ambiance Field
@help_window.dispose
@help_window = nil
# If command is [fight]
if @command_ring.command == 'Attack'
# Enable command ring
@command_ring.toggle_visibility
@command_ring.toggle_activity
end
end
#--------------------------------------------------------------------------
# * Start Actor Selection
#--------------------------------------------------------------------------
def start_actor_select
# Make Ambiance Field the help window
@help_window = Ambiance_Field.new
# Make actor arrow
@actor_arrow = Arrow_Actor.new(@spriteset.viewport1)
# Associate help window
@actor_arrow.help_window = @help_window
@actor_arrow.update
# Virtualize next action turn
@action_system.update_order
@action_system.update_coordinates
end
#--------------------------------------------------------------------------
# * Frame Update (actor command phase : actor selection)
#--------------------------------------------------------------------------
def update_phase3_actor_select
# Update actor arrow
@actor_arrow.update
# If B button was pressed
if Input.trigger?(Input::B)
# Play cancel SE
$game_system.se_play($data_system.cancel_se)
# Restore old Action Meter
@active_battler.action_meter = @current_am
# End actor selection
end_actor_select
# End virtualization
@action_system.update_order
@action_system.update_coordinates(true)
# Retrieve skill window
if @skill_window != nil
@skill_window.visible = @skill_help.visible = true
# Retrieve item window
elsif @item_window != nil
@item_window.visible = @item_help.visible = true
end
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
# Switch to action phase
start_phase4
end
end
#--------------------------------------------------------------------------
# * End Actor Selection
#--------------------------------------------------------------------------
def end_actor_select
# Dispose of actor arrow
@actor_arrow.dispose
@actor_arrow = nil
# Dispose of Ambiance Field
@help_window.dispose
@help_window = nil
end
#--------------------------------------------------------------------------
# * Start Main Phase
#--------------------------------------------------------------------------
def start_phase4
# Shift to phase 4
@phase = 4
# Switch Reyvateil ring mode
@reyvateil_menu = 'delayed' unless $game_temp.forcing_battler != nil
# Destroy Command Ring
if @command_ring != nil
@command_ring.dispose
@command_ring = nil
end
# Clear skill and item
@skill = @item = nil
# Turn count
$game_temp.battle_turn += 1
# Switch to phase 1 if @active_battler is nil
if @active_battler == nil
start_phase1
return
end
# Right shift when enemy attack
@action_system.right_shift if @active_battler.is_a?(Game_Enemy)
# Blink
@active_battler.blink = false
# Create help window
@help_window = Action_Help.new(@spriteset.viewport5, @active_battler.current_action)
# Set main phase flag
$game_temp.battle_main_phase = true
# Shift to step 1
@phase4_step = 1
end
#--------------------------------------------------------------------------
# * Frame Update (main phase)
#--------------------------------------------------------------------------
def update_phase4
case @phase4_step
when 1
update_phase4_step1
when 2
update_phase4_step2
when 3
update_phase4_step3
when 4
update_phase4_step4
when 5
update_phase4_step5
when 6
update_phase4_step6
end
end
#--------------------------------------------------------------------------
# * Frame Update (main phase step 1 : action preparation)
#--------------------------------------------------------------------------
def update_phase4_step1
# Determine win/loss
if judge
# If won, or if lost : end method
return
end
# Initialize animation ID and common event ID
@animation1_id = 0
@animation2_id = 0
@common_event_id = 0
# Slip damage
if @active_battler.hp > 0 and @active_battler.slip_damage?
@active_battler.slip_damage_effect
@active_battler.damage_pop = true
end
# Natural removal of states
@active_battler.remove_states_auto
# Refresh status window (active battler only)
@status_windows[@active_battler.index].refresh if @active_battler.is_a?(Game_Actor)
# Shift to step 2
@phase4_step = 2
end
#--------------------------------------------------------------------------
# * Frame Update (main phase step 2 : start action)
#--------------------------------------------------------------------------
def update_phase4_step2
# If not a forcing action
unless @active_battler.current_action.forcing
# If restriction is [normal attack enemy] or [normal attack ally]
if @active_battler.restriction == 2 or @active_battler.restriction == 3
# Set attack as an action
@active_battler.current_action.kind = 0
@active_battler.current_action.basic = 0
end
# If restriction is [cannot perform action]
if @active_battler.restriction == 4
# Clear battler being forced into action
$game_temp.forcing_battler = nil
# Shift to step 1
@phase4_step = 1
return
end
end
# Clear target battlers
@target_battlers = []
# Branch according to each action
case @active_battler.current_action.kind
when 0 # basic
make_basic_action_result
when 1 # skill
make_skill_action_result
when 2 # item
make_item_action_result
end
# Shift to step 3
@phase4_step = 3
end
#--------------------------------------------------------------------------
# * Make Basic Action Results
#--------------------------------------------------------------------------
def make_basic_action_result
# If attack
if @active_battler.current_action.basic == 0
# Set animation 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
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
@target_battlers.each {|target| target.attack_effect(@active_battler)}
return
end
# If escape
if @active_battler.is_a?(Game_Enemy) and
@active_battler.current_action.basic == 2
# 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 = 5
return
end
end
#--------------------------------------------------------------------------
# * Make Skill Action Results
#--------------------------------------------------------------------------
def make_skill_action_result
# Get skill
@skill = $data_skills[@active_battler.current_action.skill_id]
# Set animation ID
@animation1_id = @skill.animation1_id
@animation2_id = @skill.animation2_id
# Removes HP, SP or Harmonics
if KreadCFG::HarmoOverdriveSkills.include?(@skill.id) && @active_battler.is_a?(Game_Actor)
@reyvateil.harmonics = 0
$game_party.harmonics = 0
end
if $game_system.vanguards_sp || @active_battler.is_a?(Game_Enemy)
@active_battler.sp -= @skill.sp_cost
else
@active_battler.hp =
[(@active_battler.hp - (@skill.sp_cost * @active_battler.maxhp) / 100), 0].max
end
# Set command event ID
@common_event_id = @skill.common_event_id
# Set target battlers
set_target_battlers(@skill.scope)
# Check skill hit number
hit_nb = KreadCFG.skill_hits(skill.id)
# If number is 1, apply the effect once
if hit_nb == 1
@target_battlers.each {|target| target.skill_effect(@active_battler, @skill)}
# Else, apply the effect for each hit
else
for i in (1..hit_nb)
for target in @target_battlers
target.skill_effect(@active_battler, @skill, (i - 1))
end
end
end
end
#--------------------------------------------------------------------------
# * Make Item Action Results
#--------------------------------------------------------------------------
def make_item_action_result
# Get item
@item = $data_items[@active_battler.current_action.item_id]
# If unable to use due to items running out
unless $game_party.item_can_use?(@item.id)
# Shift to step 1
@phase4_step = 1
return
end
# If consumable
if @item.consumable
# Decrease used item by 1
$game_party.lose_item(@item.id, 1)
end
# Set animation ID
@animation1_id = @item.animation1_id
@animation2_id = @item.animation2_id
# Set common event ID
@common_event_id = @item.common_event_id
# Decide on target
index = @active_battler.current_action.target_index
target = $game_party.smooth_target_actor(index)
# Set targeted battlers
set_target_battlers(@item.scope)
# Apply item effect
for target in @target_battlers
target.item_effect(@item)
end
end
#--------------------------------------------------------------------------
# * Make Song Magic Action Results
#--------------------------------------------------------------------------
def make_song_action_result
# Get skill
@skill = $data_skills[@reyvateil.current_action.skill_id]
# Set animation ID
@animation1_id = @skill.animation1_id
@animation2_id = @skill.animation2_id
# Refresh status window
@status_windows[@reyvateil.index].refresh
# Set command event ID
@common_event_id = @skill.common_event_id
# Set target battlers
set_target_battlers(@skill.scope)
# Check skill hit number
hit_nb = KreadCFG.skill_hits(skill.id)
# If number is 1, apply the effect once
if hit_nb == 1
@target_battlers.each {|target|
target.song_effect(@reyvateil, @skill)
target.damage_pop = true if @reyvateil.song_blue
}
# Else, apply the effect for each hit
else
for i in (1..hit_nb)
for target in @target_battlers
target.song_effect(@reyvateil, @skill, (i - 1))
target.damage_pop = true if @reyvateil.song_blue
end
end
end
end
#--------------------------------------------------------------------------
# * Frame Update (main phase step 3 : animation for action performer)
#--------------------------------------------------------------------------
def update_phase4_step3
# Animation for action performer (if ID is 0, then white flash)
if @animation1_id == 0
@active_battler.white_flash = true
else
@active_battler.animation_id = @animation1_id
@active_battler.animation_hit = true
end
# Refresh status window (active battler only)
@status_windows[@active_battler.index].refresh if @active_battler.is_a?(Game_Actor)
# Shift to step 4
@phase4_step = 4
end
#--------------------------------------------------------------------------
# * Frame Update (main phase step 4 : animation for target)
#--------------------------------------------------------------------------
def update_phase4_step4
# Animation for target
@target_battlers.each {|target|
target.animation_id = @animation2_id
target.animation_hit = (target.damage[0] != 'Miss')
}
# Shift to step 5
@phase4_step = 5
end
#--------------------------------------------------------------------------
# * Frame Update (main phase step 5 : damage display)
#--------------------------------------------------------------------------
def update_phase4_step5
# Destroy help window
@help_window.dispose
@help_window = nil
# Display damage
@target_battlers.each {|target|
if target.damage.size > 0
target.damage_pop = true
end
}
# Refresh status windows
@status_windows.each {|win| win.refresh}
# Refreshes Action Meters
@action_system.update_order
@action_system.update_coordinates
if $game_temp.battle_turn % ($game_party.actors.size + $game_troop.enemies.size - 1) == 0
@blue_launch = true if @reyvateil != nil && @reyvateil.song_blue
end
# Wait 12 frames
@wait_count = 12
# Clear the forcing battler
$game_temp.forcing_battler = nil
# Shift to phase 1
start_phase1
# Switch to phase 6
if @delayed_command
start_phase6 unless fake_judge
@delayed_command = false
end
end
#--------------------------------------------------------------------------
# * Start After Battle Phase
#--------------------------------------------------------------------------
def start_phase5
# Shift to phase 5
@phase = 5
# Play battle end ME
$game_system.me_play($game_system.battle_end_me)
# Return to BGM before battle started
$game_system.bgm_play($game_temp.map_bgm)
# Initialize EXP, amount of gold, and treasure
exp = 0
gold = 0
treasures = []
# Loop
for enemy in $game_troop.enemies
# If enemy is not hidden
unless enemy.hidden
# Add EXP and amount of gold obtained
exp += enemy.exp
gold += enemy.gold
# Determine if treasure appears
if rand(100) < enemy.treasure_prob
if enemy.item_id > 0
treasures.push($data_items[enemy.item_id])
end
if enemy.weapon_id > 0
treasures.push($data_weapons[enemy.weapon_id])
end
if enemy.armor_id > 0
treasures.push($data_armors[enemy.armor_id])
end
end
end
end
# Treasure is limited to a maximum of 6 items
treasures = treasures[0..5]
# Obtaining EXP
@levelup_sprites = []
for i in 0...$game_party.actors.size
actor = $game_party.actors[i]
@levelup_sprites.push(Sprite_LevelUP.new(@spriteset.viewport5, actor))
if actor.cant_get_exp? == false
last_level = actor.level
actor.exp += exp
if actor.level > last_level
@levelup_sprites[actor.index].visible = true
end
end
end
# Obtaining gold
$game_party.gain_gold(gold)
# Obtaining treasure
for item in treasures
case item
when RPG::Item
$game_party.gain_item(item.id, 1)
when RPG::Weapon
$game_party.gain_weapon(item.id, 1)
when RPG::Armor
$game_party.gain_armor(item.id, 1)
end
end
# Make battle result window
@result_window = Window_BattleResult.new(exp, gold, treasures)
# Set wait count
@phase5_wait_count = 100
end
#--------------------------------------------------------------------------
# * Frame Update (after battle phase)
#--------------------------------------------------------------------------
def update_phase5
# If wait count is larger than 0
if @phase5_wait_count > 0
# Decrease wait count
@phase5_wait_count -= 1
# If wait count reaches 0
if @phase5_wait_count == 0
# Show result window
@result_window.visible = true
# Clear main phase flag
$game_temp.battle_main_phase = false
end
return
end
# If C button was pressed
if Input.trigger?(Input::C)
# Battle ends
battle_end(0)
end
end
#--------------------------------------------------------------------------
# * Start Reyvateil Command Phase
#--------------------------------------------------------------------------
def start_phase6
# Shift to phase 6
@phase = 6
# Blink
@reyvateil.blink = true
# Set action meter to max
@reyvateil.action_meter = 1000
# Create battler icon
@action_system.insert_reyvateil
# Make Reyvateil Command sprite invisible
@reyvateil_command.visible = false
# Prepare action
@song_activate = false
@wait_count = 10
end
#--------------------------------------------------------------------------
# * Frame Update (Reyvateil command phase)
#--------------------------------------------------------------------------
def update_phase6
# Create Reyvateil Command Ring
if @reyvateil_ring == nil
@reyvateil_ring = Command_Ring.new(@reyvateil)
end
# Update Song activation
if @song_activate
update_phase6_song_activation
# Update Song selection
elsif @song_window != nil
update_phase6_song_select
# Update Reyvateil ring
elsif @reyvateil_ring != nil
update_phase6_reyvateil_ring
end
end
#--------------------------------------------------------------------------
# * Frame Update (phase 6: Song Magic activation)
#--------------------------------------------------------------------------
def update_phase6_song_activation
# Supress animations
@reyvateil.loop_animation_id = 0
@reyvateil.song_chant = false
# Make skill result
@target_battlers = []
@active_battler = @reyvateil
@skill = $data_skills[@active_battler.current_action.skill_id]
set_target_battlers(@skill.scope)
make_song_action_result
@target_battlers.each {|target|
target.animation_id = @animation2_id
target.animation_hit = (target.damage[0] != 'Miss')
}
@reyvateil.animation_id = KreadCFG::SongActivateAnimID
@active_battler = nil
# Destroy Burst
@burst_gauge.dispose
@burst_gauge = nil
@reyvateil.burst_value = 0
end_reyvateil_command
end
#--------------------------------------------------------------------------
# * Frame Update (phase 6: Song Magic activation - Blue)
#--------------------------------------------------------------------------
def update_phase6_blue_magic
# Make skill result
prev_ab = @active_battler
@target_battlers = []
@active_battler = @reyvateil
@skill = $data_skills[@active_battler.current_action.skill_id]
set_target_battlers(@skill.scope)
make_song_action_result
@target_battlers.each {|target|
target.animation_id = @animation2_id
target.animation_hit = (target.damage[0] != 'Miss')
}
@status_windows.each {|win| win.refresh}
@active_battler = prev_ab
end
#--------------------------------------------------------------------------
# * Frame Update (phase 6: Song Magic selection)
#--------------------------------------------------------------------------
def update_phase6_song_select
# Update window
@song_window.update
# B: Return to Ring
if Input.trigger?(Input::B)
# Play SE
$game_system.se_play($data_system.cancel_se)
# Retrieve command ring
@reyvateil_ring.toggle_visibility
@reyvateil_ring.toggle_activity
# Destroy song window
@song_window.dispose
@song_window = nil
# Destroy help window
@help_window.dispose
@help_window = nil
return
end
# C: Validate Song Magic
if Input.trigger?(Input::C)
# Play SE
$game_system.se_play($data_system.decision_se)
# Set battler action
@reyvateil.song_chant = true
@reyvateil.song_blue = [3, 4, 5, 6].include?(@song_window.skill.scope)
@reyvateil.burst_value = 0
@reyvateil.current_action.kind = 1
@reyvateil.current_action.skill_id = @song_window.skill.id
# Set animation and loop animation
@reyvateil.animation_id = @song_window.skill.animation1_id
@reyvateil.loop_animation_id = KreadCFG::SongMagicChargeAnim[@song_window.skill.id]
@reyvateil.loop_animation_id = 0 if @reyvateil.loop_animation_id == nil
# Create Burst Gauge
if @burst_gauge == nil
@burst_gauge = Burst_Gauge.new(@spriteset.viewport5, @reyvateil)
end
@blue_launch = @reyvateil.song_blue
# Return to previous phase
end_reyvateil_command
return
end
end
#--------------------------------------------------------------------------
# * Frame Update (phase 6: Reyvateil Command selection)
#--------------------------------------------------------------------------
def update_phase6_reyvateil_ring
# Update ring
@reyvateil_ring.update
# B: Cancels command
if Input.trigger?(Input::B)
# Play SE
$game_system.se_play($data_system.cancel_se)
# Return to previous phase
end_reyvateil_command
end
# C: Validate command
if Input.trigger?(Input::C)
# Branch by command
case @reyvateil_ring.command
when KreadCFG::SongMagicName
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Hide command ring
@reyvateil_ring.toggle_visibility
@reyvateil_ring.toggle_activity
# Create Song Magic window and help window
@help_window = Window_SongHelp.new
@song_window = Window_BattleSkill.new(@reyvateil)
@song_window.help_window = @help_window
when KreadCFG::SongActivate
# Do nothing if no song is chanted
unless (@reyvateil.song_chant && !@reyvateil.song_blue)
$game_system.se_play($data_system.buzzer_se)
return
end
# Activates the song
@song_activate = true
when KreadCFG::SongCancel
# Do nothing if no song is chanted
unless @reyvateil.song_chant
$game_system.se_play($data_system.buzzer_se)
return
end
# Play animation
@reyvateil.animation_id = KreadCFG::SongCancelAnimID
# Destroy Burst
@burst_gauge.dispose
@burst_gauge = nil
# Clear action
@reyvateil.song_chant = false
@reyvateil.song_blue = false
@reyvateil.loop_animation_id = 0
@reyvateil.current_action.clear
end_reyvateil_command
when 'Flee'
# Play escape SE
$game_system.se_play($data_system.escape_se)
# Return to BGM before battle started
$game_system.bgm_play($game_temp.map_bgm)
# Battle ends
battle_end(1)
end
end
end
#--------------------------------------------------------------------------
# * End Reyvateil Command
#--------------------------------------------------------------------------
def end_reyvateil_command
@reyvateil_command.visible = true
@reyvateil.blink = false
# Destroy all
@reyvateil_ring.dispose
@reyvateil_ring = nil
if @song_window != nil
@song_window.dispose
@song_window = nil
end
if @help_window != nil
@help_window.dispose
@help_window = nil
end
@action_system.remove_reyvateil
if @previous_phase == nil
start_phase1
else
@phase = @previous_phase
end
end
#--------------------------------------------------------------------------
end
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
# Ar Tonelico Custom Battle System
# Author: Kread-EX
# Version 1.1
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
#===========================================================
# ** Sprite
#------------------------------------------------------------------------------
# Basic sprite class, enhanced with moving capabilities
#===========================================================
class Sprite
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_reader :x_destination
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
alias_method :krx_move_sprite_init, :initialize
def initialize(viewport = nil)
krx_move_sprite_init(viewport) # Original call
# When these two variables are different than the coordinates, the sprite moves.
@x_destination = nil
@y_destination = nil
# Coordinates incrementation.
@increment = 0
end
#--------------------------------------------------------------------------
# * Horizontal move
#--------------------------------------------------------------------------
def x_slide(x_dest, inc)
@x_destination = x_dest
@increment= inc
end
#--------------------------------------------------------------------------
# * Vertical move
#--------------------------------------------------------------------------
def y_slide(y_dest, inc)
@y_destination = y_dest
@increment = inc
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
alias_method :krx_move_sprite_update, :update
def update
update_x_slide
update_y_slide
return if self.is_sliding?
krx_move_sprite_update # Original call
end
#--------------------------------------------------------------------------
# * Update horizontal motion
#--------------------------------------------------------------------------
def update_x_slide
return if @x_destination == nil
if @x_destination > self.x
self.x = [self.x + @increment, @x_destination].min
else
self.x = [self.x - @increment, @x_destination].max
end
@x_destination = nil if @x_destination == self.x
end
#--------------------------------------------------------------------------
# * Update vertical motion
#--------------------------------------------------------------------------
def update_y_slide
return if @y_destination == nil
if @y_destination > self.y
self.y = [self.y + @increment, @y_destination].min
else
self.y = [self.y - @increment, @y_destination].max
end
@y_destination = nil if @y_destination == self.y
end
#--------------------------------------------------------------------------
# * Checks if moving
#--------------------------------------------------------------------------
def is_sliding?
return (@x_destination != nil || @y_destination != nil)
end
#--------------------------------------------------------------------------
end
#===========================================================
# ** RPG::Sprite
#------------------------------------------------------------------------------
# Basic RGSS class, enhanced to display damage with image files and processing multi-hit skills.
#===========================================================
class RPG::Sprite
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize(viewport = nil)
super(viewport)
@_whiten_duration = 0
@_appear_duration = 0
@_escape_duration = 0
@_collapse_duration = 0
@_damage_sprites = []
@_damage_durations = []
@_animation_duration = 0
@_blink = false
end
#--------------------------------------------------------------------------
# * Dispose all
#--------------------------------------------------------------------------
def dispose
@_damage_sprites.each {|spr| dispose_damage(spr)}
dispose_animation
dispose_loop_animation
super
end
#--------------------------------------------------------------------------
# * Determine if effects are displayed
#--------------------------------------------------------------------------
def effect?
@_whiten_duration > 0 ||
@_appear_duration > 0 ||
@_escape_duration > 0 ||
@_collapse_duration > 0 ||
@_animation_duration > 0
end
#--------------------------------------------------------------------------
# * Dispose the damage sprites
#--------------------------------------------------------------------------
def dispose_damage(sprite)
if sprite != nil
sprite.dispose
@_damage_durations.delete_at(@_damage_sprites.index(sprite))
@_damage_durations.compact!
@_damage_sprites.delete(sprite)
@_damage_sprites.compact!
end
end
#--------------------------------------------------------------------------
# * Display damage
#--------------------------------------------------------------------------
def damage(value)
# Creates the bitmap
bitmap = Bitmap.new(519, 124)
bitmap.draw_damage(value) unless value == ''
# And draw it on the sprite
@_damage_sprites.push(::Sprite.new(self.viewport))
@_damage_sprites[-1].bitmap = bitmap
@_damage_sprites[-1].ox = 47 + self.viewport.ox
@_damage_sprites[-1].oy = 32
@_damage_sprites[-1].x = self.x + self.viewport.rect.x
@_damage_sprites[-1].y = self.y - self.oy / 2 + self.viewport.rect.y
@_damage_sprites[-1].z = 3000
# Setup damage durations
@_damage_durations[@_damage_sprites.index(@_damage_sprites[-1])] = 40
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
super
# Update white flash
if @_whiten_duration > 0
@_whiten_duration -= 1
self.color.alpha = 128 - (16 - @_whiten_duration) * 10
end
# Update enemy appearance
if @_appear_duration > 0
@_appear_duration -= 1
self.opacity = (16 - @_appear_duration) * 16
end
# Update escape
if @_escape_duration > 0
@_escape_duration -= 1
self.opacity = 256 - (32 - @_escape_duration) * 10
end
# Update collapse animation
if @_collapse_duration > 0
@_collapse_duration -= 1
self.opacity = 256 - (48 - @_collapse_duration) * 6
end
# Update damage sprites
@_damage_sprites.each {|sprite|
if @_damage_durations[@_damage_sprites.index(sprite)] > 0
@_damage_durations[@_damage_sprites.index(sprite)] -= 1
sprite.y -= 3
sprite.opacity -= 8
if @_damage_durations[@_damage_sprites.index(sprite)] == 0
dispose_damage(sprite)
end
end
}
# Update animation
if @_animation != nil && (Graphics.frame_count % 2 == 0)
@_animation_duration -= 1
update_animation
end
# Update state animation
if @_loop_animation != nil && (Graphics.frame_count % 2 == 0)
update_loop_animation
@_loop_animation_index += 1
@_loop_animation_index %= @_loop_animation.frame_max
end
# Update blink for actor command
if @_blink
@_blink_count = (@_blink_count + 1) % 32
if @_blink_count < 16
alpha = (16 - @_blink_count) * 6
else
alpha = (@_blink_count - 16) * 6
end
self.color.set(255, 255, 255, alpha)
end
# Clear the animation data
@@_animations.clear
end
#--------------------------------------------------------------------------
end
#===========================================================
# ** Sprite_Battler
#------------------------------------------------------------------------------
# This sprite is used to display the battler.It observes the Game_Character
# class and automatically changes sprite conditions.
#===========================================================
class Sprite_Battler < RPG::Sprite
#--------------------------------------------------------------------------
# * Object Initialization
# viewport : viewport
# battler : battler (Game_Battler)
#--------------------------------------------------------------------------
alias_method :krx_atcbs_sprite_battler_initialize, :initialize
def initialize(viewport, battler = nil)
krx_atcbs_sprite_battler_initialize(viewport, battler)
@loop_anim_id = 0
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
super
# Quit if battler is nil
if @battler == nil
self.bitmap = nil
loop_animation(nil)
return
end
# If file name or hue are different than current ones
if @battler.battler_name != @battler_name || @battler.battler_hue != @battler_hue
# Get and set bitmap
@battler_name = @battler.battler_name
@battler_hue = @battler.battler_hue
self.bitmap = RPG::Cache.battler(@battler_name, @battler_hue)
@width = bitmap.width
@height = bitmap.height
self.ox = @width / 2
self.oy = @height
# Change opacity level to 0 when dead or hidden
self.opacity = 0 if @battler.dead? or @battler.hidden
end
# If battler dies when chanting
if @battler.dead?
@battler.burst_value = 0
@battler.song_chant = false
@battler.loop_animation_id = 0
end
# If animation ID is different than current one
if @battler.damage.size == 0 && @battler.state_animation_id != @state_animation_id
@state_animation_id = @battler.state_animation_id
loop_animation($data_animations[@state_animation_id])
end
# Song Magic loop animation
if KreadCFG.is_reyvateil?(@battler) && @battler.loop_animation_id != @loop_anim_id
@loop_anim_id = @battler.loop_animation_id
if @battler.loop_animation_id == 0
loop_animation(nil)
return
end
skill_id = @battler.current_action.skill_id
if skill_id != 0
loop_animation($data_animations[KreadCFG::SongMagicChargeAnim[skill_id]])
else
loop_animation(nil)
end
end
# Blink
if @battler.blink
blink_on
else
blink_off
end
# If invisible
unless @battler_visible
# Appear
if !@battler.hidden && !@battler.dead? && (@battler.damage.size == 0 || @battler.damage_pop)
appear
@battler_visible = true
end
end
# If visible
if @battler_visible
# Escape
if @battler.hidden
$game_system.se_play($data_system.escape_se)
escape
@battler_visible = false
end
# White flash
if @battler.white_flash
whiten
@battler.white_flash = false
end
# Animation
if @battler.animation_id != 0
animation = $data_animations[@battler.animation_id]
animation(animation, @battler.animation_hit)
@battler.animation_id = 0
end
# Damage
if @battler.damage_pop
damage(@battler.damage.shift)
@battler.critical = false
@battler.damage_pop = false
end
# Collapse
if @battler.damage.size == 0 && @battler.dead?
if @battler.is_a?(Game_Enemy)
$game_system.se_play($data_system.enemy_collapse_se)
else
$game_system.se_play($data_system.actor_collapse_se)
end
collapse
@battler_visible = false
end
end
# Set sprite coordinates
self.x = @battler.screen_x
self.y = @battler.screen_y
self.z = @battler.screen_z
end
#--------------------------------------------------------------------------
# * Frame Update: Animation
#--------------------------------------------------------------------------
def update_animation
# Get animation data
if @_animation_duration > 0
frame_index = @_animation.frame_max - @_animation_duration
cell_data = @_animation.frames[frame_index].cell_data
position = @_animation.position
animation_set_sprites(@_animation_sprites, cell_data, position)
# Checks if there is a skill and the skill has multiple hits
skill = $scene.skill
if skill != nil && KreadCFG.skill_hits(skill.id) > 1
# If the frame index match one of the skill timings
KreadCFG::HitTimings[skill.id].each {|i|
if frame_index == i
# Display damage if there is any
@battler.damage_pop = true if @battler.damage.size > 0
end
}
end
# Process timings
@_animation.timings.each {|timing|
if timing.frame == frame_index
animation_process_timing(timing, @_animation_hit)
end
}
else
dispose_animation
end
end
#--------------------------------------------------------------------------
end
#===========================================================
# ** Bitmap
#------------------------------------------------------------------------------
# Basic bitmap class, enhanced with various drawing methods.
#===========================================================
class Bitmap
#--------------------------------------------------------------------------
# * Draws text, but with outline
#--------------------------------------------------------------------------
def draw_outlined_text(x, y, width, height, string, align = 0, outline_color = Color.new(0, 0, 0))
old_color = self.font.color.dup
self.font.color = outline_color
self.draw_text(x - 1, y - 1, width + 1, height + 1, string, align)
self.draw_text(x - 1, y + 1, width + 1, height + 1, string, align)
self.draw_text(x + 1, y - 1, width + 1, height + 1, string, align)
self.draw_text(x + 1, y + 1, width + 1, height + 1, string, align)
self.font.color = old_color
self.draw_text(x, y, width, height, string, align)
end
#--------------------------------------------------------------------------
# * Draws the damage values
#--------------------------------------------------------------------------
def draw_damage(value, element_set = $scene.skill != nil ? $scene.skill.element_set : [])
# Process numeric values
if value.is_a?(Numeric)
# Computes the first digit
if value != 0
digit = Math.log10(value.abs).to_i
# Automatically 0 if the value if 0
else
digit = 0
end
# Checks if the value if negative
if value < 0
filename = 'Damage_Recovery'
# Checks the element_set to know which file to load
elsif element_set.include?(KreadCFG::FireElement)
filename = 'Damage_Fire'
elsif element_set.include?(KreadCFG::IceElement)
filename = 'Damage_Ice'
elsif element_set.include?(KreadCFG::WindElement)
filename = 'Damage_Wind'
else
filename = 'Damage'
end
value = value.abs
# Loads the bitmap
bmp = RPG::Cache.picture(filename)
# Transfer one digit after the other until none remains
x = 0
while digit >= 0
self.blt(x, 0, bmp, Rect.new((value / (10 ** digit)) * 47, 0, 47, 62))
x += 14
value %= 10 ** digit
digit -= 1
end
# Process string damage
else
# Loads the bitmap
bmp = RPG::Cache.picture("Damage_#{value}")
self.blt(0, 0, bmp, bmp.rect)
end
end
#--------------------------------------------------------------------------
end
#===========================================================
# ** Spriteset_Battle
#------------------------------------------------------------------------------
# This class brings together battle screen sprites. It's used within
# the Scene_Battle class.
#===========================================================
class Spriteset_Battle
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_reader :viewport5 # interface sprites viewport
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
# Make viewports
@viewport1 = Viewport.new(0, 0, 640, 480)
@viewport2 = Viewport.new(0, 0, 640, 480)
@viewport3 = Viewport.new(0, 0, 640, 480)
@viewport4 = Viewport.new(0, 0, 640, 480)
@viewport5 = Viewport.new(0, 0, 640, 480)
@viewport2.z = 101
@viewport3.z = 200
@viewport4.z = 5000
@viewport5.z = 6000
# Make battleback sprite
@battleback_sprite = Sprite.new(@viewport1)
# Make enemy sprites
@enemy_sprites = []
$game_troop.enemies.reverse.each {|enemy|
@enemy_sprites.push(Sprite_Battler.new(@viewport1, enemy))
}
# Make actor sprites
@actor_sprites = []
@actor_sprites.push(Sprite_Battler.new(@viewport2))
@actor_sprites.push(Sprite_Battler.new(@viewport2))
@actor_sprites.push(Sprite_Battler.new(@viewport2))
@actor_sprites.push(Sprite_Battler.new(@viewport2))
# Make weather
@weather = RPG::Weather.new(@viewport1)
# Make picture sprites
@picture_sprites = []
(51..100).each {|i|
@picture_sprites.push(Sprite_Picture.new(@viewport3,$game_screen.pictures[i]))
}
# Make timer sprite
@timer_sprite = Sprite_Timer.new
# Frame update
update
end
#--------------------------------------------------------------------------
# * Dispose
#--------------------------------------------------------------------------
alias_method :krx_atcbs_dispose, :dispose
def dispose
krx_atcbs_dispose
@viewport5.dispose
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
# Update actor sprite bitmap (corresponds with actor switching)
@actor_sprites[0].battler = $game_party.actors[0]
@actor_sprites[1].battler = $game_party.actors[1]
@actor_sprites[2].battler = $game_party.actors[2]
@actor_sprites[3].battler = $game_party.actors[3]
# If battleback file name is different from current one
if @battleback_name != $game_temp.battleback_name
@battleback_name = $game_temp.battleback_name
if @battleback_sprite.bitmap != nil
@battleback_sprite.bitmap.dispose
end
# Stretches the battleback if necessary
bmp = RPG::Cache.battleback(@battleback_name)
@battleback_sprite.bitmap = Bitmap.new(640, 480)
@battleback_sprite.bitmap.stretch_blt(@battleback_sprite.bitmap.rect, bmp, bmp.rect)
end
# Update battler sprites
(@enemy_sprites + @actor_sprites).each {|sprite| sprite.update}
# Update weather graphic
@weather.type = $game_screen.weather_type
@weather.max = $game_screen.weather_max
@weather.update
# Update picture sprites
@picture_sprites.each {|sprite| sprite.update}
# Update timer sprite
@timer_sprite.update
# Set screen color tone and shake position
@viewport1.tone = $game_screen.tone
@viewport1.ox = $game_screen.shake
# Set screen flash color
@viewport4.color = $game_screen.flash_color
# Update viewports
@viewport1.update
@viewport2.update
@viewport4.update
@viewport5.update
end
#--------------------------------------------------------------------------
end
#===========================================================
# ** Action_System
#------------------------------------------------------------------------------
# Displays the turn order in battle
#===========================================================
class Action_System < Sprite
#--------------------------------------------------------------------------
# * Public instance variables
#--------------------------------------------------------------------------
attr_reader :queue
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize(viewport)
super(viewport)
create_bitmap
create_battler_icons
update_order
update_coordinates_immediate
end
#--------------------------------------------------------------------------
# * Create the bitmap
#--------------------------------------------------------------------------
def create_bitmap
self.bitmap = RPG::Cache.picture('Action_Turns')
end
#--------------------------------------------------------------------------
# * Create the icons representing the battlers
#--------------------------------------------------------------------------
def create_battler_icons
@queue = []
($game_party.actors + $game_troop.enemies).each {|battler|
next if KreadCFG.is_reyvateil?(battler)
@queue.push(Battler_Icon.new(self.viewport, battler))
}
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
super
@queue.each {|spr| spr.update}
end
#--------------------------------------------------------------------------
# * Update icons order by action meter
#--------------------------------------------------------------------------
def update_order
max_nb = $game_party.actors.size + $game_troop.enemies.size
sel_bat = nil
if @queue.size != max_nb
($game_party.actors + $game_troop.enemies).each {|bat|
sel_bat = bat
already_in_queue = false
next if !bat.exist? || bat == KreadCFG.return_reyvateil
@queue.each {|ico|
if ico.battler == sel_bat
already_in_queue = true
break
end
}
next if already_in_queue
@queue.push(Battler_Icon.new(self.viewport, bat))
}
end
inds = []
@queue.each_index {|i|
if !@queue[i].battler.exist?
@queue[i].dispose
inds.push(i)
end
}
inds.each {|j| @queue[j] = nil}
@queue.compact!
@queue.sort! {|a, b| b.battler.action_meter <=> a.battler.action_meter}
end
#--------------------------------------------------------------------------
# * Update icons coordinates by order
#--------------------------------------------------------------------------
def update_coordinates(with_right_shift = false)
@queue.each_index {|i| @queue[i].x_slide((self.bitmap.width - 130) - 53 * i, 24)}
if with_right_shift
@queue.each_index {|i|
@queue[i].x_slide(@queue[i].x_destination + (i == 0 ? 60 : 53), 12)
}
end
end
#--------------------------------------------------------------------------
# * Update icons coordinates by order immediately
#--------------------------------------------------------------------------
def update_coordinates_immediate
@queue.each_index {|i| @queue[i].x = (self.bitmap.width - 130) - 53 * i}
end
#--------------------------------------------------------------------------
# * Shift the icons to the right
#--------------------------------------------------------------------------
def right_shift
@queue.each_index {|i|
@queue[i].x_slide(@queue[i].x + (i == 0 ? 60 : 53), 12)
}
end
#--------------------------------------------------------------------------
# * Insert the Reyvateil icon
#--------------------------------------------------------------------------
def insert_reyvateil
@queue.push(Battler_Icon.new(self.viewport, $game_party.actors[-1]))
@queue[-1].x = @queue[0].x + 60
end
#--------------------------------------------------------------------------
# * Remove the Reyvateil icon
#--------------------------------------------------------------------------
def remove_reyvateil
@queue[-1].dispose
@queue[-1] = nil
@queue.compact!
end
#--------------------------------------------------------------------------
end
#===========================================================
# ** Battler_Icon
#------------------------------------------------------------------------------
# Displays the battler's graphic for turns in battle
#===========================================================
class Battler_Icon < Sprite
#--------------------------------------------------------------------------
# * Public instance variables
#--------------------------------------------------------------------------
attr_reader :battler
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize(viewport, battler)
super(viewport)
@battler = battler
@am = 0
create_bitmap
setup_initial_coordinates
update
end
#--------------------------------------------------------------------------
# * Create the bitmap
#--------------------------------------------------------------------------
def create_bitmap
# If enemies don't have custom icons, use the default one
bmp = RPG::Cache.picture("BattleFace_#{@battler.name}") rescue NIL
if bmp != nil
self.bitmap = bmp
else
if @battler.is_a?(Game_Enemy)
self.bitmap = RPG::Cache.picture('BattleFace_Enemy').clone
end
end
# Loads action meter bitmap
@am_bmp = RPG::Cache.picture('ActionBar_Full')
end
#--------------------------------------------------------------------------
# * Setups the coordinates for the battle entry
#--------------------------------------------------------------------------
def setup_initial_coordinates
self.y, self.z = 7, 1
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
super
# Updates Action Meter if necessary
if @am != @battler.action_meter
# Computes AM / Max AM ratio
ratio = [(@battler.action_meter / 1000.0), 1000].min
am_rect = Rect.new(0, 0, @am_bmp.width, @am_bmp.height * ratio)
self.bitmap.fill_rect(48, 0, 5, 48, Color.new(0, 0, 0))
self.bitmap.blt(49, 1, @am_bmp, am_rect)
@am = @battler.action_meter
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
#--------------------------------------------------------------------------
alias_method :krx_atcbs_update, :update
def update
krx_atcbs_update
# Set help window coordinates
if @help_window != nil
@help_window.x = self.x - 64
@help_window.y = self.y - 8
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
#--------------------------------------------------------------------------
alias_method :krx_atcbs_update, :update
def update
krx_atcbs_update
# Set help window coordinates
if @help_window != nil
@help_window.x = self.x - 64
@help_window.y = self.y - 8
end
end
#--------------------------------------------------------------------------
end
#===========================================================
# ** Action_Help
#------------------------------------------------------------------------------
# Displays action name in battle
#===========================================================
class Action_Help < Sprite
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize(viewport, action)
super(viewport)
@action = action
set_bitmap
set_coordinates
refresh
end
#--------------------------------------------------------------------------
# * Setup the bitmap
#--------------------------------------------------------------------------
def set_bitmap
# Dispose bitmap if already existing
if self.bitmap != nil
self.bitmap.dispose
self.bitmap = nil
end
# Branch by action kind
if @action.kind == 0 # Basics
self.bitmap = Bitmap.new(8, 8) # Blank Bitmap
else # Skills and Items
self.bitmap = Bitmap.new('Graphics/Pictures/Help')
end
end
#--------------------------------------------------------------------------
# * Setup the coordinates
#--------------------------------------------------------------------------
def set_coordinates
self.ox = self.bitmap.width / 2
self.oy = self.bitmap.height / 2
self.x = 320
self.y = 96
end
#--------------------------------------------------------------------------
# * Refresh
#--------------------------------------------------------------------------
def refresh
# Sets font
self.bitmap.font.name = 'Arial'
self.bitmap.font.size = 32
self.bitmap.font.italic = true
# Branch by kind
case @action.kind
when 1 # Skill
text = $data_skills[@action.skill_id].name
self.bitmap.draw_text(0, 12, self.bitmap.width, 32, text, 1)
when 2 # Item
text = $data_items[@action.item_id].name
self.bitmap.draw_text(0, 12, self.bitmap.width, 32, text, 1)
end
end
#--------------------------------------------------------------------------
end
#===========================================================
# ** Reyvateil_Command
#------------------------------------------------------------------------------
# Displays the Reyvateil special command
#===========================================================
class Reyvateil_Command < Sprite
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize(viewport)
super(viewport)
self.bitmap = Bitmap.new(190, 40)
self.bitmap.font.name = ['Sylfaen', 'Arial']
self.bitmap.font.bold = self.bitmap.font.italic = true
refresh
end
#--------------------------------------------------------------------------
# * Refresh
#--------------------------------------------------------------------------
def refresh
ico = RPG::Cache.icon('button_13')
self.x = 640 - self.bitmap.width
self.y = 480 - self.bitmap.height
self.bitmap.blt(0, 6, ico, ico.rect)
self.bitmap.draw_outlined_text(28, 0, self.bitmap.width, 32,
KreadCFG::ReyvateilClass + ' Command')
end
#--------------------------------------------------------------------------
end
#===========================================================
# ** Burst_Gauge
#------------------------------------------------------------------------------
# Displays the Burst Gauge
#===========================================================
class Burst_Gauge < Sprite
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize(viewport, reyvateil)
super(viewport)
@reyvateil = reyvateil
@last_value = 0
@value_sprite = Burst_Value.new(viewport, reyvateil)
set_bitmap
set_coordinates
end
#--------------------------------------------------------------------------
# * Dispose all
#--------------------------------------------------------------------------
def dispose
super
@value_sprite.dispose
end
#--------------------------------------------------------------------------
# * Create the bitmap
#--------------------------------------------------------------------------
def set_bitmap
@back = RPG::Cache.picture('BurstGauge_Back')
self.bitmap = Bitmap.new(@back.width, @back.height)
self.bitmap.blt(0, 0, @back, @back.rect)
end
#--------------------------------------------------------------------------
# * Setup initial coordinates
#--------------------------------------------------------------------------
def set_coordinates
self.x, self.y, self.z = 8, 416, -5
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
super
# Quit unless stored burst value is different than current burst value
return unless @last_value != @reyvateil.burst_value
return if @reyvateil.dead?
# Refreshes the gauge
filler = RPG::Cache.picture('BurstGauge_Fill')
ratio = (@reyvateil.burst_value * 1.00) /
(KreadCFG::SongMagicMaxBurst[@reyvateil.current_action.skill_id] * 1.00)
rect = Rect.new(0, 0, [(filler.width * ratio).round, filler.width].min, filler.height)
self.bitmap.clear
self.bitmap.blt(0, 0, @back, @back.rect)
self.bitmap.blt(2, 2, filler, rect)
@value_sprite.refresh(@reyvateil.burst_value)
@last_value = @reyvateil.burst_value
end
#--------------------------------------------------------------------------
end
#===========================================================
# ** Burst_Value
#------------------------------------------------------------------------------
# Displays the Burst value
#===========================================================
class Burst_Value < Sprite
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize(viewport, reyvateil)
super(viewport)
set_bitmap
set_coordinates
end
#--------------------------------------------------------------------------
# * Create the bitmap
#--------------------------------------------------------------------------
def set_bitmap
self.bitmap = Bitmap.new(320, 96)
self.bitmap.font.name = ['Abduction II', 'Arial']
self.bitmap.font.size = 32
self.bitmap.draw_outlined_text(2, 2, 320, 96, '0%')
end
#--------------------------------------------------------------------------
# * Setup initial coordinates
#--------------------------------------------------------------------------
def set_coordinates
self.x, self.y, self.z = 332, 375, -4
end
#--------------------------------------------------------------------------
# * Refresh
#--------------------------------------------------------------------------
def refresh(new_value)
self.bitmap.clear
self.bitmap.draw_outlined_text(2, 2, 320, 96, new_value.to_s + '%')
end
#--------------------------------------------------------------------------
end
#===========================================================
# ** Harmonics_Gauge
#------------------------------------------------------------------------------
# Displays the Harmonics gauge.
#===========================================================
class Harmonics_Gauge < Sprite
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize(viewport, reyvateil)
super(viewport)
self.x, self.y = 6, 440
self.bitmap = RPG::Cache.picture('Harmonics_Back')
@reyvateil = reyvateil
@last_harmo = nil
create_vanguards_bar
create_reyvateil_bar if @reyvateil != nil
end
#--------------------------------------------------------------------------
# * Dispose all
#--------------------------------------------------------------------------
def dispose
super
if @v_bar != nil
@vanguards_fill.dispose
@v_bar.bitmap.dispose
@v_bar.dispose
end
if @r_bar != nil
@reyvateil_fill.dispose
@r_bar.bitmap.dispose
@r_bar.dispose
end
end
#--------------------------------------------------------------------------
# * Create the gauge bar (Vanguards)
#--------------------------------------------------------------------------
def create_vanguards_bar
@vanguards_fill = RPG::Cache.picture('Harmonics_Vanguards')
@v_bar = Sprite.new(self.viewport)
@v_bar.bitmap = Bitmap.new(@vanguards_fill.width, @vanguards_fill.height)
@v_bar.x, @v_bar.y, @v_bar.z = self.x + 7, self.y + 7, self.z + 1
end
#--------------------------------------------------------------------------
# * Create the gauge bar (Reyvateil)
#--------------------------------------------------------------------------
def create_reyvateil_bar
@reyvateil_fill = RPG::Cache.picture('Harmonics_Reyvateil')
@r_bar = Sprite.new(self.viewport)
@r_bar.mirror = true
@r_bar.bitmap = Bitmap.new(@reyvateil_fill.width, @reyvateil_fill.height)
@r_bar.x, @r_bar.y, @r_bar.z = self.x + 7, self.y + 7, self.z + 1
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
super
# Quit if Harmonics value didn't change
return unless $game_party.global_harmonics != @last_harmo
# If the global harmonics are maxed, then show special bar
if $game_party.global_harmonics == $game_temp.max_harmonics
bmp = RPG::Cache.picture('Harmonics_Maxed')
rect = bmp.rect
@r_bar.bitmap.clear if @r_bar != nil
@v_bar.bitmap.clear
@v_bar.bitmap.blt(0, 0, bmp, rect)
@last_harmo = $game_party.global_harmonics
return
end
# Update Vanguards bar
if @v_bar != nil
# Computes the amount of global harmonics due to Vanguards
ratio = $game_party.harmonics.to_f / $game_temp.max_harmonics.to_f
# And adjust the rect coordinate
rect = Rect.new(0, 0, (@vanguards_fill.width * ratio).round, @vanguards_fill.height)
@v_bar.bitmap.clear
@v_bar.bitmap.blt(0, 0, @vanguards_fill, rect)
end
# Update Reyvateil bar
if @r_bar != nil
# Computes the amount of global harmonics due to Reyvateil
ratio = @reyvateil.harmonics.to_f / $game_temp.max_harmonics.to_f
# And adjust the rect coordinate
rect = Rect.new(0, 0, (@reyvateil_fill.width * ratio).round, @reyvateil_fill.height)
@r_bar.bitmap.clear
@r_bar.bitmap.blt(0, 0, @reyvateil_fill, rect)
end
@last_harmo = $game_party.global_harmonics
end
#--------------------------------------------------------------------------
end
#===========================================================
# ** Sprite_LevelUp
#------------------------------------------------------------------------------
# Displays levelling up
#===========================================================
class Sprite_LevelUP < Sprite
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize(viewport, actor)
super(viewport)
self.bitmap = Bitmap.new(120, 64)
self.bitmap.font.color = Color.new(0, 0, 0)
self.bitmap.draw_text(1, 1, 80, 32, 'Level Up')
self.bitmap.draw_text(1, 3, 80, 32, 'Level Up')
self.bitmap.draw_text(3, 1, 80, 32, 'Level Up')
self.bitmap.draw_text(3, 3, 80, 32, 'Level Up')
self.bitmap.font.color = Color.new(255, 255, 255)
self.bitmap.draw_text(2, 2, 80, 32, 'Level Up')
self.visible = false
self.x = 560
self.y = 176 + (actor.index * 58)
end
#--------------------------------------------------------------------------
end
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
# Ar Tonelico Custom Battle System
# Author: Kread-EX
# Version 1.1
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
#===========================================================
# ** Window
#------------------------------------------------------------------------------
# Basic window class, enhanced with moving capabilities
#===========================================================
class Window
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
alias_method :krx_move_window_init, :initialize
def initialize(viewport = nil)
krx_move_window_init(viewport) # Original call
# When these two variables are different than the coordinates, the window moves.
@x_destination = nil
@y_destination = nil
# Coordinates incrementation.
@increment = 0
end
#--------------------------------------------------------------------------
# * Horizontal move
#--------------------------------------------------------------------------
def x_slide(x_dest, inc)
@x_destination = x_dest
@increment= inc
end
#--------------------------------------------------------------------------
# * Vertical move
#--------------------------------------------------------------------------
def y_slide(y_dest, inc)
@y_destination = y_dest
@increment = inc
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
alias_method :krx_move_window_update, :update
def update
update_x_slide
update_y_slide
return if self.is_sliding?
krx_move_window_update # Original call
end
#--------------------------------------------------------------------------
# * Update horizontal motion
#--------------------------------------------------------------------------
def update_x_slide
return if @x_destination == nil
if @x_destination > self.x
self.x = [self.x + @increment, @x_destination].min
else
self.x = [self.x - @increment, @x_destination].max
end
@x_destination = nil if @x_destination == self.x
end
#--------------------------------------------------------------------------
# * Update vertical motion
#--------------------------------------------------------------------------
def update_y_slide
return if @y_destination == nil
if @y_destination > self.y
self.y = [self.y + @increment, @y_destination].min
else
self.y = [self.y - @increment, @y_destination].max
end
@y_destination = nil if @y_destination == self.y
end
#--------------------------------------------------------------------------
# * Checks if moving
#--------------------------------------------------------------------------
def is_sliding?
return (@x_destination != nil || @y_destination != nil)
end
#--------------------------------------------------------------------------
end
#===========================================================
# ** Command_Ring
#------------------------------------------------------------------------------
# Ring menu for selecting commands in battle.
#===========================================================
class Command_Ring < Window_Base
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize(actor)
super(500, 350, 320, 320)
self.contents = Bitmap.new(width - 32, height - 32)
self.opacity = 0
@actor = actor
@center_x = [actor.screen_x, 500].min
@center_y = actor.screen_y - 32
@last_x, @last_y = @center_x, @center_y
@index = 0
@active = true
create_commands
create_icons
setup_icons_coordinates
make_self_coordinates
refresh
end
#--------------------------------------------------------------------------
# * Get Index
#--------------------------------------------------------------------------
def index
return @index
end
#--------------------------------------------------------------------------
# * Get selected command
#--------------------------------------------------------------------------
def command
return @commands[@index]
end
#--------------------------------------------------------------------------
# * Dispose objects
#--------------------------------------------------------------------------
def dispose
super
@icons.each {|ico| ico.bitmap.dispose ; ico.dispose}
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
super
make_self_coordinates
correct_coordinates
# Quit here is the ring isn't active
return if !@active
process_rotation
@icons.each {|ico| ico.update}
end
#--------------------------------------------------------------------------
# * Rotates the ring upon keyboard input
#--------------------------------------------------------------------------
def process_rotation
return if self.is_sliding?
# Clockwise
if Input.trigger?(Input::RIGHT)
rotate
@icons[@index].zoom_x = @icons[@index].zoom_y = 2.0
# Counterclockwise
elsif Input.trigger?(Input::LEFT)
rotate(true)
@icons[@index].zoom_x = @icons[@index].zoom_y = 2.0
end
end
#--------------------------------------------------------------------------
# * Refresh
#--------------------------------------------------------------------------
def refresh
command = @commands[@index]
self.contents.clear
self.contents.font.color = Color.new(70, 100, 235, 255)
self.contents.font.name = 'Verdana'
self.contents.font.size = 22
self.contents.font.bold = self.contents.font.italic = true
self.contents.draw_text(0, 0, 320, 36, command)
self.contents.draw_text(0, 2, 320, 36, command)
self.contents.draw_text(2, 0, 320, 36, command)
self.contents.draw_text(2, 2, 320, 36, command)
self.contents.font.color = Color.new(255, 255, 255, 255)
self.contents.draw_text(1, 1, 320, 36, command)
end
#--------------------------------------------------------------------------
# * Makes the ring visible or invisible
#--------------------------------------------------------------------------
def toggle_visibility
self.visible = !self.visible
@icons.each {|ico| ico.visible = !ico.visible}
end
#--------------------------------------------------------------------------
# * Makes the ring active or inactive
#--------------------------------------------------------------------------
def toggle_activity
@active = !@active
end
#--------------------------------------------------------------------------
# * Rotate the ring
#--------------------------------------------------------------------------
def rotate(counterclockwise = false)
make_new_index(counterclockwise)
reset_zoom
d1 = 2.0 * Math::PI / @commands.size
(0...@commands.size).each {|i|
j = i - @index
d = d1 * j + d1
@icons[i].x_slide(@center_x + (96 * Math.sin(d)).to_i, 15) rescue nil
@icons[i].y_slide(@center_y - (96 * Math.cos(d)).to_i, 15)
}
end
#--------------------------------------------------------------------------
# * Correct the coordinates
#--------------------------------------------------------------------------
def correct_coordinates
@center_x, @center_y = [@actor.screen_x, 500].min, @actor.screen_y - 32
if @last_x != @center_x || @last_y != @center_y
self.x_slide(@center_x, 64)
self.y_slide(@center_y, 64)
(0...@icons.size).each {|i|
d1 = 2.0 * Math::PI / @commands.size
j = i - @index
d = d1 * j + d1
@icons[i].x_slide(@center_x + (96 * Math.sin(d)).to_i, 64) rescue nil
@icons[i].y_slide(@center_y - (96 * Math.cos(d)).to_i, 64)
}
@last_x, @last_y = @center_x, @center_y
end
end
#--------------------------------------------------------------------------
# * Determine if the ring is moving
#--------------------------------------------------------------------------
def moving?
@icons.each {|ico| return true if ico.moving?}
return false
end
#--------------------------------------------------------------------------
# * Initialize the icons coordinates
#--------------------------------------------------------------------------
def setup_icons_coordinates
d1 = 2.0 * Math::PI / @commands.size
(0...@commands.size).each {|i|
j = i - @index
d = d1 * j + d1
@icons[i].x = @center_x + (96 * Math.sin(d)).to_i
@icons[i].y = @center_y - (96 * Math.cos(d)).to_i
@icons[i].z += 1000
@icons[i].ox = @icons[i].oy = 12
}
end
#--------------------------------------------------------------------------
# * Calculate the new index
#--------------------------------------------------------------------------
def make_new_index(minus)
@index = minus ? @index - 1 : @index + 1
@index %= @commands.size
refresh
end
#--------------------------------------------------------------------------
# * Calculate the new coordinates
#--------------------------------------------------------------------------
def make_self_coordinates
command = @commands[@index].is_a?(Array) ? @commands[@index][0] : @commands[@index]
self.x = @icons[@index].x - (58 + self.contents.text_size(command).width)
self.y = @icons[@index].y - 32
self.z += 1000
end
#--------------------------------------------------------------------------
# * Reset zoom
#--------------------------------------------------------------------------
def reset_zoom
@counter = 0
@icons.each {|ico|
ico.zoom_x = 1.0
ico.zoom_y = 1.0
}
end
#--------------------------------------------------------------------------
# * Create commands
#--------------------------------------------------------------------------
def create_commands
# Switch to Reyvateil Command if necessary
if KreadCFG.is_reyvateil?(@actor)
create_reyvateil_commands
return
end
@commands = ['Attack']
# Adds Skill if character knows at least one skill
@commands.push('Skill') if @actor.skills.size > 0
# Adds Guard
@commands.push('Guard')
# Adds Item
@commands.push('Item')
# Adds Flee if escape is enabled for this battle
@commands.push('Flee') if $game_temp.battle_can_escape
end
#--------------------------------------------------------------------------
# * Create icons
#--------------------------------------------------------------------------
def create_icons
# Quit if the actor is a Reyvateil
return if KreadCFG.is_reyvateil?(@actor)
@icons = []
# Check commands and add icons corresponding to them
@commands.each {|str|
@icons.push(Sprite.new(self.viewport))
@icons[-1].bitmap = RPG::Cache.icon("RingIcon_#{str.downcase}")
}
end
#--------------------------------------------------------------------------
# * Create commands and icons (Reyvateil Only)
#--------------------------------------------------------------------------
def create_reyvateil_commands
@commands = [KreadCFG::SongMagicName, KreadCFG::SongActivate, KreadCFG::SongCancel]
@icons = [] ; 3.times {@icons.push(Sprite.new(self.viewport))}
@icons[0].bitmap = RPG::Cache.icon('RingIcon_SongMagic')
@icons[1].bitmap = RPG::Cache.icon('RingIcon_SongActivate')
@icons[2].bitmap = RPG::Cache.icon('RingIcon_SongCancel')
# Adds Flee is possible...
return unless $game_temp.battle_can_escape
@commands.push('Flee')
@icons.push(Sprite.new(self.viewport))
@icons[-1].bitmap = RPG::Cache.icon('RingIcon_flee')
end
#--------------------------------------------------------------------------
end
#===========================================================
# ** Ambiance_Field
#------------------------------------------------------------------------------
# Displays ambiance field, as well as enemy name and status effects
#===========================================================
class Ambiance_Field < Window_Base
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
super(0, 0, 260, 96)
self.contents = Bitmap.new(width - 32, height - 32)
self.opacity = 0
self.z = 5000
@battler = nil
end
#--------------------------------------------------------------------------
# * Displays actor information
#--------------------------------------------------------------------------
def set_actor(actor)
set_battler(actor)
end
#--------------------------------------------------------------------------
# * Displays enemy information
#--------------------------------------------------------------------------
def set_enemy(enemy)
set_battler(enemy)
display_ambiance_field_value(enemy) if $game_system.ambiance_field
end
#--------------------------------------------------------------------------
# * Displays battler information
#--------------------------------------------------------------------------
def set_battler(battler)
return if @battler == battler
self.contents.clear
display_name(battler)
display_hp(battler)
@battler = battler
end
#--------------------------------------------------------------------------
# * Displays the name
#--------------------------------------------------------------------------
def display_name(battler)
self.contents.font.color = Color.new(70, 100, 235, 255)
self.contents.font.name = 'Verdana'
self.contents.font.size = 22
self.contents.font.bold = self.contents.font.italic = true
self.contents.draw_text(0, 0, 102, 36, battler.name, 1)
self.contents.draw_text(0, 2, 102, 36, battler.name, 1)
self.contents.draw_text(2, 0, 102, 36, battler.name, 1)
self.contents.draw_text(2, 2, 102, 36, battler.name, 1)
self.contents.font.color = Color.new(255, 255, 255, 255)
self.contents.draw_text(1, 1, 102, 36, battler.name, 1)
end
#--------------------------------------------------------------------------
# * Displays the hp bar
#--------------------------------------------------------------------------
def display_hp(battler)
# Draws Bar back
self.contents.fill_rect(0, 32, 96, 5, Color.new(0, 0, 0))
# Computes HP / Max HP ratio
ratio = battler.hp.to_f / battler.maxhp.to_f
# Draws Bar
full = RPG::Cache.picture('HpBar_Full')
rect = Rect.new(0, 0, (ratio * full.width).round, full.height)
self.contents.blt(1, 33, full, rect)
end
#--------------------------------------------------------------------------
# * Displays the value of the Ambiance Field
#--------------------------------------------------------------------------
def display_ambiance_field_value(enemy)
self.contents.font.size = 52
self.contents.font.color = Color.new(230, 100, 100, 255)
self.contents.draw_text(110, 2, 320, 64, enemy.ambiance_field.to_s)
self.contents.draw_text(110, 4, 320, 64, enemy.ambiance_field.to_s)
self.contents.draw_text(112, 2, 320, 64, enemy.ambiance_field.to_s)
self.contents.draw_text(112, 4, 320, 64, enemy.ambiance_field.to_s)
self.contents.font.color = Color.new(255, 255, 255, 255)
self.contents.draw_text(111, 3, 320, 64, enemy.ambiance_field.to_s)
end
#--------------------------------------------------------------------------
end
#===========================================================
# ** Window_BattleSkill
#------------------------------------------------------------------------------
# This window displays usable skills on the battle screens.
#===========================================================
class Window_BattleSkill < Window_Selectable
#--------------------------------------------------------------------------
# * Object Initialization
# actor : actor
#--------------------------------------------------------------------------
def initialize(actor)
super(0, 128, 240, 256)
self.index = 0
self.back_opacity = 160
self.z = 7000
@actor = actor
@column_max = 1
refresh
end
#--------------------------------------------------------------------------
# * Acquiring Skill
#--------------------------------------------------------------------------
def skill
return @data[self.index]
end
#--------------------------------------------------------------------------
# * Refresh
#--------------------------------------------------------------------------
def refresh
if self.contents != nil
self.contents.dispose
self.contents = nil
end
@data = []
(0...@actor.skills.size).each {|i|
skill = $data_skills[@actor.skills[i]]
@data.push(skill) if skill != nil
}
# If item count is not 0, make a bit map and draw all items
@item_max = @data.size
if @item_max > 0
self.contents = Bitmap.new(width - 32, row_max * 32)
(0...@item_max).each {|i| draw_item(i)}
end
end
#--------------------------------------------------------------------------
# * Draw Item
# index : item number
#--------------------------------------------------------------------------
def draw_item(index)
skill = @data[index]
if @actor.skill_can_use?(skill.id)
self.contents.font.color = normal_color
else
self.contents.font.color = disabled_color
end
x = 4 + index % 1 * (288 + 32)
y = index * 32
rect = Rect.new(x, y, self.width / @column_max - 32, 32)
self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
bitmap = RPG::Cache.icon(skill.icon_name)
opacity = self.contents.font.color == normal_color ? 255 : 128
self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity)
self.contents.draw_text(x + 28, y, 204, 32, skill.name, 0)
end
#--------------------------------------------------------------------------
# * Help Text Update
#--------------------------------------------------------------------------
def update_help
if @help_window.class == Window_SkillHelp
@help_window.set_skill(self.skill, @actor)
else
@help_window.set_skill(self.skill)
end
end
#--------------------------------------------------------------------------
end
#===========================================================
# ** Window_BattleItem
#------------------------------------------------------------------------------
# This window displays usable items on the battle screens.
#===========================================================
class Window_BattleItem < Window_Selectable
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
super(0, 128, 240, 256)
self.index = 0
self.back_opacity = 160
self.z = 7000
@column_max = 1
refresh
end
#--------------------------------------------------------------------------
# * Acquiring Item
#--------------------------------------------------------------------------
def item
return @data[self.index]
end
#--------------------------------------------------------------------------
# * Refresh
#--------------------------------------------------------------------------
def refresh
if self.contents != nil
self.contents.dispose
self.contents = nil
end
@data = []
(1...$data_items.size).each {|i|
item = $data_items[i]
@data.push(item) if [0, 1].include?(item.occasion) && $game_party.item_number(item.id) > 0
}
# If item count is not 0, make a bit map and draw all items
@item_max = @data.size
if @item_max > 0
self.contents = Bitmap.new(width - 32, row_max * 32)
(0...@item_max).each {|i| draw_item(i)}
end
end
#--------------------------------------------------------------------------
# * Draw Item
# index : item number
#--------------------------------------------------------------------------
def draw_item(index)
item = @data[index]
x = 4 + index % 1 * (288 + 32)
y = index * 32
rect = Rect.new(x, y, self.width / @column_max - 32, 32)
self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
bitmap = RPG::Cache.icon(item.icon_name)
self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24))
self.contents.draw_text(x + 28, y, 204, 32, item.name, 0)
end
#--------------------------------------------------------------------------
# * Help Text Update
#--------------------------------------------------------------------------
def update_help
@help_window.set_item(self.item)
end
#--------------------------------------------------------------------------
end
#===========================================================
# ** Window_SkillHelp
#------------------------------------------------------------------------------
# This window displays skill effect on the battle screen. Also works for items.
#===========================================================
class Window_SkillHelp < Window_Base
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
super(240, 128, 240, 256)
self.back_opacity = 160
self.contents = Bitmap.new(width - 32, height - 32)
self.z = 7000
end
#--------------------------------------------------------------------------
# * Set skill
#--------------------------------------------------------------------------
def set_skill(skill, actor)
if @skill != skill || @actor != actor
@skill = skill
@actor = actor
self.contents.clear
draw_skill_hp_cost if !$game_system.vanguards_sp
draw_skill_sp_cost if $game_system.vanguards_sp
draw_skill_description
end
end
#--------------------------------------------------------------------------
# * Set item
#--------------------------------------------------------------------------
def set_item(item)
if @skill != item
@skill = item
self.contents.clear
draw_item_number
draw_skill_description
end
end
#--------------------------------------------------------------------------
# * Draw the hp cost of the skill
#--------------------------------------------------------------------------
def draw_skill_hp_cost
self.contents.font.color = system_color
self.contents.font.italic = true
self.contents.draw_text(0, 0, 96, 32, 'HP Cost')
self.contents.font.color = normal_color
self.contents.draw_text(87, 0, 96, 32, ((@actor.maxhp * @skill.sp_cost) / 100).to_s)
self.contents.font.italic = false
end
#--------------------------------------------------------------------------
# * Draw the sp cost of the skill
#--------------------------------------------------------------------------
def draw_skill_sp_cost
self.contents.font.color = system_color
self.contents.font.italic = true
self.contents.draw_text(0, 0, 96, 32, 'SP Cost')
self.contents.font.color = normal_color
self.contents.draw_text(87, 0, 96, 32, @skill.sp_cost.to_s)
self.contents.font.italic = false
end
#--------------------------------------------------------------------------
# * Draw skill description
#--------------------------------------------------------------------------
def draw_skill_description
# Break the text in lines
lines, last_word, current_text = [], 0, ''
text = @skill.description.clone
(0..text.size).each do |i|
if text[i, 1] == ' ' || i == text.size || text[i, 2] == "\n"
word = text[last_word, i-last_word]
if self.contents.text_size("#{current_text} #{word}").width > (self.width - 32) ||
word.include?("\n")
lines.push(current_text)
current_text = word
else
current_text += (current_text == '' ? word : " #{word}")
end
last_word = i+1
end
end
lines.push("#{current_text} #{text[last_word, text.size-last_word]}")
# Draw the text
self.contents.font.color = normal_color
lines.each_index {|i| self.contents.draw_text(0, 32 + 32 * i, self.width - 32, 32, lines[i])}
end
#--------------------------------------------------------------------------
# * Draw the number possessed of an item
#--------------------------------------------------------------------------
def draw_item_number
self.contents.font.color = system_color
self.contents.font.italic = true
self.contents.draw_text(0, 0, 96, 32, 'Possessed')
self.contents.font.color = normal_color
self.contents.draw_text(103, 0, 96, 32, $game_party.item_number(@skill.id).to_s)
self.contents.font.italic = false
end
#--------------------------------------------------------------------------
end
#===========================================================
# ** Window_SongHelp
#------------------------------------------------------------------------------
# This window displays Song Magic effect on the battle screen
#===========================================================
class Window_SongHelp < Window_Base
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
super(240, 128, 320, 256)
self.back_opacity = 160
self.contents = Bitmap.new(width - 32, height - 32)
self.z = 7000
end
#--------------------------------------------------------------------------
# * Set skill
#--------------------------------------------------------------------------
def set_skill(skill)
if @skill != skill
@skill = skill
self.contents.clear
draw_skill_category
draw_ruler
draw_skill_sp_cost
draw_skill_description
draw_burst_evolutions
end
end
#--------------------------------------------------------------------------
# * Draw Song Magic category (Red or Blue)
#--------------------------------------------------------------------------
def draw_skill_category
category = @skill.scope == 2 ? KreadCFG::SongRed : KreadCFG::SongBlue
self.contents.font.color = system_color
self.contents.draw_text(0, 0, 240, 32, category)
end
#--------------------------------------------------------------------------
# * Draw ruler
#--------------------------------------------------------------------------
def draw_ruler
self.contents.font.name = 'Arial'
self.contents.font.size = 16
char_size = self.contents.text_size('_').width
self.contents.draw_text(0, 8, self.width - 40, 32, '_' * ((self.width - 40) / char_size), 1)
self.contents.font.name = Font.default_name
self.contents.font.size = Font.default_size
end
#--------------------------------------------------------------------------
# * Draw the sp cost of the skill
#--------------------------------------------------------------------------
def draw_skill_sp_cost
self.contents.font.italic = true
self.contents.draw_text(0, 192, 96, 32, 'SP Rate')
self.contents.font.color = normal_color
self.contents.draw_text(72, 192, 96, 32, @skill.sp_cost.to_s)
self.contents.font.italic = false
end
#--------------------------------------------------------------------------
# * Draw skill description
#--------------------------------------------------------------------------
def draw_skill_description
# Break the text in lines
@lines, last_word, current_text = [], 0, ''
text = @skill.description.clone
(0..text.size).each do |i|
if text[i, 1] == ' ' || i == text.size || text[i, 2] == "\n"
word = text[last_word, i-last_word]
if self.contents.text_size("#{current_text} #{word}").width > (self.width - 32) ||
word.include?("\n")
@lines.push(current_text)
current_text = word
else
current_text += (current_text == '' ? word : " #{word}")
end
last_word = i+1
end
end
@lines.push("#{current_text} #{text[last_word, text.size-last_word]}")
# Draw the text
self.contents.font.color = normal_color
@lines.each_index {|i| self.contents.draw_text(0, 32 + 32 * i, self.width - 32, 32, @lines[i])}
end
#--------------------------------------------------------------------------
# * Draw burst evolutions
#--------------------------------------------------------------------------
def draw_burst_evolutions
# Checks evolution pattern
pattern = []
bursts = []
new_skill = @skill.id
while new_skill != nil
unless new_skill == @skill.id
pattern.push($data_skills[new_skill])
bursts.push(KreadCFG::SongMagicMaxBurst[new_skill])
end
new_skill = KreadCFG::SongMagicEvolve[new_skill]
end
# Draws the pattern on the window
return if pattern.size == 0
y = 32 + 32 * @lines.size
self.contents.font.color = system_color
self.contents.font.italic = true
(0...pattern.size).each {|i|
self.contents.draw_text(0, y + i * 32, 320, 32,
"Becomes #{pattern[i].name} at #{bursts[i]}%.")
}
end
#--------------------------------------------------------------------------
end
#===========================================================
# ** Battle_Status
#------------------------------------------------------------------------------
# Displays the status of a party member on the battle screen.
#===========================================================
class Battle_Status < Window_Base
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize(actor_index)
super(432, 0, 240, 96)
self.contents = Bitmap.new(width - 32, height - 32)
self.contents.font.name = ['Staccato222 BT', 'Arial']
self.contents.font.size = 20
self.z = 900
self.opacity = 0
# Get actor
@actor = $game_party.actors[actor_index]
refresh
end
#--------------------------------------------------------------------------
# * Refresh
#--------------------------------------------------------------------------
def refresh
self.contents.clear
# Create the background
if !KreadCFG.is_reyvateil?(@actor) && !$game_system.vanguards_sp
back = RPG::Cache.picture('Status_Window2')
else
back = RPG::Cache.picture('Status_Window')
end
self.contents.blt(0, 0, back, back.rect)
# Create the face
face = RPG::Cache.picture("Status_Window_#{@actor.name}")
self.contents.blt(144, 4, face, face.rect)
# Display HP and SP
refresh_hp
refresh_sp
end
#--------------------------------------------------------------------------
# * Draws current and max HP
#--------------------------------------------------------------------------
def refresh_hp
# Computes HP / Max HP ratio
ratio = @actor.hp.to_f / @actor.maxhp.to_f
# Draws Bar
bar = RPG::Cache.picture('HpBar_Full')
rect = Rect.new(0, 0, (ratio * bar.width).round, bar.height)
self.contents.blt(49, 22, bar, rect)
first_text_size = self.contents.text_size(@actor.hp.to_s).width
second_text_size = self.contents.text_size("/#{@actor.maxhp}").width
# Draws the values
self.contents.font.color = @actor.hp == 0 ? Color.new(255, 64, 0) :
(@actor.hp <= @actor.maxhp / 4) ? Color.new(255, 255, 64) : Color.new(255, 255, 255)
self.contents.draw_outlined_text(48, 0, bar.width - second_text_size, 32, @actor.hp.to_s, 1)
self.contents.font.color = Color.new(255, 255, 255)
self.contents.draw_outlined_text(48 + first_text_size, 0, bar.width - first_text_size, 32,
"/#{@actor.maxhp}", 1)
end
#--------------------------------------------------------------------------
# * Draws current and max SP
#--------------------------------------------------------------------------
def refresh_sp
# Quit in the actor is a vanguard and SP usage disabled
return if !KreadCFG.is_reyvateil?(@actor) && !$game_system.vanguards_sp
# Computes SP / Max SP ratio
ratio = @actor.sp.to_f / @actor.maxsp.to_f
# Draws Bar
bar = RPG::Cache.picture('SpBar_Full')
rect = Rect.new(0, 0, (ratio * bar.width).round, bar.height)
self.contents.blt(49, 42, bar, rect)
first_text_size = self.contents.text_size(@actor.sp.to_s).width
second_text_size = self.contents.text_size("/#{@actor.maxsp}").width
# Draws the values
self.contents.font.color = @actor.sp == 0 ? Color.new(255, 64, 0) :
(@actor.sp <= @actor.maxsp / 4) ? Color.new(255, 255, 64) : Color.new(255, 255, 255)
self.contents.draw_outlined_text(48, 20, bar.width - second_text_size, 32, @actor.sp.to_s, 1)
self.contents.font.color = Color.new(255, 255, 255)
self.contents.draw_outlined_text(48 + first_text_size, 20, bar.width - first_text_size, 32,
"/#{@actor.maxsp}", 1)
end
#--------------------------------------------------------------------------
# * Draws current and max SP (Reyvateil chanting only)
#--------------------------------------------------------------------------
def refresh_sp_only
# Clears the SP part of the bitmap
crop = RPG::Cache.picture('Status_Window_Crop')
self.contents.fill_rect(4, 28, 140, 20, Color.new(0, 0, 0, 0))
self.contents.blt(4, 28, crop, crop.rect)
# Computes SP / Max SP ratio
ratio = @actor.sp.to_f / @actor.maxsp.to_f
# Draw bar
bar = RPG::Cache.picture('SpBar_Full')
rect = Rect.new(0, 0, (ratio * bar.width).round, bar.height)
self.contents.blt(49, 42, bar, rect)
first_text_size = self.contents.text_size(@actor.sp.to_s).width
second_text_size = self.contents.text_size("/#{@actor.maxsp}").width
# Draws the values
self.contents.font.color = @actor.sp == 0 ? Color.new(255, 64, 0) :
(@actor.sp <= @actor.maxsp / 4) ? Color.new(255, 255, 64) : Color.new(255, 255, 255)
self.contents.draw_outlined_text(48, 20, bar.width - second_text_size, 32, @actor.sp.to_s, 1)
self.contents.font.color = Color.new(255, 255, 255)
self.contents.draw_outlined_text(48 + first_text_size, 20, bar.width - first_text_size, 32,
"/#{@actor.maxsp}", 1)
end
#--------------------------------------------------------------------------
end
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
# Ar Tonelico Custom Battle System
# Author: Kread-EX
# Version 1.1
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
#===========================================================
# ** Game_System
#------------------------------------------------------------------------------
# This class handles data surrounding the system. Backround music, etc.
# is managed here as well. Refer to "$game_system" for the instance of
# this class.
#===========================================================
class Game_System
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_accessor :ambiance_field # If true, the ambiance field is activated
attr_accessor :vanguards_sp # If true, the front liners use SP for their skills
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
alias_method :krx_atcbs_initialize, :initialize
def initialize
krx_atcbs_initialize
@ambiance_field = true
@vanguards_sp = false
end
#--------------------------------------------------------------------------
end
#===========================================================
# ** Game_Battler
#------------------------------------------------------------------------------
# This class deals with battlers. It's used as a superclass for the Game_Actor
# and Game_Enemy classes.
#===========================================================
class Game_Battler
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_accessor :action_meter # Sort of ATB counter - roughly
attr_accessor :song_chant # If true, the a song is currently active
attr_accessor :song_blue # If true, the current song is Blue Magic
attr_accessor :burst_value # Actual burst value for the song
attr_accessor :harmonics # Actual harmonics value (Reyvateil only)
attr_accessor :loop_animation_id # ID of the looping animation
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
alias_method :krx_atcbs_initialize, :initialize
def initialize
krx_atcbs_initialize
@action_meter = 0
@song_chant = false
@song_blue = false
@burst_value = 0
@harmonics = 0
@loop_animation_id = 0
@damage = []
end
#--------------------------------------------------------------------------
# * Determine Usable Skills
# skill_id : skill ID
#--------------------------------------------------------------------------
def skill_can_use?(skill_id)
# Check HP requirements.
if !$game_system.vanguards_sp
if self.is_a?(Game_Actor) && !KreadCFG.is_reyvateil?(self)
return false if self.hp <= (self.maxhp * $data_skills[skill_id].sp_cost) / 100
end
end
# In case of Harmo Overdrive, need the correct amount of Harmonics
if KreadCFG::HarmoOverdriveSkills.include?(skill_id) && self.is_a?(Game_Actor)
if $game_party.global_harmonics < $game_temp.max_harmonics
return false
end
end
# If there's not enough SP, the skill cannot be used.
if $data_skills[skill_id].sp_cost > self.sp
return false
end
# Unusable if incapacitated
if dead?
return false
end
# If silent, only physical skills can be used
if $data_skills[skill_id].atk_f == 0 and self.restriction == 1
return false
end
# Get usable time
occasion = $data_skills[skill_id].occasion
# If in battle
if $game_temp.in_battle
# Usable with [Normal] and [Only Battle]
return (occasion == 0 or occasion == 1)
# If not in battle
else
# Usable with [Normal] and [Only Menu]
return (occasion == 0 or occasion == 2)
end
end
#--------------------------------------------------------------------------
# * Applying Normal Attack Effects
# attacker : battler
#--------------------------------------------------------------------------
def attack_effect(attacker)
# Clear critical flag
self.critical = false
# First hit detection
hit_result = (rand(100) < attacker.hit)
# If hit occurs
if hit_result == true
# Calculate basic damage
atk = [attacker.atk - self.pdef / 2, 0].max
self.damage[0] = atk * (20 + attacker.str) / 20
# Element correction
self.damage[0] *= elements_correct(attacker.element_set)
self.damage[0] /= 100
# If damage value is strictly positive
if self.damage[0] > 0
# Critical correction
if rand(100) < 4 * attacker.dex / self.agi
self.damage[0] *= 2
self.critical = true
end
# Guard correction
self.damage[0] /= 2 if self.guarding?
end
# Dispersion
if self.damage[0].abs > 0
amp = [self.damage[0].abs * 15 / 100, 1].max
self.damage[0] += rand(amp+1) + rand(amp+1) - amp
end
# Second hit detection
eva = 8 * self.agi / attacker.dex + self.eva
hit = self.damage[0] < 0 ? 100 : 100 - eva
hit = self.cant_evade? ? 100 : hit
hit_result = (rand(100) < hit)
end
# If hit occurs
if hit_result == true
# State Removed by Shock
remove_states_shock
# Substract damage from HP
self.hp -= self.damage[0]
# Raise Ambiance Field
if $game_system.ambiance_field
@ambiance_field = [(@ambiance_field + 1), 3].min if self.is_a?(Game_Enemy)
end
# State change
@state_changed = false
states_plus(attacker.plus_state_set)
states_minus(attacker.minus_state_set)
# Update harmonics
if attacker.is_a?(Game_Actor)
$scene.vanguards_harmonics += 50
else
if KreadCFG.return_reyvateil == self
$scene.reyvateil_harmonics -= 50
else
$scene.vanguards_harmonics -= 50
end
end
# When missing
else
# Set damage to "Miss"
self.damage[0] = 'Miss'
# Clear critical flag
self.critical = false
end
# End Method
return true
end
#--------------------------------------------------------------------------
# * Apply Skill Effects
# user : the one using skills (battler)
# skill : skill
#--------------------------------------------------------------------------
def skill_effect(user, skill, hit_number = 0)
# 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
if ((skill.scope == 3 or skill.scope == 4) and self.hp == 0) or
((skill.scope == 5 or skill.scope == 6) and self.hp >= 1)
# End Method
return false
end
# Clear effective flag
effective = false
# Set effective flag if common ID is effective
effective |= skill.common_event_id > 0
# 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)
# Calculate basic damage
self.damage[hit_number] = power * rate / 20
# Element correction
self.damage[hit_number] *= elements_correct(skill.element_set)
self.damage[hit_number] /= 100
# If damage value is strictly positive
if self.damage[hit_number] > 0
# Raise Ambiance Field
@ambiance_field = [(@ambiance_field + 1), 3].min if self.is_a?(Game_Enemy)
# Guard correction
if self.guarding?
self.damage[hit_number] /= 2
end
end
# Dispersion
if skill.variance > 0 and self.damage[-1].abs > 0
amp = [self.damage[hit_number].abs * skill.variance / 100, 1].max
self.damage[hit_number] += rand(amp+1) + rand(amp+1) - amp
end
# Second hit detection
eva = 8 * self.agi / user.dex + self.eva
hit = self.damage[hit_number] < 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
# Update harmonics
if hit_number == 0 && !KreadCFG::HarmoOverdriveSkills.include?(skill.id) && skill.scope < 3
if user.is_a?(Game_Actor)
$scene.vanguards_harmonics += skill.scope == 1 ? 80 : 20
else
if KreadCFG.return_reyvateil == self
$scene.reyvateil_harmonics -= 80
else
$scene.vanguards_harmonics -= skill.scope == 1 ? 80 : 20
end
end
end
# 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[hit_number]
effective |= self.hp != last_hp
# State change
@state_changed = false
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[hit_number] = ''
# If state is unchanged
unless @state_changed
# Set damage to "Miss"
self.damage[hit_number] = 'Miss'
end
end
# If miss occurs
else
# Set damage to "Miss"
self.damage[hit_number] = 'Miss'
end
# If not in battle
unless $game_temp.in_battle
# Set damage to an empty array
self.damage = []
end
# End Method
return effective
end
#--------------------------------------------------------------------------
# * Apply Song Magic effects
# user : the Reyvateil
# skill : skill
#--------------------------------------------------------------------------
def song_effect(user, skill, hit_number = 0)
# 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
if ((skill.scope == 3 or skill.scope == 4) and self.hp == 0) or
((skill.scope == 5 or skill.scope == 6) and self.hp >= 1)
# End Method
return false
end
# Song Magic never miss, so no hit detection is performed
# Power calculation method (for Red Magic only):
if skill.scope == 2
power = (([(user.int - self.mdef), 0].max + user.burst_value) * (skill.power / 100.00)).round
else
# For Blue Magic, skill base power only
power = skill.power
power -= user.int if power != 0
end
self.damage[hit_number] = power
# Ambiance Field correction
self.damage[hit_number] += (@ambiance_field / 3) * power if self.damage[hit_number] > 0
# Element correction
self.damage[hit_number] *= elements_correct(skill.element_set)
self.damage[hit_number] /= 100
# Dispersion
if skill.variance > 0 and self.damage[hit_number].abs > 0
amp = [self.damage[hit_number].abs * skill.variance / 100, 1].max
self.damage[hit_number] += rand(amp+1) + rand(amp+1) - amp
end
# Substract damage from HP
last_hp = self.hp
self.hp -= self.damage[hit_number]
return true
end
#--------------------------------------------------------------------------
# * Application of Item Effects
# item : item
#--------------------------------------------------------------------------
def item_effect(item)
# Clear critical flag
self.critical = false
# 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
if ((item.scope == 3 or item.scope == 4) and self.hp == 0) or
((item.scope == 5 or item.scope == 6) and self.hp >= 1)
# End Method
return false
end
# Clear effective flag
effective = false
# Set effective flag if common ID is effective
effective |= item.common_event_id > 0
# Determine hit
hit_result = (rand(100) < item.hit)
# Set effective flag is skill is uncertain
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 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
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 an empty array
self.damage = []
end
# End Method
return effective
end
#--------------------------------------------------------------------------
# * Application of Slip Damage Effects
#--------------------------------------------------------------------------
def slip_damage_effect
# Set damage
self.damage << self.maxhp / 10
# Dispersion
if self.damage[-1].abs > 0
amp = [self.damage[-1].abs * 15 / 100, 1].max
self.damage[-1] += rand(amp+1) + rand(amp+1) - amp
end
# Subtract damage from HP
self.hp -= self.damage[-1]
# End Method
return true
end
#--------------------------------------------------------------------------
end
#===========================================================
# ** Game_Enemy
#------------------------------------------------------------------------------
# This class handles enemies. It's used within the Game_Troop class
# ($game_troop).
#===========================================================
class Game_Enemy < Game_Battler
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_accessor :ambiance_field
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
alias_method :krx_atcbs_game_enemy_initialize, :initialize
def initialize(troop_id, member_index)
@ambiance_field = 0
krx_atcbs_game_enemy_initialize(troop_id, member_index)
end
#--------------------------------------------------------------------------
# * Make Action
#--------------------------------------------------------------------------
def make_action
# Clear current action
self.current_action.clear
# If unable to move
unless self.movable?
# End Method
return
end
# Extract current effective actions
available_actions = []
rating_max = 0
for action in self.actions
# Confirm turn conditions
n = $game_temp.battle_turn
a = action.condition_turn_a
b = action.condition_turn_b
if (b == 0 and n != a) or
(b > 0 and (n < 1 or n < a or n % b != a % b))
next
end
# Confirm HP conditions
if self.hp * 100.0 / self.maxhp > action.condition_hp
next
end
# Confirm level conditions
if $game_party.max_level < action.condition_level
next
end
# Confirm switch conditions
switch_id = action.condition_switch_id
if switch_id > 0 and $game_switches[switch_id] == false
next
end
# Add this action to applicable conditions
available_actions.push(action)
if action.rating > rating_max
rating_max = action.rating
end
end
# Calculate total with max rating value at 3 (exclude 0 or less)
ratings_total = 0
for action in available_actions
if action.rating > rating_max - 3
ratings_total += action.rating - (rating_max - 3)
end
end
# If ratings total isn't 0
if ratings_total > 0
# Create random numbers
value = rand(ratings_total)
# Set things that correspond to created random numbers as current action
for action in available_actions
if action.rating > rating_max - 3
if value < action.rating - (rating_max - 3)
self.current_action.kind = action.kind
self.current_action.basic = action.basic
self.current_action.skill_id = action.skill_id
self.current_action.decide_random_target_for_enemy
case action.kind
when 0
self.action_meter = self.agi
when 1
self.action_meter = self.agi * KreadCFG.skill_speed(action.skill_id)
end
return
else
value -= action.rating - (rating_max - 3)
end
end
end
end
end
#--------------------------------------------------------------------------
end
#===========================================================
# ** Game_Party
#------------------------------------------------------------------------------
# This class handles the party. It includes information on amount of gold
# and items. Refer to "$game_party" for the instance of this class.
#===========================================================
class Game_Party
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_reader :harmonics # Vanguards Harmonics, without Reyvateil value
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
alias_method :krx_atcbs_initialize, :initialize
def initialize
krx_atcbs_initialize # Original call
@harmonics = 0
end
#--------------------------------------------------------------------------
# * Change Harmonic value
#--------------------------------------------------------------------------
def harmonics=(harmonics)
@harmonics = harmonics
if self.global_harmonics > $game_temp.max_harmonics
substract = KreadCFG.return_reyvateil == nil ? 0 : KreadCFG.return_reyvateil.harmonics
@harmonics = $game_temp.max_harmonics - substract
end
end
#--------------------------------------------------------------------------
# * Returns Global Harmonics value
#--------------------------------------------------------------------------
def global_harmonics
return @harmonics if KreadCFG.return_reyvateil == nil
return (@harmonics + KreadCFG.return_reyvateil.harmonics)
end
#--------------------------------------------------------------------------
end
#===========================================================
# ** Game_Temp
#------------------------------------------------------------------------------
# This class handles temporary data that is not included with save data.
# Refer to "$game_temp" for the instance of this class.
#===========================================================
class Game_Temp
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_accessor :max_harmonics
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
alias_method :krx_atcbs_initialize, :initialize
def initialize
krx_atcbs_initialize
@max_harmonics = 1000
end
#--------------------------------------------------------------------------
end