class Game_Battler
attr_reader :id # ID
attr_reader :x # map x-coordinate (logical)
attr_reader :y # map y-coordinate (logical)
attr_reader :real_x # map x-coordinate (real * 128)
attr_reader :real_y # map y-coordinate (real * 128)
attr_reader :tile_id # tile ID (invalid if 0)
attr_reader :character_name # character file name
attr_reader :character_hue # character hue
attr_reader

pacity # opacity level
attr_reader :blend_type # blending method
attr_accessor :direction # direction
attr_reader :pattern # pattern
attr_reader :move_route_forcing # forced move route flag
attr_reader :through # through
attr_accessor :animation_id # animation ID
attr_accessor :transparent # transparent flag
attr_accessor :step_anime # non walking animation state
attr_accessor :moved
attr_accessor :perf_action
attr_accessor :atb
attr_accessor :neutral
attr_accessor :tactic
attr_accessor :current_action
attr_accessor :collapsed
attr_accessor :skill_cast
attr_reader :timer
attr_reader :tile_id
attr_reader :remain_move
attr_accessor :damage2
attr_accessor :damage2_pop
attr_accessor :h
attr_accessor :th
attr_accessor :pause
attr_reader :projectiles
attr_accessor :attacker_dir
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
alias battler_initialize initialize
def initialize
battler_initialize
@id = 0
@x = 0
@y = 0
@h = 0
@th = 0
@real_x = 0
@real_y = 0
@tile_id = 0
@character_name = ""
@character_hue = 0
@opacity = 255
@blend_type = 0
@direction = 2
@pattern = 0
@move_route_forcing = false
@through = false
@animation_id = 0
@transparent = false
@original_direction = 2
@original_pattern = 0
@move_type = 0
@move_speed = 4
@move_frequency = 6
@move_route = nil
@move_route_index = 0
@original_move_route = nil
@original_move_route_index = 0
@walk_anime = true
@step_anime = false
@direction_fix = false
@always_on_top = false
@anime_count = 0
@stop_count = 0
@jump_count = 0
@jump_peak = 0
@wait_count = 0
@locked = false
@prelock_direction = 0
@atb = 0
@move_route = []
@perf_action = false
@moved = false
@remain_move = [0,0]
@neutral = false
@tactic = 1
@collapsed = false
@view_range = GTBS::VIEW_RANGE
@tile_id = 0
@skillcasting = 0
@skill_cast = nil
@stop_anim = false
@pose = 0
@timer = 0
@current_action = Game_BattleAction.new
@damage2 = nil
@damage2_pop = false
@pause = false
@projectiles = []
@attacker_dir = -1
end
#--------------------------------------------------------------------------
# Projectile in motion - used to determine if projectile has not yet hit target
#--------------------------------------------------------------------------
def projectile_in_motion?
return true if @projectiles.size > 0
return false
end
#--------------------------------------------------------------------------
# Counter Result - Used to determine if char can COUNTER the attack
#--------------------------------------------------------------------------
def counter_result(attacker)
#return false if not counter state
return [false, nil] if !state?(GTBS::COUNTER_ID)
return [false, nil] if self == attacker
return [false, nil] if (self.is_a?(Game_Actor) and attacker.is_a?(Game_Actor)) or (self.is_a?(Game_Enemy) and attacker.is_a?(Game_Enemy))
dist = (attacker.x-self.x).abs + (attacker.y - self.y).abs
#return false if distance greater than 1
return [false, nil] if dist > 1
#set default percentage
perc = 25
if self.hp/self.maxhp.to_f < 0.25
#increase rate by 10% when 25% of hp, makes 35% counter rate
perc += 10
elsif self.hp/self.maxhp.to_f < 0.50
#increase rate by 5% when 50% of hp, makes 30% counter rate
perc += 5
end
#Figure counter based on %
if rand(100) < perc #if rand less than %, counter = true
return [true, self]
else #failed to counter
return [false, nil]
end
end
#--------------------------------------------------------------------------
# Check if battler is paused by event
#--------------------------------------------------------------------------
def paused?
return @pause
end
#--------------------------------------------------------------------------
# Current height
#--------------------------------------------------------------------------
def screen_h
return @h
end
#--------------------------------------------------------------------------
# Current tile height
#--------------------------------------------------------------------------
def screen_th
return 0 if !$game_map.iso?
tile_id = $game_map.map.data[self.x,self.y,0]
t_x = (tile_id - 384) % 8
t_y = (tile_id - 384) / 8
th = t_x + t_y * 8
return th
end
#--------------------------------------------------------------------------
# * Add State
# state_id : state ID
# force : forcefully added flag (used to deal with auto state)
#--------------------------------------------------------------------------
def add_state(state_id, force = false)
# For an ineffective state
if $data_states[state_id] == nil
# End Method
return
end
# If not forcefully added
unless force
# A state loop already in existance
for i in @states
# If a new state is included in the state change (-) of an existing
# state, and that state is not included in the state change (-) of
# a new state (example: an attempt to add poison during dead)
if $data_states
.minus_state_set.include?(state_id) and
not $data_states[state_id].minus_state_set.include?(i)
# End Method
return
end
end
end
# If this state is not added
unless state?(state_id)
# Add state ID to @states array
@states.push(state_id)
# If option [regarded as HP 0]is effective
if $data_states[state_id].zero_hp
# Change HP to 0
@hp = 0
end
# All state loops
for i in 1...$data_states.size
# Dealing with a state change (+)
if $data_states[state_id].plus_state_set.include?(i)
add_state(i)
end
# Dealing with a state change (-)
if $data_states[state_id].minus_state_set.include?(i)
remove_state(i)
end
end
# line change to a large rating order (if value is the same, then a
# strong restriction order)
@states.sort! do |a, b|
state_a = $data_states[a]
state_b = $data_states
if state_a.rating > state_b.rating
-1
elsif state_a.rating < state_b.rating
+1
elsif state_a.restriction > state_b.restriction
-1
elsif state_a.restriction < state_b.restriction
+1
else
a <=> b
end
end
end
# If added forcefully
if force
# Set the natural removal's lowest number of turns to -1
@states_turn[state_id] = -1
end
# If not added forcefully
unless @states_turn[state_id] == -1
# Set the natural removal's lowest number of turns
@states_turn[state_id] = $data_states[state_id].hold_turn
end
# Check the maximum value of HP and SP
@hp = [@hp, self.maxhp].min
@sp = [@sp, self.maxsp].min
end
#--------------------------------------------------------------------------
# * Checks states for Doom
#--------------------------------------------------------------------------
def has_doom?
for i in @states
if $data_states.is_doom_state?
if self.doom_counter != nil
self.doom_counter -= 1
if self.doom_counter < 0
self.doom_counter = nil
self.damage = 'DOOM!'
self.damage_pop = true
self.hp -= self.hp
return
end
self.damage2 = "0#{self.doom_counter}"
self.damage2_pop = true
end
end
end
end
#--------------------------------------------------------------------------
# * Sets actors current pose based on id
#--------------------------------------------------------------------------
def set_pose(type)
if self.moving?
return 6 unless self.dead?
end
case type
when "wait" ; @pose = 0
when "attack" ; @pose = 1 ;@timer = 36
when "defend" ; @pose = 2 ;@timer = 36
when "pain" ; @pose = 3 ;@timer = 36
when "casting" ; @pose = 4 ;@timer = 36
when "collapse" ; @pose = 5 #dead
when "walk" ; @pose = 6
when "cast" ; @pose = 7 ;@timer = 36
when "heal" ; @pose = 8 ;@timer = 36
when "spec1" ; @pose = 9 ;@timer = 36
when "spec2" ; @pose = 10;@timer = 36
else; @pose = 0
end
end
#--------------------------------------------------------------------------
# * Checks current pose
#--------------------------------------------------------------------------
def pose?
return @pose
end
#--------------------------------------------------------------------------
# * Resets animation frame to start
#--------------------------------------------------------------------------
def reset_frame
@pattern = 0
end
#--------------------------------------------------------------------------
# * Returns character name, unless in battle. Then returns battler name.
#--------------------------------------------------------------------------
def character_name
if $game_temp.in_battle
return @battler_name
else
return @character_name
end
end
#--------------------------------------------------------------------------
# * Knock Back - Checks for "knock back"
#--------------------------------------------------------------------------
def knock_back(attacker)
case attacker.direction
when 2 #down
@y += 1
when 4
@x -= 1
when 6
@x += 1
when 8
@y -= 1
end
end
def paralyzed?
return state?(GTBS::PARALYZED_ID)
end
def sleeping?
return state?(GTBS::SLEEPING_ID)
end
def knocked_out?
return state?(1)
end
def muted?
return true if self.restriction == 1
return false
end
#--------------------------------------------------------------------------
# * Return if actor has collapsed
#--------------------------------------------------------------------------
def collapsed?
if !dead?
@collapsed = false
end
return @collapsed
end
#--------------------------------------------------------------------------
# * Prepare wait skill
#--------------------------------------------------------------------------
def setup_skill
@skillcasting = GTBS::skill_wait(@skill_cast[0].id)
end
#--------------------------------------------------------------------------
# * In the act of Casting?
#--------------------------------------------------------------------------
def casting?
return true if @skillcasting > 0
return false
end
#--------------------------------------------------------------------------
# * Returns what you are "Casting"
#--------------------------------------------------------------------------
def cast
return @skill_cast
end
#--------------------------------------------------------------------------
# * Updates current casting time, or resets it
#--------------------------------------------------------------------------
def up_cast(reset = false)
if reset == false
@skillcasting -= int
else
@skillcasting = 0
end
end
def view_range
return @view_range
end
#--------------------------------------------------------------------------
# * Update ATB - used for Active Time
#--------------------------------------------------------------------------
def up_atb(amount)
@atb += amount
return @atb
end
#--------------------------------------------------------------------------
# * Resets ATB
#--------------------------------------------------------------------------
def reset_atb
@atb = 0
return @atb
end
#--------------------------------------------------------------------------
# * Clear TBS Actions - Resets tbs flags for moved/acted
#--------------------------------------------------------------------------
def clear_tbs_actions(override = false)
if override
@current_action.clear(true)
else
@current_action.clear
end
@moved = false
@perf_action = false
@state_animation_id = 0
end
#--------------------------------------------------------------------------
# * Returns if actor has moved completely or not
#--------------------------------------------------------------------------
def moved?
if remain_move[0] != $game_temp.battle_turn
reset_move
end
if GTBS::MOVE_VARIABLE
return false if state?(GTBS::DONT_MOVE_ID)
if @remain_move[1] > 0
return false
else
return true
end
else
return @moved
end
end
#--------------------------------------------------------------------------
# * used with variable move - not fully implemented yet.
#--------------------------------------------------------------------------
def reset_move
if remain_move[0] != $game_temp.battle_turn
remain_move[0] = $game_temp.battle_turn
move = base_move_range
for s_id in @states
case s_id
when 11 #delay (slow)
move -= 2
end
end
remain_move[1] = move
end
end
#--------------------------------------------------------------------------
# * Returns true if you have ACTED
#--------------------------------------------------------------------------
def perfaction?
return @perf_action
end
#--------------------------------------------------------------------------
# * Not stuck?
#--------------------------------------------------------------------------
def movable?
return (not @hidden and restriction < 4)
end
#--------------------------------------------------------------------------
# * set state animation
#--------------------------------------------------------------------------
def state_animation_id=(value)
@state_animation_id = value
self.update
end
def action_list
if self.is_a?(Game_Enemy)
self.current_action.clear
return [] if !self.movable?
available_actions = []
for action in self.actions
#p action
n = $game_temp.battle_turn + 1
a = action.condition_turn_a
b = action.condition_turn_b
next if (b == 0 and n != a) or (b > 0 and (n < 1 or n < a or n % b != a % b))
next if self.hp * 100.0 / self.maxhp > action.condition_hp
next if $game_party.max_level < action.condition_level
switch_id = action.condition_switch_id
next if switch_id > 0 and $game_switches[switch_id] == false
next if action.kind == 1 and !skill_can_use?(action.skill_id)
available_actions.push(action)
end
return available_actions
else
return [] if !self.movable?
available_actions = []
attack = RPG::Enemy::Action.new
available_actions.push(attack)
for i in 0...skills.size
skill = $data_skills[skills]
next if skill == nil
next if !skill_can_use?(skills)
s = RPG::Enemy::Action.new
s.kind = 1
s.skill_id = skills
available_actions.push(s)
end
return available_actions
end
end
def moving?
return (@real_x != @x * 128 or @real_y != @y * 128)
end
def jumping?
return @jump_count > 0
end
def straighten
if @walk_anime or @step_anime
@pattern = 0
end
@anime_count = 0
@prelock_direction = 0
end
def bush_depth
if @tile_id > 0 or @always_on_top
return 0
end
if @jump_count == 0 and $game_map.bush?(@x, @y)
return 12
else
return 0
end
end
def force_move_route(move_route)
if @original_move_route == nil
@original_move_route = @move_route
@original_move_route_index = @move_route_index
end
@move_route = move_route
@move_route_index = 0
@move_route_forcing = true
@prelock_direction = 0
@wait_count = 0
move_type_custom
end
def atb_set(atb)
@atb = atb
end
def atb
return @atb
end
def atb_update
@atb += agi.to_i
end
def place(x, y)
@x = x
@y = y
@real_x = @x * 128
@real_y = @y * 128
end
#--------------------------------------------------------------------------
# * Passable? - determins if proposed x,y in direction are a passable
#--------------------------------------------------------------------------
def passable?(x, y, d)
if $game_map.iso?
@diff_n = ISO_LVL2_Config::DIFF_N
@diff_l = ISO_LVL2_Config::DIFF_L
new_x = x + (d == 6 ? 1 : d == 4 ? -1 : d == 1 ? -1 : d == 3 ? 1 : d == 7 ? -1 : d == 9 ? 1 : 0)
new_y = y + (d == 2 ? 1 : d == 8 ? -1 : d == 1 ? 1 : d == 3 ? 1 : d == 7 ? -1 : d == 9 ? -1 : 0)
tile_id = $game_map.map.data[x, y, 0]
return false if tile_id.nil?
t_x= (tile_id - 384)%8
t_y= (tile_id - 384)/8
h = t_x + t_y * 8
new_tile_id = $game_map.map.data[new_x, new_y,0]
return false if new_tile_id == nil
new_t_x= (new_tile_id - 384)%8
new_t_y= (new_tile_id - 384)/8
new_h = new_t_x + new_t_y * 8
tile_tag = $game_map.terrain_tag(x, y)
tile_tag_new = $game_map.terrain_tag(new_x, new_y)
if tile_tag == 1
@diff = @diff_l
else
@diff = @diff_n
end
#If flying, then can accend 4 levels higher than normal (meaning they can go up a wall that is height 6)
if state?(GTBS::FLYING_ID)
@diff += 4
end
return false if new_x.nil? or new_y.nil?
unless $game_map.valid?(new_x, new_y) and (new_h - h) <= @diff and (new_h - h) >= -@diff
return false
end
if @through
return true
end
for event in $scene.battle_events.values
if event.character_name != "" and
event.x == new_x and event.y == new_y and not event.through
return false
end
end
#If character flying return true
if state?(GTBS::FLYING_ID) and $game_map.terrain_tag(new_x,new_y) >= 6
return true
end
#If character can "walk on water" and tile is water, return true
if state?(GTBS::WWATER_ID) and $game_map.terrain_tag(new_x,new_y) == 6
return true
end
unless $game_map.passable?(x, y, d, self)
return false
end
unless $game_map.passable?(new_x, new_y, 10 - d)
return false
end
if $game_temp.in_battle == true
for battler in $game_system.tactics_actors + $game_system.tactics_enemies + $game_system.tactics_neutral + $game_system.tactics_dead
if battler.x == new_x and battler.y == new_y and battler != self
if self.is_a?(Game_Actor)
if GTBS::TEAM_THROUGH
if battler.is_a?(Game_Actor)
return true
#return false
else
if battler.dead?
return true
#return false
else
return false
end
end
else
if battler.dead?
return true
#return false
else
return false
end
end
else
if GTBS::TEAM_THROUGH
if battler.is_a?(Game_Enemy)
return true
#return false
else
return false
end
else
if battler.dead?
return true
#return false
else
return false
end
end
end
end
end
end
return true
else
# Get new coordinates
new_x = x + (d == 6 ? 1 : d == 4 ? -1 : 0)
new_y = y + (d == 2 ? 1 : d == 8 ? -1 : 0)
unless $game_map.valid?(new_x, new_y)
return false
end
if @through
return true
end
#If character flying return true
if state?(GTBS::FLYING_ID) and $game_map.terrain_tag(new_x,new_y) >= 6
return true
end
#If character can "walk on water" and tile is water, return true
if state?(GTBS::WWATER_ID) and $game_map.terrain_tag(new_x,new_y) == 6
return true
end
unless $game_map.passable?(x, y, d, self)
if state?(GTBS::FLYING_ID) and $game_map.terrain_tag(x,y) >= 6
if $game_map.passable?(new_x, new_y, 0)
#juts makes it easier to do it with a else statement
else
return false
end
else
return false
end
end
unless $game_map.passable?(new_x, new_y, 10 - d)
if state?(GTBS::FLYING_ID) and $game_map.terrain_tag(new_x,new_y) >= 6
#juts makes it easier to do it with a else statement
else
return false
end
end
if $game_temp.in_battle == true
for battler in $game_system.tactics_actors + $game_system.tactics_enemies + $game_system.tactics_neutral + $game_system.tactics_dead
if battler.x == new_x and battler.y == new_y and battler != self
if self.is_a?(Game_Actor)
if GTBS::TEAM_THROUGH
if battler.is_a?(Game_Actor)
return true
else
if battler.dead?
return true
else
return false
end
end
else
if battler.dead?
return true
else
return false
end
end
else
if GTBS::TEAM_THROUGH
if battler.is_a?(Game_Enemy)
return true
else
return false
end
else
if battler.dead?
return true
else
return false
end
end
end
end
end
end
return true
end
end
def run_route(route)
self.set_pose("walk")
@step_count = 0
@move_route = route
end
def turn_to(who)
return if !who
sx = @x - who.x
sy = @y - who.y
return 0 if sx == 0 and sy == 0
if sx.abs > sy.abs
sx > 0 ? @direction = 4 : @direction = 6
return sx.abs
else
sy > 0 ? @direction = 8 : @direction = 2
return sy.abs
end
end
def moveto(x, y)
@x = x % $game_map.width
@y = y % $game_map.height
@real_x = @x * 128
@real_y = @y * 128
@prelock_direction = 0
end
def run_path
if @move_route.size > 0
if @move_route[@step_count] == nil
@move_route = []
end
action = @move_route[@step_count]
@step_count += 1
h = screen_th
case action
when 2
self.move_down
when 4
self.move_left
when 6
self.move_right
when 8
self.move_up
end
#if @remain_move[1] != 0
# @remain_move[1] -= 1
#else
# @move_route = []
#end
end
end
def effect?
return true if @animation_id > 0
return false
end
#Updates projectiles
def update_projectiles
for projectile in @projectiles
if projectile.disposed?
@projectiles.delete(projectile)
else
projectile.update
end
end
end
def update
update_projectiles
if $game_map.iso?
if screen_h < screen_th
@h = screen_th
elsif screen_h > screen_th
if (screen_h - screen_th) > 1.5
@h -= [ISO_LVL2_Config::FALLING_SPEED * 3, 1].min
else
@h -= ISO_LVL2_Config::FALLING_SPEED
end
end
end
if jumping?
update_jump
elsif moving?
update_move
else
update_stop
end
if @anime_count > 18 - @move_speed * 2
if not @step_anime and @stop_count > 0
@pattern = @original_pattern
else
if GTBS::ANIM_BATTLER and @battler_name.include?("ANIM")
@pattern = (@pattern + 1) % 6
else
@pattern = (@pattern + 1) % 4
end
end
@anime_count = 0
end
if @wait_count > 0
@wait_count -= 1
return
end
if @move_route.size > 0
run_path unless moving?
end
if @move_route_forcing
move_type_custom
return
end
end
def move_down(turn_enabled = true)
if turn_enabled
turn_down
end
if passable?(@x, @y, 2)
turn_down
@y += 1
else
check_event_trigger_touch(@x, @y+1) unless self.is_a?(Game_Enemy)
end
end
def move_left(turn_enabled = true)
if turn_enabled
turn_left
end
if passable?(@x, @y, 4)
turn_left
@x -= 1
else
check_event_trigger_touch(@x-1, @y) unless self.is_a?(Game_Enemy)
end
end
def move_right(turn_enabled = true)
if turn_enabled
turn_right
end
if passable?(@x, @y, 6)
turn_right
@x += 1
else
check_event_trigger_touch(@x+1, @y) unless self.is_a?(Game_Enemy)
end
end
def move_up(turn_enabled = true)
if turn_enabled
turn_up
end
if passable?(@x, @y, 8)
turn_up
@y -= 1
else
check_event_trigger_touch(@x, @y-1) unless self.is_a?(Game_Enemy)
end
end
def turn_down
unless @direction_fix
@direction = 2
@stop_count = 0
end
end
def turn_left
unless @direction_fix
@direction = 4
@stop_count = 0
end
end
def turn_right
unless @direction_fix
@direction = 6
@stop_count = 0
end
end
def turn_up
unless @direction_fix
@direction = 8
@stop_count = 0
end
end
def update_stop
if GTBS::ANIM_BATTLER and @battler_name.include?("ANIM")
@timer -= 1 if @timer > 0
if @step_anime
@anime_count += 2
elsif @pattern != @original_pattern
@anime_count += 2.5
end
else
if @step_anime
@anime_count += 1
elsif @pattern != @original_pattern
@anime_count += 1.5
end
end
#update animation speeds depending on state of hast/slow
if state?(GTBS::SLOW_ID) #slow
if @step_anime
@anime_count -= 0.5
else
@anime_count -= 1
end
elsif state?(GTBS::HASTE_ID) #haste
if @step_anime
@anime_count += 1
else
@anime_count += 1.5
end
end
if @timer == 0
set_pose("wait") if !dead?
end
unless @starting or lock?
@stop_count += 1
end
end
def update_jump
@jump_count -= 1
@real_x = (@real_x * @jump_count + @x * 128) / (@jump_count + 1)
@real_y = (@real_y * @jump_count + @y * 128) / (@jump_count + 1)
end
def update_move
distance = 2 ** @move_speed
if @y * 128 > @real_y
@real_y = [@real_y + distance, @y * 128].min
end
if @x * 128 < @real_x
@real_x = [@real_x - distance, @x * 128].max
end
if @x * 128 > @real_x
@real_x = [@real_x + distance, @x * 128].min
end
if @y * 128 < @real_y
@real_y = [@real_y - distance, @y * 128].max
end
if GTBS::ANIM_BATTLER
self.set_pose('walk') unless self.pose? == 3
end
if @walk_anime
@anime_count += 3.0
elsif @step_anime
@anime_count += 2.0
end
end
def lock
if @locked
return
end
@prelock_direction = @direction
turn_toward_player
@locked = true
end
def lock?
return @locked
end
def unlock
unless @locked
return
end
@locked = false
unless @direction_fix
if @prelock_direction != 0
@direction = @prelock_direction
end
end
end
def skill_can_use?(skill_id)
skill = $data_skills[skill_id]
if skill.sp_cost > self.sp
return false
end
if dead?
return false
end
occasion = $data_skills[skill_id].occasion
if $game_temp.in_battle
sum = GTBS::is_summon?(skill_id)
if sum > 0
name = $game_actors[sum].name.to_s
is = false
for bat in $game_system.tactics_actors + $game_system.tactics_enemies + $game_system.tactics_neutral
if bat.name.to_s == name
is = true
end
end
return false if is
end
if [5, 6].include?(skill.scope) and $game_system.tactics_dead.size == 0
return false
end
return (occasion == 0 or occasion == 1)
else
return (occasion == 0 or occasion == 2)
end
return true
end
def get_angle(attacker)
return Math.to_d(Math.atan((attacker.y - self.y)/(attacker.x - self.x))) unless (attacker.x - self.x) == 0
return 90
end
def from_back?(attacker)
back = false
case self.direction
when 2
if (attacker.y < self.y)
angle = get_angle(attacker)
if angle < 46 and angle > (-46)
back = true
end
end
when 4
if (attacker.x > self.x)
angle = get_angle(attacker)
if angle < 46 and angle > (-46)
back = true
end
end
when 6
if (attacker.x < self.x)
angle = get_angle(attacker)
if angle < 46 and angle > (-46)
back = true
end
end
when 8
if (attacker.y > self.y)
angle = get_angle(attacker)
if angle < 46 and angle > (-46)
back = true
end
end
end
return back
end
def from_front?(attacker)
front = false
case self.direction
when 2
if (attacker.y > self.y)
angle = get_angle(attacker)
if angle < 46 and angle > (-46)
front = true
end
end
when 4
if (attacker.x < self.x)
angle = get_angle(attacker)
if angle < 46 and angle > (-46)
front = true
end
end
when 6
if (attacker.x > self.x)
angle = get_angle(attacker)
if angle < 46 and angle > (-46)
front = true
end
end
when 8
if (attacker.y < self.y)
angle = get_angle(attacker)
if angle < 46 and angle > (-46)
front = true
end
end
end
return front
end
#Performs attack calculations
def attack_effect(attacker, affected = 0)
# 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 = atk * (20 + attacker.str) / 20
# Element correction
self.damage *= elements_correct(attacker.element_set)
self.damage /= 100
# If damage value is strictly positive
if self.damage > 0
# Critical correction
if rand(100) < 4 * attacker.dex / self.agi
self.damage *= 2
self.critical = true
end
# Guard correction
if self.guarding?
self.damage /= 2
end
if self.from_back?(attacker)
self.damage *= 1.3
else
if self.from_front?(attacker)
self.damage *= 0.8
else
self.damage *= 1.0
end
end
# Remove decimals
self.damage = self.damage.to_s.split(".")[0].to_i
end
# Dispersion
if self.damage.abs > 0
amp = [self.damage.abs * 15 / 100, 1].max
self.damage += rand(amp+1) + rand(amp+1) - amp
end
# Second hit detection
eva = 8 * self.agi / attacker.dex + self.eva
hit = self.damage < 0 ? 100 : 100 - eva
hit = self.cant_evade? ? 100 : hit
if self.from_back?(attacker)
hit += 10
elsif !self.from_front?(attacker)
hit += 5 #from sides
end
hit = hit > 100 ? 100 : hit
hit_result = (rand(100) < hit)
end
# If hit occurs
if hit_result == true
if affected > 0
curve = GTBS::CHAIN_LIGHTNING_CURVE
if !(affected >= curve.size)
self.damage *= (curve[affected-1]/100.to_f)
else
self.damage *= (curve.last/100.to_f)
end
self.damage = self.damage.to_i
end
# State Removed by Shock
remove_states_shock
# Substract damage from HP
self.hp -= self.damage
# State change
@state_changed = false
states_plus(attacker.plus_state_set)
states_minus(attacker.minus_state_set)
# When missing
else
# Set damage to "Miss"
self.damage = "Miss"
# Clear critical flag
self.critical = false
end
if self.dead?
self.animation_id = 108
end
if self.current_action.basic == 1
self.current_action.basic = 0
end
# End Method
return true
end
#--------------------------------------------------------------------------
# * Apply Skill Effects
# user : the one using skills (battler)
# skill : skill
#--------------------------------------------------------------------------
def skill_effect(user, skill, affected=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 = power * rate / 20
# Element correction
self.damage *= elements_correct(skill.element_set)
self.damage /= 100
# If damage value is strictly positive
if self.damage > 0
# Guard correction
if self.guarding?
self.damage /= 2
end
end
# Dispersion
if skill.variance > 0 and self.damage.abs > 0
amp = [self.damage.abs * skill.variance / 100, 1].max
self.damage += rand(amp+1) + rand(amp+1) - amp
end
# Second hit detection
eva = 8 * self.agi / user.dex + self.eva
hit = self.damage < 0 ? 100 : 100 - eva * skill.eva_f / 100
hit = self.cant_evade? ? 100 : hit
hit_result = (rand(100) < hit)
# Set effective flag if skill is uncertain
effective |= hit < 100
end
# If hit occurs
if hit_result == true
# If physical attack has power other than 0
if skill.power != 0 and skill.atk_f > 0
# State Removed by Shock
remove_states_shock
# Set to effective flag
effective = true
end
if affected > 0
curve = GTBS::CHAIN_LIGHTNING_CURVE
if !(affected >= curve.size)
self.damage *= (curve[affected-1]/100.to_f)
else
self.damage *= (curve.last/100.to_f)
end
self.damage = self.damage.to_i
end
###Drain Skills###
drain = GTBS::drain_skill?(skill.id)
if drain[0]
user.hp += (self.damage * (drain[1]/100.to_f)).to_i
user.damage = -(self.damage * (drain[1]/100.to_f)).to_i
user.damage_pop = true
end
# Substract damage from HP
last_hp = self.hp
self.hp -= self.damage
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 = ""
# If state is unchanged
unless @state_changed
# Set damage to "Miss"
self.damage = "Miss"
end
end
# If miss occurs
else
# Set damage to "Miss"
self.damage = "Miss"
end
# If not in battle
unless $game_temp.in_battle
# Set damage to nil
self.damage = nil
end
if self.dead? and self.damage.is_a?(Numeric) and user.is_a?(Game_Actor) and skill != nil
if skill.element_set.include?(GTBS::SECRET_HUNT_ID) and self.damage > 0
item = GTBS.secret_hunt_result?(self.id)
if item != []
case item[0]
when 0 #item
$game_party.gain_item(item[1],1)
when 1 #weapon
$game_party.gain_weapon(item[1],1)
when 2 #armor
$game_party.gain_armor(item[1],1)
end
end
end
end
if self.current_action.basic == 1
self.current_action.basic = 0
end
# End Method
return effective
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 nil
self.damage = nil
end
# End Method
return effective
end
#--------------------------------------------------------------------------
# * Application of Slip Damage Effects
#--------------------------------------------------------------------------
alias slp_dmg_efct slip_damage_effect
def slip_damage_effect
slip = []
for i in @states
if $data_states.slip_damage
slip.push(i)
end
end
for i in slip
if GTBS::slip_dmg?(i)[0] == true
self.damage = GTBS::slip_dmg?(i)[1]
self.hp -= self.damage
return true
else
# Set damage
self.damage = self.maxhp / 10
# Dispersion
if self.damage.abs > 0
amp = [self.damage.abs * 15 / 100, 1].max
self.damage += rand(amp+1) + rand(amp+1) - amp
end
# Subtract damage from HP
self.hp -= self.damage
# End Method
return true
end
end
end
end