445 lines
18 KiB
Ruby
445 lines
18 KiB
Ruby
|
|
# -*- coding: utf-8 -*-
|
||
|
|
#==============================================================================
|
||
|
|
# ** Game_CharacterBase
|
||
|
|
#------------------------------------------------------------------------------
|
||
|
|
# This base class handles characters. It retains basic information, such as
|
||
|
|
# coordinates and graphics, shared by all characters.
|
||
|
|
#==============================================================================
|
||
|
|
|
||
|
|
class Game_CharacterBase
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Public Instance Variables
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
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)
|
||
|
|
attr_reader :real_y # map Y coordinate (real)
|
||
|
|
attr_reader :tile_id # tile ID (invalid if 0)
|
||
|
|
attr_reader :character_name # character graphic filename
|
||
|
|
attr_reader :character_index # character graphic index
|
||
|
|
attr_reader :move_speed # movement speed
|
||
|
|
attr_reader :move_frequency # movement frequency
|
||
|
|
attr_reader :walk_anime # walking animation
|
||
|
|
attr_reader :step_anime # stepping animation
|
||
|
|
attr_reader :direction_fix # direction fix
|
||
|
|
attr_reader :opacity # opacity level
|
||
|
|
attr_reader :blend_type # blending method
|
||
|
|
attr_reader :direction # direction
|
||
|
|
attr_reader :pattern # pattern
|
||
|
|
attr_reader :priority_type # priority type
|
||
|
|
attr_reader :through # pass-through
|
||
|
|
attr_reader :bush_depth # bush depth
|
||
|
|
attr_accessor :animation_id # animation ID
|
||
|
|
attr_accessor :balloon_id # balloon icon ID
|
||
|
|
attr_accessor :transparent # transparency flag
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Object Initialization
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def initialize
|
||
|
|
init_public_members
|
||
|
|
init_private_members
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Initialize Public Member Variables
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def init_public_members
|
||
|
|
@id = 0
|
||
|
|
@x = 0
|
||
|
|
@y = 0
|
||
|
|
@real_x = 0
|
||
|
|
@real_y = 0
|
||
|
|
@tile_id = 0
|
||
|
|
@character_name = ""
|
||
|
|
@character_index = 0
|
||
|
|
@move_speed = 4
|
||
|
|
@move_frequency = 6
|
||
|
|
@walk_anime = true
|
||
|
|
@step_anime = false
|
||
|
|
@direction_fix = false
|
||
|
|
@opacity = 255
|
||
|
|
@blend_type = 0
|
||
|
|
@direction = 2
|
||
|
|
@pattern = 1
|
||
|
|
@priority_type = 1
|
||
|
|
@through = false
|
||
|
|
@bush_depth = 0
|
||
|
|
@animation_id = 0
|
||
|
|
@balloon_id = 0
|
||
|
|
@transparent = false
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Initialize Private Member Variables
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def init_private_members
|
||
|
|
@original_direction = 2 # Original direction
|
||
|
|
@original_pattern = 1 # Original pattern
|
||
|
|
@anime_count = 0 # Animation count
|
||
|
|
@stop_count = 0 # Stop count
|
||
|
|
@jump_count = 0 # Jump count
|
||
|
|
@jump_peak = 0 # Jump peak count
|
||
|
|
@locked = false # Locked flag
|
||
|
|
@prelock_direction = 0 # Direction before lock
|
||
|
|
@move_succeed = true # Move success flag
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Determine Coordinate Match
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def pos?(x, y)
|
||
|
|
@x == x && @y == y
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Determine if Coordinates Match and Pass-Through Is Off (nt = No Through)
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def pos_nt?(x, y)
|
||
|
|
pos?(x, y) && !@through
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Determine if [Same as Characters] Priority
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def normal_priority?
|
||
|
|
@priority_type == 1
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Determine if Moving
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def moving?
|
||
|
|
@real_x != @x || @real_y != @y
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Determine if Jumping
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def jumping?
|
||
|
|
@jump_count > 0
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Calculate Jump Height
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def jump_height
|
||
|
|
(@jump_peak * @jump_peak - (@jump_count - @jump_peak).abs ** 2) / 2
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Determine if Stopping
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def stopping?
|
||
|
|
!moving? && !jumping?
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Get Move Speed (Account for Dash)
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def real_move_speed
|
||
|
|
@move_speed + (dash? ? 1 : 0)
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Calculate Move Distance per Frame
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def distance_per_frame
|
||
|
|
2 ** real_move_speed / 256.0
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Determine if Dashing
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def dash?
|
||
|
|
return false
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Determine if Debug Pass-Through State
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def debug_through?
|
||
|
|
return false
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Straighten Position
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def straighten
|
||
|
|
@pattern = 1 if @walk_anime || @step_anime
|
||
|
|
@anime_count = 0
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Get Opposite Direction
|
||
|
|
# d : Direction (2,4,6,8)
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def reverse_dir(d)
|
||
|
|
return 10 - d
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Determine if Passable
|
||
|
|
# d : Direction (2,4,6,8)
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def passable?(x, y, d)
|
||
|
|
x2 = $game_map.round_x_with_direction(x, d)
|
||
|
|
y2 = $game_map.round_y_with_direction(y, d)
|
||
|
|
return false unless $game_map.valid?(x2, y2)
|
||
|
|
return true if @through || debug_through?
|
||
|
|
return false unless map_passable?(x, y, d)
|
||
|
|
return false unless map_passable?(x2, y2, reverse_dir(d))
|
||
|
|
return false if collide_with_characters?(x2, y2)
|
||
|
|
return true
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Determine Diagonal Passability
|
||
|
|
# horz : Horizontal (4 or 6)
|
||
|
|
# vert : Vertical (2 or 8)
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def diagonal_passable?(x, y, horz, vert)
|
||
|
|
x2 = $game_map.round_x_with_direction(x, horz)
|
||
|
|
y2 = $game_map.round_y_with_direction(y, vert)
|
||
|
|
(passable?(x, y, vert) && passable?(x, y2, horz)) ||
|
||
|
|
(passable?(x, y, horz) && passable?(x2, y, vert))
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Determine if Map is Passable
|
||
|
|
# d : Direction (2,4,6,8)
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def map_passable?(x, y, d)
|
||
|
|
$game_map.passable?(x, y, d)
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Detect Collision with Character
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def collide_with_characters?(x, y)
|
||
|
|
collide_with_events?(x, y) || collide_with_vehicles?(x, y)
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Detect Collision with Event
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def collide_with_events?(x, y)
|
||
|
|
$game_map.events_xy_nt(x, y).any? do |event|
|
||
|
|
event.normal_priority? || self.is_a?(Game_Event)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Detect Collision with Vehicle
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def collide_with_vehicles?(x, y)
|
||
|
|
$game_map.boat.pos_nt?(x, y) || $game_map.ship.pos_nt?(x, y)
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Move to Designated Position
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def moveto(x, y)
|
||
|
|
@x = x % $game_map.width
|
||
|
|
@y = y % $game_map.height
|
||
|
|
@real_x = @x
|
||
|
|
@real_y = @y
|
||
|
|
@prelock_direction = 0
|
||
|
|
straighten
|
||
|
|
update_bush_depth
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Change Direction to Designated Direction
|
||
|
|
# d : Direction (2,4,6,8)
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def set_direction(d)
|
||
|
|
@direction = d if !@direction_fix && d != 0
|
||
|
|
@stop_count = 0
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Determine Tile
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def tile?
|
||
|
|
@tile_id > 0 && @priority_type == 0
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Determine Object Character
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def object_character?
|
||
|
|
@tile_id > 0 || @character_name[0, 1] == '!'
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Get Number of Pixels to Shift Up from Tile Position
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def shift_y
|
||
|
|
object_character? ? 0 : 4
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Get Screen X-Coordinates
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def screen_x
|
||
|
|
$game_map.adjust_x(@real_x) * 32 + 16
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Get Screen Y-Coordinates
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def screen_y
|
||
|
|
$game_map.adjust_y(@real_y) * 32 + 32 - shift_y - jump_height
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Get Screen Z-Coordinates
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def screen_z
|
||
|
|
@priority_type * 100
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Frame Update
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def update
|
||
|
|
update_animation
|
||
|
|
return update_jump if jumping?
|
||
|
|
return update_move if moving?
|
||
|
|
return update_stop
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Update While Jumping
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def update_jump
|
||
|
|
@jump_count -= 1
|
||
|
|
@real_x = (@real_x * @jump_count + @x) / (@jump_count + 1.0)
|
||
|
|
@real_y = (@real_y * @jump_count + @y) / (@jump_count + 1.0)
|
||
|
|
update_bush_depth
|
||
|
|
if @jump_count == 0
|
||
|
|
@real_x = @x = $game_map.round_x(@x)
|
||
|
|
@real_y = @y = $game_map.round_y(@y)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Update While Moving
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def update_move
|
||
|
|
@real_x = [@real_x - distance_per_frame, @x].max if @x < @real_x
|
||
|
|
@real_x = [@real_x + distance_per_frame, @x].min if @x > @real_x
|
||
|
|
@real_y = [@real_y - distance_per_frame, @y].max if @y < @real_y
|
||
|
|
@real_y = [@real_y + distance_per_frame, @y].min if @y > @real_y
|
||
|
|
update_bush_depth unless moving?
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Update While Stopped
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def update_stop
|
||
|
|
@stop_count += 1 unless @locked
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Update Walking/Stepping Animation
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def update_animation
|
||
|
|
update_anime_count
|
||
|
|
if @anime_count > 18 - real_move_speed * 2
|
||
|
|
update_anime_pattern
|
||
|
|
@anime_count = 0
|
||
|
|
end
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Update Animation Count
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def update_anime_count
|
||
|
|
if moving? && @walk_anime
|
||
|
|
@anime_count += 1.5
|
||
|
|
elsif @step_anime || @pattern != @original_pattern
|
||
|
|
@anime_count += 1
|
||
|
|
end
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Update Animation Pattern
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def update_anime_pattern
|
||
|
|
if !@step_anime && @stop_count > 0
|
||
|
|
@pattern = @original_pattern
|
||
|
|
else
|
||
|
|
@pattern = (@pattern + 1) % 4
|
||
|
|
end
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Determine if Ladder
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def ladder?
|
||
|
|
$game_map.ladder?(@x, @y)
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Update Bush Depth
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def update_bush_depth
|
||
|
|
if normal_priority? && !object_character? && bush? && !jumping?
|
||
|
|
@bush_depth = 8 unless moving?
|
||
|
|
else
|
||
|
|
@bush_depth = 0
|
||
|
|
end
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Determine if Bush
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def bush?
|
||
|
|
$game_map.bush?(@x, @y)
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Get Terrain Tag
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def terrain_tag
|
||
|
|
$game_map.terrain_tag(@x, @y)
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Get Region ID
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def region_id
|
||
|
|
$game_map.region_id(@x, @y)
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Increase Steps
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def increase_steps
|
||
|
|
set_direction(8) if ladder?
|
||
|
|
@stop_count = 0
|
||
|
|
update_bush_depth
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Change Graphics
|
||
|
|
# character_name : new character graphic filename
|
||
|
|
# character_index : new character graphic index
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def set_graphic(character_name, character_index)
|
||
|
|
@tile_id = 0
|
||
|
|
@character_name = character_name
|
||
|
|
@character_index = character_index
|
||
|
|
@original_pattern = 1
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Determine Triggering of Frontal Touch Event
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def check_event_trigger_touch_front
|
||
|
|
x2 = $game_map.round_x_with_direction(@x, @direction)
|
||
|
|
y2 = $game_map.round_y_with_direction(@y, @direction)
|
||
|
|
check_event_trigger_touch(x2, y2)
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Determine if Touch Event is Triggered
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def check_event_trigger_touch(x, y)
|
||
|
|
return false
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Move Straight
|
||
|
|
# d: Direction (2,4,6,8)
|
||
|
|
# turn_ok : Allows change of direction on the spot
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def move_straight(d, turn_ok = true)
|
||
|
|
@move_succeed = passable?(@x, @y, d)
|
||
|
|
if @move_succeed
|
||
|
|
set_direction(d)
|
||
|
|
@x = $game_map.round_x_with_direction(@x, d)
|
||
|
|
@y = $game_map.round_y_with_direction(@y, d)
|
||
|
|
@real_x = $game_map.x_with_direction(@x, reverse_dir(d))
|
||
|
|
@real_y = $game_map.y_with_direction(@y, reverse_dir(d))
|
||
|
|
increase_steps
|
||
|
|
elsif turn_ok
|
||
|
|
set_direction(d)
|
||
|
|
check_event_trigger_touch_front
|
||
|
|
end
|
||
|
|
end
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
# * Move Diagonally
|
||
|
|
# horz: Horizontal (4 or 6)
|
||
|
|
# vert: Vertical (2 or 8)
|
||
|
|
#--------------------------------------------------------------------------
|
||
|
|
def move_diagonal(horz, vert)
|
||
|
|
@move_succeed = diagonal_passable?(x, y, horz, vert)
|
||
|
|
if @move_succeed
|
||
|
|
@x = $game_map.round_x_with_direction(@x, horz)
|
||
|
|
@y = $game_map.round_y_with_direction(@y, vert)
|
||
|
|
@real_x = $game_map.x_with_direction(@x, reverse_dir(horz))
|
||
|
|
@real_y = $game_map.y_with_direction(@y, reverse_dir(vert))
|
||
|
|
increase_steps
|
||
|
|
end
|
||
|
|
set_direction(horz) if @direction == reverse_dir(horz)
|
||
|
|
set_direction(vert) if @direction == reverse_dir(vert)
|
||
|
|
end
|
||
|
|
end
|