Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

[RESOLVED] View Range Script Wierdness

I'm using NearFantastica's View Range script for enemy detection purposes and I've run into a strange little bug. I've pored over it for a long time but I can't figure it out. I was hoping someone might be able to help me with it.

In case anyone isn't familiar with the script, one of the usages of it is Enemies_View, which is a script call which detects if a player is within the VIEW range of an enemy. Essentially, it draws a semi-circle in the direction the enemy is looking and if the player is in that semi-circle, it flips a self-switch or a switch. Additionally, this function can determine whether or not the player is behind an impassable tile (which an enemy couldn't see through) and if so, does not detect the player. This is done by setting the "block" parameter to "true".

Here is the script call:
$view_range.enemies_view(ev_id, v_range, sw_id, s_sw_id, block)

So, when I use this script call, I notice something screwed up: the enemy event will detect the player almost all the time, but strangely enough, it will NOT detect the player if the player is in a straight line from the enemy. In other words, if the player is directly to the left, right, top, or bottom of the event, the player will not be detected even if the player is within the specified view range. However, if the player steps OUT of the straight line from the event's view, the event will suddenly detect the player. In both cases, there are no actual impassable tiles in the way of the enemy's view range, but this bug only occurs when the impassability parameter (block) is set to true. I need this set to true, however, for the whole thing to work.

I realize this is hard to explain with just words, so I took a few screenshots to illustrate the problem:

For the enemy event, I have the following script call:
$view_range.enemies_view(12, 5, nil, "A", true)

When I'm well within the range and in a straight line from the event, nothing happens...


But when I step OUT of that line, all of a sudden it works:


As I said before, this only happens when the passability check is turned to true. So, I looked at the method in the View Range script involving that check, and I have no idea what the problem might be. Here's the method:
def vr_in_range?(element, object, range, pass_block = false)
# Obtain Range
x = (element.x - object.x) * (element.x - object.x)
y = (element.y - object.y) * (element.y - object.y)
# Obtain values to loop and counter value
x_loops = x_count = (object.x - element.x).abs
y_loops = y_count = (object.y - element.y).abs
# Reset player's check location
check_player_x = -1
check_player_y = -1
r = x + y
if r <= (range * range)
# Set the return flag
rflag = true
# If tiles can block view
if pass_block
# Horizontal Checks
x_loops.times {
x_playerchk = ((object.x - element.x) >= 0 ? element.x + x_count : element.x - x_count)
x_passingchk = ((object.x - element.x) >= 0 ? (element.x + x_count)-1 : (element.x - x_count)+1)
unless $game_player.passable?(x_passingchk, element.y , element.direction)
# Change flag
rflag = false
# Set player check location
check_player_x = object.x if x_playerchk == object.x
end
# Decrease counter
x_count -= 1
}
# Vertical Checks
y_loops.times {
y_playerchk = ((object.y - element.y) >= 0 ? element.y + y_count : element.y - y_count)
y_passingchk = ((object.y - element.y) >= 0 ? (element.y + y_count)-1 : (element.y - y_count)+1)
unless $game_player.passable?(element.x, y_passingchk , element.direction)
# Change flag
rflag = false
# Set player check location
check_player_y = object.y if y_playerchk == object.y
end
# Decrease counter
y_count -= 1
}
end
# Re-enable flag based on player position
if check_player_x == object.x && check_player_y == object.y
#print "uyui"
r_flag = true
end
# Return system-determined flag
return rflag
else
# Return default flag
return false
end
end

And here is the entire script for reference:
#==============================================================================
# ** View Range Script v3 gamma
#------------------------------------------------------------------------------
# Original version by: Near Fantastica
# Original date: June 14, 2005
#
# Modifications/edit by: DerVVulfman
# Modification date: November 25, 2007
#
#==============================================================================
#
# INTRODUCTION:
# The original v3 View Range system allowed a more detailed detection between
# player and event ranges than version 2. Adding the ability to use events to
# detect the player as well as enemy events facing the player added to its
# usefullness.
#
# Unfortunately, when version 2 was released (at least where I found it), the
# instructions for the system's use were only partially correct and did not
# inform the users that the system no longer used the event's self-switches.
# The newer version now used the RMXP Database's regular switches instead.
#
# Though it was not my intention to tangle with the View Range system, luck
# (and a few friends) nudged me into experimenting with this system. As such
# I have not only combined the use of SelfSwitches 'AND' regular switches in
# to the system, I have also added a couple more features for use.
#
# The system now includes a routine to check the range between two different
# events which may be useful for 'collision detection' purposes. Also, I have
# also altered the Event_Sound routine so the user can set a lower volume or
# pitch setting for targettable events.
#
#==============================================================================
#
# THE FUNCTIONS:
#
# There are now four routines that you can use with this system (or 5 if you
# script a routine to use the vr_in_range? method). The four are listed below
# detailing usage and proper syntax for you.
#
#--------------------------------------------------------------------------
#
# Event View
# ==========
# This function checks to see if the player is within the range of an event
# and turns on the properly designated switch.
#
# Syntax:
# $view_range.event_view(ev_id, v_range, sw_id, s_sw_id, block)
#
# ev_id - (Event ID)
# This is the ID number of the event that the radius/range is
# based on. If the player comes within the range of 'this'
# event, the system is triggered.
#
# ev2_id - (Event2 ID)
# This is the ID number of the event
#
# v_range - (View Range)
# This is the range(in tiles) in which to perform the check.
#
# sw_id - (Switch ID) - Defaulted to 'nil'
# The RMXP switch number to turn ON. By default, this is set
# to 'nil'. You must enter a valid Switch number to use.
#
# s_sw_id - (Self Switch ID) - Defaulted to 'nil'
# The 'Self-Switch' for the event to turn ON. Proper values
# to set are "A", "B", "C", or "D". By default, this is set
# to 'nil'. You must enter a valid Self-Switch to use.
#
# block - (Blocked by Tiles) - Defaulted to 'false'
# This is a 'true/false' switch that determines if the view
# range system is unable to see around impassable tiles. By
# default, this is set to 'false'. If it is set to 'true',
# the view range system will not detect the player if it is
# behind an impassable tile or tiles.
#
#--------------------------------------------------------------------------
#
# Event to Event View
# ===================
# This function checks to see if a single event is within the range of
# another event and turns on the properly designated switch. This new
# routine may be useful for collision detection between events.
#
# Syntax:
# $view_range.event2event_view(ev_id, ev2_id, v_range, sw_id, s_sw_id, block)
#
# ev_id - (Event ID)
# This is the ID number of the event that the radius/range is
# based on. If the target event moves or appears within the
# range of 'this' event, the system is triggered.
#
# ev2_id - (Event2 ID)
# This is the ID number of the target event which to check.
# If this event finds itself within range of the other
# event's area of effect, the system is triggered.
#
# v_range - (View Range)
# This is the range(in tiles) in which to perform the check.
#
# sw_id - (Switch ID) - Defaulted to 'nil'
# The RMXP switch number to turn ON. By default, this is set
# to 'nil'. You must enter a valid Switch number to use.
#
# s_sw_id - (Self Switch ID) - Defaulted to 'nil'
# The 'Self-Switch' for the event to turn ON. Proper values
# to set are "A", "B", "C", or "D". By default, this is set
# to 'nil'. You must enter a valid Self-Switch to use.
#
# block - (Blocked by Tiles) - Defaulted to 'false'
# This is a 'true/false' switch that determines if the view
# range system is unable to see around impassable tiles. By
# default, this is set to 'false'. If it is set to 'true',
# the view range system will not detect the target event if
# it is behind an impassable tile or tiles.
#
#
#--------------------------------------------------------------------------
#
# Enemies View
# ============
# This function checks to see if the player is within range of an event
# that is facing him/her, and turns on the properly designated switch.
#
# Syntax:
# $view_range.enemies_view(ev_id, v_range, sw_id, s_sw_id, block)
#
# ev_id - (Event ID)
# This is the ID number of the event that the radius/range is
# based on. If the player is in front of 'this' event and
# within the set range, the system is triggered.
#
# v_range - (View Range)
# This is the range(in tiles) in which to perform the check.
#
# sw_id - (Switch ID) - Defaulted to 'nil'
# The RMXP switch number to turn ON. By default, this is set
# to 'nil'. You must enter a valid Switch number to use.
#
# s_sw_id - (Self Switch ID) - Defaulted to 'nil'
# The 'Self-Switch' for the event to turn ON. Proper values
# to set are "A", "B", "C", or "D". By default, this is set
# to 'nil'. You must enter a valid Self-Switch to use.
#
# block - (Blocked by Tiles) - Defaulted to 'false'
# This is a 'true/false' switch that determines if the view
# range system is unable to see around impassable tiles. By
# default, this is set to 'false'. If it is set to 'true',
# the view range system will not detect the player if it is
# behind an impassable tile or tiles.
#
#--------------------------------------------------------------------------
#
# Event Sound
# ===========
# This function checks to see if the player is within range of an event
# that is linked to a sound effect. The closer the player is to the event,
# the louder the effect is played.
#
# The maximum sound range of this routine is eight (8) tiles. It is not
# recommended to overlap these events as this can cause massive lag on the
# game/project as the system will attempt to cycle through the overlapped
# calls. Also note that this routine will override the map's default back-
# ground sound effect.
#
# Syntax:
# $view_range.event_sound(ev_id, bgs_name, bgs_vol = 100, bgs_pitch = 100)
#
# ev_id - (Event ID)
# This is the ID number of the event that the radius/range is
# based on. If the player is in front of 'this' event and
# within the set range, the system is triggered.
#
# bgs_name - (Background Effect's Name)
# This is the filename of the background effect. This effect
# is stored in the Audio\BGS folder.
#
# bgs_vol - (Background Effect's Volume)
# This is the volume setting of the background effect within
# a range of 1 to 100, with 100 being the loudest.
#
# bgs_pitch - (Background Effect's Pitch)
# This is the pitch setting of the background effect within a
# range of 50 to 150, with 150 being the highest setting.
#
#==============================================================================
#
# HOW IT DETERMINES THE RANGE:
#
# The Range system works by searching the area of a circle for the player's
# 'x' and 'y' position. The view range is set in each event and is the ra-
# dius of a circle.
#
# The equation used is: radius^2 = (Px-Ex)^2 + (Py-Ey)^2
# Where P = player, and E = event
#
# If the radius is less than or equal to the view range, then the player is
# inside the circular area.
#
#==============================================================================



#==============================================================================
# ** View Range
#------------------------------------------------------------------------------
# This class is Near Fantastica's which checks distances between events.
#==============================================================================

class View_Range
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
@playing_bgs = []
@bgs = BGS.new
@event_local_switch = ""
end
#--------------------------------------------------------------------------
# * In Range?
# element : element
# object : object
# range : range in tiles
# pass_block : if terrain tiles can block view
#--------------------------------------------------------------------------
def vr_in_range?(element, object, range, pass_block = false)
# Obtain Range
x = (element.x - object.x) * (element.x - object.x)
y = (element.y - object.y) * (element.y - object.y)
# Obtain values to loop and counter value
x_loops = x_count = (object.x - element.x).abs
y_loops = y_count = (object.y - element.y).abs
# Reset player's check location
check_player_x = -1
check_player_y = -1
r = x + y
if r <= (range * range)
# Set the return flag
rflag = true
# If tiles can block view
if pass_block
# Horizontal Checks
x_loops.times {
x_playerchk = ((object.x - element.x) >= 0 ? element.x + x_count : element.x - x_count)
x_passingchk = ((object.x - element.x) >= 0 ? (element.x + x_count)-1 : (element.x - x_count)+1)
unless $game_player.passable?(x_passingchk, element.y , element.direction)
# Change flag
rflag = false
# Set player check location
check_player_x = object.x if x_playerchk == object.x
end
# Decrease counter
x_count -= 1
}
# Vertical Checks
y_loops.times {
y_playerchk = ((object.y - element.y) >= 0 ? element.y + y_count : element.y - y_count)
y_passingchk = ((object.y - element.y) >= 0 ? (element.y + y_count)-1 : (element.y - y_count)+1)
unless $game_player.passable?(element.x, y_passingchk , element.direction)
# Change flag
rflag = false
# Set player check location
check_player_y = object.y if y_playerchk == object.y
end
# Decrease counter
y_count -= 1
}
end
# Re-enable flag based on player position
if check_player_x == object.x && check_player_y == object.y
#print "uyui"
r_flag = true
end
# Return system-determined flag
return rflag
else
# Return default flag
return false
end
end
#--------------------------------------------------------------------------
# * View Switch
# ev_id : event ID
# sw_id : switch ID
# s_sw_id : event's self switch ID
#--------------------------------------------------------------------------
def view_switch(ev_id, sw_id = nil, s_sw_id = nil)
$game_switches[sw_id] = true if sw_id != nil
if s_sw_id != nil
key=[$game_map.map_id, ev_id, s_sw_id]
$game_self_switches[key] = true
end
$game_map.need_refresh = true
end
#--------------------------------------------------------------------------
# * Event Sound
# ev_id : Event ID
# bgs_name : filename of background sound effect
# bgs_vol : background effect's volume
# bgs_pitch : background effect's pitch
#--------------------------------------------------------------------------
def event_sound(ev_id, bgs_name, bgs_vol = 100, bgs_pitch = 100)
event = $game_map.events[ev_id]
@bgs.name = bgs_name
@bgs.pitch = bgs_pitch
radius = ($game_player.x-event.x) * ($game_player.x-event.x) +
($game_player.y-event.y) * ($game_player.y-event.y)
if radius > 64
if @playing_bgs[event.id] != nil
@playing_bgs[event.id] = nil
$game_system.bgs_fade(1)
return
end
elsif radius <= 64 and radius > 49
if @playing_bgs[event.id] == nil
@bgs.volume = (bgs_vol * 30)/100
@playing_bgs[event.id] = @bgs
$game_system.bgs_play(@bgs)
return
end
@bgs.volume = (bgs_vol * 30)/100
if @bgs.volume != @playing_bgs[event.id].volume or
@bgs.name != @playing_bgs[event.id].name
@playing_bgs[event.id] = @bgs
$game_system.bgs_play(@bgs)
return
end
elsif radius <= 49 and radius > 36
@bgs.volume = (bgs_vol * 40)/100
@playing_bgs[event.id] = @bgs
$game_system.bgs_play(@bgs)
return
elsif radius <= 36 and radius > 25
@bgs.volume = (bgs_vol * 50)/100
@playing_bgs[event.id] = @bgs
$game_system.bgs_play(@bgs)
return
elsif radius <= 25 and radius > 16
@bgs.volume = (bgs_vol * 60)/100
@playing_bgs[event.id] = @bgs
$game_system.bgs_play(@bgs)
return
elsif radius <= 16 and radius > 9
@bgs.volume = (bgs_vol * 70)/100
@playing_bgs[event.id] = @bgs
$game_system.bgs_play(@bgs)
return
elsif radius <= 9 and radius > 4
@bgs.volume = (bgs_vol * 80)/100
@playing_bgs[event.id] = @bgs
$game_system.bgs_play(@bgs)
return
elsif radius <= 4 and radius > 1
@bgs.volume = (bgs_vol * 90)/100
@playing_bgs[event.id] = @bgs
$game_system.bgs_play(@bgs)
return
elsif radius = 1
@bgs.volume = (bgs_vol * 100)/100
@playing_bgs[event.id] = @bgs
$game_system.bgs_play(@bgs)
return
end
end
#--------------------------------------------------------------------------
# * Event View
# ev_id : event ID
# v_range : range in tiles
# sw_id : switch ID
# s_sw_id : event's self switch ID
# block : View block (true/false)
#--------------------------------------------------------------------------
def event_view(ev_id, v_range, sw_id = nil, s_sw_id = nil, block = false)
event = $game_map.events[ev_id]
if vr_in_range?(event, $game_player, v_range, block)
view_switch(ev_id, sw_id, s_sw_id)
end
end
#--------------------------------------------------------------------------
# * Event to Event View
# ev_id : event ID
# ev2_id : event ID of target
# v_range : range in tiles
# sw_id : switch ID
# s_sw_id : event's self switch ID
# block : View block (true/false)
#--------------------------------------------------------------------------
def event2event_view(ev_id, ev2_id, v_range, sw_id = nil, s_sw_id = nil, block = false)
event = $game_map.events[ev_id]
target = $game_map.events[ev2_id]
if vr_in_range?(event, target, v_range, block)
view_switch(ev_id, sw_id, s_sw_id)
end
end
#--------------------------------------------------------------------------
# * Enemies View
# ev_id : event ID
# v_range : range in tiles
# sw_id : switch ID
# s_sw_id : event's self switch ID
# block : View block (true/false)
#--------------------------------------------------------------------------
def enemies_view(ev_id, v_range, sw_id= nil, s_sw_id = nil, block = false)
event = $game_map.events[ev_id]
if event.direction == 2 && $game_player.y >= event.y
if vr_in_range?(event, $game_player, v_range, block)
view_switch(ev_id, sw_id, s_sw_id)
end
end
if event.direction == 4 && $game_player.x <= event.x
if vr_in_range?(event, $game_player, v_range, block)
view_switch(ev_id, sw_id, s_sw_id)
end
end
if event.direction == 6 && $game_player.x >= event.x
if vr_in_range?(event, $game_player, v_range, block)
view_switch(ev_id, sw_id, s_sw_id)
end
end
if event.direction == 8 && $game_player.y <= event.y
if vr_in_range?(event, $game_player, v_range, block)
view_switch(ev_id, sw_id, s_sw_id)
end
end
end
end



#==============================================================================
# ** Scene_Title
#------------------------------------------------------------------------------
# This class performs title screen processing.
#==============================================================================

class Scene_Title
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
alias vr_scene_title_update update
def update
$view_range = View_Range.new
vr_scene_title_update
end
end



#==============================================================================
# ** 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 :playing_bgs
end



#==============================================================================
# ** Background Sounds
#------------------------------------------------------------------------------
# Data class for Background SE files.
#==============================================================================
class BGS
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_accessor :name
attr_accessor :volume
attr_accessor :pitch
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
@name
@volume
@pitch
end
end

I hope that clarifies that clarifies the problem as much as possible. Anyone have any idea what's going on?
 
I found the error and updated it to 'Delta', aka version 4

Code:
#==============================================================================

#  ** View Range Script v3 Delta

#------------------------------------------------------------------------------

#  Original version by:     Near Fantastica

#  Original date:           June 14, 2005

#

#  Modifications/edit by:   DerVVulfman

#  Modification date:       October 22, 2009

#

#==============================================================================

#

#  INTRODUCTION:

#  The original v3 View Range system allowed a more detailed detection between

#  player and event ranges than version 2. Adding the ability to use events to

#  detect the player  as well as enemy events  facing the player  added to its

#  usefullness.

#

#  Unfortunately, when version 2 was released (at least where I found it), the

#  instructions for the system's use  were only partially correct  and did not

#  inform the users that the system no longer used  the event's self-switches.

#  The newer version now used the RMXP Database's regular switches instead.

#

#  Though it was not my intention  to tangle with  the View Range system, luck

#  (and a few friends) nudged me into experimenting with this system.  As such

#  I have not only combined the use  of SelfSwitches 'AND' regular switches in

#  to the system, I have also added a couple more features for use.

#

#  The system now includes a routine  to check the range between two different

#  events which may be useful for 'collision detection' purposes. Also, I have

#  also altered the Event_Sound routine  so the user can set a lower volume or

#  pitch setting for targettable events.

#

#==============================================================================

#

#  THE FUNCTIONS:

#  

#  There are now four routines that you can use with this system  (or 5 if you

#  script a routine to use the vr_in_range? method). The four are listed below

#  detailing usage and proper syntax for you.

#

#--------------------------------------------------------------------------

#

#     Event View

#     ==========

#     This function checks to see if the player is within the range of an event

#     and turns on the properly designated switch.

#

#     Syntax:

#     $view_range.event_view(ev_id, v_range, sw_id, s_sw_id, block)

#

#     ev_id     - (Event ID)      

#                  This is the ID number of the event that the radius/range is

#                  based on.   If the player comes within the range of  'this' 

#                  event, the system is triggered.

#

#     ev2_id    - (Event2 ID)

#                  This is the ID number of the event

#

#     v_range   - (View Range)    

#                  This is the range(in tiles) in which to perform the check.

#

#     sw_id     - (Switch ID) - Defaulted to 'nil'    

#                  The RMXP switch number to turn ON.  By default, this is set

#                  to 'nil'.  You must enter a valid Switch number to use.

#

#     s_sw_id   - (Self Switch ID) - Defaulted to 'nil'

#                  The 'Self-Switch' for the event to turn ON.   Proper values  

#                  to set are "A", "B", "C", or "D".   By default, this is set

#                  to 'nil'.  You must enter a valid Self-Switch to use.

#

#     block     - (Blocked by Tiles) - Defaulted to 'false'

#                  This is a 'true/false' switch  that determines  if the view

#                  range system is unable to see around impassable tiles.   By

#                  default,  this is set to 'false'.   If it is set to 'true', 

#                  the view range system will not detect  the player  if it is

#                  behind an impassable tile or tiles.

#

#--------------------------------------------------------------------------

#

#     Event to Event View

#     ===================

#     This function checks to see if a single event is within the range of 

#     another event and turns on the properly designated switch.  This new

#     routine may be useful for collision detection between events.

#

#     Syntax:

#     $view_range.event2event_view(ev_id, ev2_id, v_range, sw_id, s_sw_id, block)

#

#     ev_id     - (Event ID)      

#                  This is the ID number of the event that the radius/range is

#                  based on.   If the target event moves or appears within the

#                  range of 'this' event, the system is triggered.

#

#     ev2_id    - (Event2 ID)

#                  This is the  ID number  of the target event which to check.

#                  If  this  event finds  itself  within  range of  the  other

#                  event's area of effect, the system is triggered.

#

#     v_range   - (View Range)    

#                  This is the range(in tiles) in which to perform the check.

#

#     sw_id     - (Switch ID) - Defaulted to 'nil'    

#                  The RMXP switch number to turn ON.  By default, this is set

#                  to 'nil'.  You must enter a valid Switch number to use.

#

#     s_sw_id   - (Self Switch ID) - Defaulted to 'nil'

#                  The 'Self-Switch' for the event to turn ON.   Proper values  

#                  to set are "A", "B", "C", or "D".   By default, this is set

#                  to 'nil'.  You must enter a valid Self-Switch to use.

#

#     block     - (Blocked by Tiles) - Defaulted to 'false'

#                  This is a 'true/false' switch  that determines  if the view

#                  range system is unable to see around impassable tiles.   By

#                  default,  this is set to 'false'.   If it is set to 'true', 

#                  the view range system  will not detect  the target event if

#                  it is behind an impassable tile or tiles.

#

#

#--------------------------------------------------------------------------

#

#     Enemies View

#     ============

#     This function checks to see if the player is within range of an event

#     that is facing him/her, and turns on the properly designated switch.

#

#     Syntax:

#     $view_range.enemies_view(ev_id, v_range, sw_id, s_sw_id, block)

#

#     ev_id     - (Event ID)      

#                  This is the ID number of the event that the radius/range is

#                  based on.   If the player is in front of 'this' event and

#                  within the set range, the system is triggered.

#

#     v_range   - (View Range)    

#                  This is the range(in tiles) in which to perform the check.

#

#     sw_id     - (Switch ID) - Defaulted to 'nil'    

#                  The RMXP switch number to turn ON.  By default, this is set

#                  to 'nil'.  You must enter a valid Switch number to use.

#

#     s_sw_id   - (Self Switch ID) - Defaulted to 'nil'

#                  The 'Self-Switch' for the event to turn ON.   Proper values  

#                  to set are "A", "B", "C", or "D".   By default, this is set

#                  to 'nil'.  You must enter a valid Self-Switch to use.

#

#     block     - (Blocked by Tiles) - Defaulted to 'false'

#                  This is a 'true/false' switch  that determines  if the view

#                  range system is unable to see around impassable tiles.   By

#                  default,  this is set to 'false'.   If it is set to 'true', 

#                  the view range system will not detect  the player  if it is

#                  behind an impassable tile or tiles.

#

#--------------------------------------------------------------------------

#

#     Event Sound

#     ===========

#     This function checks  to see if the player  is within range  of an event

#     that is linked to a sound effect. The closer the player is to the event,

#     the louder the effect is played.

#

#     The maximum sound range  of this routine is eight (8) tiles.   It is not

#     recommended to overlap these events as this can cause massive lag on the

#     game/project as the system will attempt  to cycle through the overlapped

#     calls. Also note that this routine will override the map's default back-

#     ground sound effect.

#

#     Syntax:

#     $view_range.event_sound(ev_id, bgs_name, bgs_vol = 100, bgs_pitch = 100)

#

#     ev_id     - (Event ID)      

#                  This is the ID number of the event that the radius/range is

#                  based on.   If the player is in front of 'this' event and

#                  within the set range, the system is triggered.

#

#     bgs_name  - (Background Effect's Name)

#                  This is the filename of the background effect.  This effect

#                  is stored in the Audio\BGS folder.

#

#     bgs_vol   - (Background Effect's Volume)

#                  This is the volume setting of the background effect within 

#                  a range of 1 to 100, with 100 being the loudest.

#

#     bgs_pitch - (Background Effect's Pitch)

#                  This is the pitch setting of the background effect within a

#                  range of 50 to 150, with 150 being the highest setting.

#

#==============================================================================

#

#  HOW IT DETERMINES THE RANGE:

#

#  The Range system works  by searching the area  of a circle for the player's

#  'x' and 'y' position.   The view range  is set in each event and is the ra-

#  dius of a circle.

#

#  The equation used is: radius^2 = (Px-Ex)^2 + (Py-Ey)^2

#  Where P = player, and E = event

#

#  If the radius  is less than or equal to the view range,  then the player is

#  inside the circular area.

#

#==============================================================================

 

  

 

#==============================================================================

# ** View Range

#------------------------------------------------------------------------------

#  This class is Near Fantastica's which checks distances between events.

#==============================================================================

 

class View_Range

  #--------------------------------------------------------------------------

  # * Object Initialization

  #--------------------------------------------------------------------------

  def initialize

    @playing_bgs = []

    @bgs = BGS.new

    @event_local_switch = ""

  end

  #--------------------------------------------------------------------------

  # * In Range?

  #     element     : element

  #     object      : object

  #     range       : range in tiles

  #     pass_block  : if terrain tiles can block view

  #--------------------------------------------------------------------------

  def vr_in_range?(element, object, range, pass_block = false)

    # Obtain Range

    x = (element.x - object.x) * (element.x - object.x)

    y = (element.y - object.y) * (element.y - object.y)

    # Obtain values to loop and counter value

    x_loops = x_count = ((object.x - element.x).abs)

    y_loops = y_count = ((object.y - element.y).abs)

    # Reset player's check location

    check_player_x = -1

    check_player_y = -1

    r = x + y

    if r <= (range * range)

      # Set the return flag

      rflag = true

      # If tiles can block view

      if pass_block

        # Horizontal Checks

        x_loops.times { 

          x_playerchk  = ((object.x - element.x) >= 0 ?  element.x + x_count    :  element.x - x_count)

          x_passingchk = ((object.x - element.x) >= 0 ? (element.x + x_count)-1 : (element.x - x_count)+1)

          unless $game_map.passable?(x_passingchk, element.y , element.direction)

            # Change flag

            rflag = false

            # Set player check location

            check_player_x = object.x if x_playerchk == object.x

          end

          # Decrease counter

          x_count -= 1

        }       

        # Vertical Checks

        y_loops.times { 

          y_playerchk  = ((object.y - element.y) >= 0 ? element.y + y_count : element.y - y_count)

          y_passingchk = ((object.y - element.y) >= 0 ? (element.y + y_count)-1 : (element.y - y_count)+1)

          unless $game_map.passable?(element.x, y_passingchk , element.direction)

            # Change flag

            rflag = false

            # Set player check location

            check_player_y = object.y if y_playerchk == object.y

          end

          # Decrease counter

          y_count -= 1

        }                  

      end

      # Re-enable flag based on player position

      if check_player_x == object.x && check_player_y == object.y

        r_flag = true

      end

      # Return system-determined flag      

      return rflag

    else

      # Return default flag

      return false

    end

  end

  #--------------------------------------------------------------------------

  # * View Switch

  #     ev_id       : event ID

  #     sw_id       : switch ID

  #     s_sw_id     : event's self switch ID

  #--------------------------------------------------------------------------  

  def view_switch(ev_id, sw_id = nil, s_sw_id = nil)

    $game_switches[sw_id] = true if sw_id != nil

    if s_sw_id != nil

      key=[$game_map.map_id, ev_id, s_sw_id]

      $game_self_switches[key] = true          

    end

    $game_map.need_refresh = true     

  end

  #--------------------------------------------------------------------------

  # * Event Sound

  #     ev_id       : Event ID

  #     bgs_name    : filename of background sound effect

  #     bgs_vol     : background effect's volume

  #     bgs_pitch   : background effect's pitch

  #--------------------------------------------------------------------------

  def event_sound(ev_id, bgs_name, bgs_vol = 100, bgs_pitch = 100)

    event = $game_map.events[ev_id]

    @bgs.name   = bgs_name

    @bgs.pitch  = bgs_pitch

    radius = ($game_player.x-event.x) * ($game_player.x-event.x) + 

             ($game_player.y-event.y) * ($game_player.y-event.y)

    if radius > 64

      if @playing_bgs[event.id] !=  nil

         @playing_bgs[event.id] =   nil

         $game_system.bgs_fade(1)

        return

      end

    elsif radius <= 64 and radius > 49

      if @playing_bgs[event.id] == nil

        @bgs.volume = (bgs_vol * 30)/100

        @playing_bgs[event.id] = @bgs

        $game_system.bgs_play(@bgs)

        return

      end

      @bgs.volume = (bgs_vol * 30)/100

      if @bgs.volume != @playing_bgs[event.id].volume or 

          @bgs.name != @playing_bgs[event.id].name

        @playing_bgs[event.id] = @bgs

        $game_system.bgs_play(@bgs)

        return

      end

    elsif radius <= 49 and radius > 36

      @bgs.volume = (bgs_vol * 40)/100

      @playing_bgs[event.id] = @bgs

      $game_system.bgs_play(@bgs)

      return

    elsif radius <= 36 and radius > 25

      @bgs.volume = (bgs_vol * 50)/100

      @playing_bgs[event.id] = @bgs

      $game_system.bgs_play(@bgs)

      return

    elsif radius <= 25 and radius > 16

      @bgs.volume = (bgs_vol * 60)/100

      @playing_bgs[event.id] = @bgs

      $game_system.bgs_play(@bgs)

      return

    elsif radius <= 16 and radius > 9

      @bgs.volume = (bgs_vol * 70)/100

      @playing_bgs[event.id] = @bgs

      $game_system.bgs_play(@bgs)

      return

    elsif radius <= 9 and radius > 4

      @bgs.volume = (bgs_vol * 80)/100

      @playing_bgs[event.id] = @bgs

      $game_system.bgs_play(@bgs)

      return

    elsif radius <= 4 and radius > 1

      @bgs.volume = (bgs_vol * 90)/100

      @playing_bgs[event.id] = @bgs

      $game_system.bgs_play(@bgs)

      return

    elsif radius = 1

      @bgs.volume = (bgs_vol * 100)/100

      @playing_bgs[event.id] = @bgs

      $game_system.bgs_play(@bgs)

      return

    end

  end

  #--------------------------------------------------------------------------

  # * Event View

  #     ev_id       : event ID

  #     v_range     : range in tiles

  #     sw_id       : switch ID

  #     s_sw_id     : event's self switch ID

  #     block       : View block (true/false)

  #--------------------------------------------------------------------------

  def event_view(ev_id, v_range, sw_id = nil, s_sw_id = nil, block = false)

    event = $game_map.events[ev_id]

    if vr_in_range?(event, $game_player, v_range, block)

      view_switch(ev_id, sw_id, s_sw_id)

    end

  end

  #--------------------------------------------------------------------------

  # * Event to Event View

  #     ev_id       : event ID

  #     ev2_id      : event ID of target

  #     v_range     : range in tiles

  #     sw_id       : switch ID

  #     s_sw_id     : event's self switch ID

  #     block       : View block (true/false)  

  #--------------------------------------------------------------------------

  def event2event_view(ev_id, ev2_id, v_range, sw_id = nil, s_sw_id = nil, block = false)

    event   = $game_map.events[ev_id]

    target  = $game_map.events[ev2_id]

    if vr_in_range?(event, target, v_range, block)

      view_switch(ev_id, sw_id, s_sw_id)

    end

  end

  #--------------------------------------------------------------------------

  # * Enemies View

  #     ev_id       : event ID

  #     v_range     : range in tiles

  #     sw_id       : switch ID

  #     s_sw_id     : event's self switch ID

  #     block       : View block (true/false)  

  #--------------------------------------------------------------------------

  def enemies_view(ev_id, v_range, sw_id= nil, s_sw_id = nil, block = false)

    event = $game_map.events[ev_id]

    if event.direction == 2 &&  $game_player.y >= event.y

      if vr_in_range?(event, $game_player, v_range, block)

        view_switch(ev_id, sw_id, s_sw_id)

      end

    end

    if event.direction == 4 &&  $game_player.x <= event.x

      if vr_in_range?(event, $game_player, v_range, block)

        view_switch(ev_id, sw_id, s_sw_id)

      end

    end

    if event.direction == 6 &&  $game_player.x >= event.x

      if vr_in_range?(event, $game_player, v_range, block)

        view_switch(ev_id, sw_id, s_sw_id)

      end

    end

    if event.direction == 8 &&  $game_player.y <= event.y

      if vr_in_range?(event, $game_player, v_range, block)

        view_switch(ev_id, sw_id, s_sw_id)

      end

    end

  end

end

 

 

 

#==============================================================================

# ** Scene_Title

#------------------------------------------------------------------------------

#  This class performs title screen processing.

#==============================================================================

 

class Scene_Title

  #--------------------------------------------------------------------------

  # * Frame Update

  #--------------------------------------------------------------------------

  alias vr_scene_title_update update

  def update

    $view_range = View_Range.new

    vr_scene_title_update

  end

end

 

 

 

#==============================================================================

# ** 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 :playing_bgs

end

  

 

 

#==============================================================================

# ** Background Sounds

#------------------------------------------------------------------------------

#  Data class for Background SE files.

#==============================================================================

class BGS

  #--------------------------------------------------------------------------

  # * Public Instance Variables

  #--------------------------------------------------------------------------

  attr_accessor :name

  attr_accessor :volume

  attr_accessor :pitch

  #--------------------------------------------------------------------------

  # * Object Initialization

  #--------------------------------------------------------------------------

  def initialize

    @name

    @volume

    @pitch

  end

end
Funny thing. All I did was change the routine that checked passables from the 'Game_Player' class's passable method over to the one for 'Game_Map' and that was it.
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top