I have put allot of work into the script and have kinda hit a brick wall. Because of the way in which I've scripted it(using the parallel process) it updates the field of view and the highlighted squares constantly instead of when it needs to (player or events move or turn). This is causing allot of lag when i turn the highlighter on with 3 or more events. Any help fixing this problem would be much appreciated, it doesn't matter if it is still laggy but having it update properly will help me implement more features than i can at the moment. You don't have to rewrite my script, just telling me how i could go about it will probably be enough help. Thank you in advance.

I even commented everything.
CODE
#===============================================================================
# Tactical Espionage Engine
# Author: Maximusmaxy
# Version: 0.5.1
# Thanks to:
# Night Runner - Creating the coordinate highlighter and general tips.
# Yoshi Guy - Ideas/proof reading/emotional support
#===============================================================================
# Version 0.1: 24/8/2011
# Version 0.5: 5/9/2011
# Version 0.5.1: 5/9/2011 fixed WRS and how it updates
#===============================================================================
#
#Introduction:
#This is a compilation of small scripts ive written, compiled together to make
#a tactical espionage engine, much like a metal gear solid game (it's where i
#got the idea from.) It gives enemies true fields of view as apposed to blocky
#or rectangular/unrealistic views. It gives the player the abillity walk, run
#and sneak with easy to set up keys and speeds. It also splits the menu/cancel
#button like in most other RPG games.
#
#Instructions:
#
#Field of View:
#To use this script place a script call eg. FoV.new(7,1,5) in a parallel process
#to have the event constantly look for you. If you enter the events field of
#view it will activate its self switch 'A' which could than trigger a chase
#event system or an autorun event, however you want that event to react.
#
#The script call placed in a parralel process is:
#
#FoV.new(ID,DISTANCE,TYPE,SELF_SWITCH)
#
#ID is the ID of the event.
#
#DISTANCE is how many tiles they look in that direction.
#ONLY USE ODD DISTANCES for diamond and circle as it has been poorly scripted.
#
#TYPE is the field of view type.
#
#Type 0: Diamond Type 1: Pyramid Type 2: Linear Type 3,4: Circle
#
# N
# 3 3N 3
# 234 23N 234
# E1234N E123N E1234N 12E4N
# 234 23N 234
# 3 3N 3
# N
#
#where Distance = 5 where Distance = 4 where distance = 5 where Distance = 5
#
#TYPE 4 is a noise check which should be called when the player touches the
#event. It makes a sound depending on how fast you are moving and nearby
#events may hear it, switching there self switch and reacting accordingly.
#Running doulbes the circle size, walking has regular circle size and sneaking
#has no circle size.
#
#SELF_SWICH is the switch that is changed when you enter the field of view
#
#You can omit putting in the distance/type/switch and use the defaults
#eg. FoV.new(16,4,1), FoV.new(7,2) or FoV.new(4)
#
#Walk/Run/Sneak:
#Running and sneaking can be enabled and disabled during the game using script
#calls. It is recommended to disable them manually during cutscenes.
#The script calls are as follows:
#WRS.run_enable (enables running)
#WRS.sneak_enable (enables sneaking
#WRS.both_enable (enables both running and sneaking)
#WRS.run_disable (disables running)
#WRS.sneak_disable (disables sneaking)
#WRS.both_disable (disables both running and sneaking)
#
#You can reference the speed of the player for scripting purposes using the
#variable $game_player.speed where 1 = sneaking, 2 = walking, 3 = running.
#They keys for running and sneaking can be configured bellow.
#
#Menu Split:
#This feature simply splits the menu and cancel button into 2 seperate buttons.
#Its not an important feature but like most RPG's the cancel button is usually
#also the run button and i have tried to emulate this. It can be enabled or
#disabled in the configuration and the key can be changed.
#
#Compatabillity:
#This script is very likely to have compatabillity issues with other running
#and sneaking scripts,possibly 8 directional/pixel based movement scripts and
#other scripts which change or use certain controls. If the menu split conflicts
#with other scripts just disable it in the configuration.
#Other than that it should be compatable with most other scripts.
#
#===============================================================================
#===============================================================================
#Configuration
#===============================================================================
module Espionage
#set the defaults for the field of view here
DISTANCE = 5
TYPE = 0
SELF_SWITCH = 'A'
#set walk/run/sneak speed here
WALK_S = 4
RUN_S = 4.8
SNEAK_S = 3
#set the input keys for run and sneak here
RUN_K = Input::B
SNEAK_K = Input::A
#set if running or sneaking is allowed initially
$run_allow = true
$sneak_allow = true
#set if you want to split the menu/cancel keys and the new menu input
MENU_SPLIT = true
MENU_K = Input::X
#The sound that plays for Type 4 can be chosen here. It references a sound
#file placed in the SE folder.
SOUND = '042-Knock03'
#The coordinate highlighter is currently really laggy and should only be used
#for debug purposes untill i fix the problem.
HIGHLIGHT_K = Input::L
end
#===============================================================================
#End Configuration
#===============================================================================
class FoV
def initialize(id,dist = Espionage::DISTANCE, type = Espionage::TYPE,
switch = Espionage::SELF_SWITCH)
#load event data into local variables
@x = $game_map.events[id].x
@y = $game_map.events[id].y
@d = $game_map.events[id].direction
@d9 = $game_map.events[id].direction_9
@id = id
@switch = switch
@key = [$game_map.map_id,id,switch]
case type
#Diamond(Top left origin x, y, distance) ONLY USE ODD DISTANCES!
when 0
case @d
when 2 #down
diamond(@x - (dist-1)/2, @y + 1, dist)
when 4 #left
diamond(@x - dist,@y - (dist-1)/2, dist)
when 6 #right
diamond(@x + 1,@y - (dist-1)/2, dist)
when 8 #up
diamond(@x - (dist-1)/2,@y - dist, dist)
end
case @d9
#Triangle(x, y, left right?, LR inc, up down?, UD inc, distance)
when 1 #bottom left
triangle(@x, @y+dist, -1, 0, -1, -1, dist+1)
when 3 #bottom right
triangle(@x+dist, @y, -1, -1, 1, 0, dist+1)
when 7 #top left
triangle(@x-dist, @y, 1, 1, -1, 0, dist+1)
when 9 #top right
triangle(@x, @y-dist, 1, 0, 1, 1, dist+1)
#Circle(distance) ONLY USE ODD DISTANCES!
when 5
circle(dist,type)
end
#Pyramid(x, y, left right?, LR inc, up down?, UD inc, distance)
when 1
case @d
when 2 #down
pyramid(@x, @y + 1, -1, 1, 1, 0, dist)
when 4 #left
pyramid(@x - 1, @y, -1, 0, -1, 1, dist)
when 6 #right
pyramid(@x + 1, @y, 1, 0, 1, -1, dist)
when 8 #up
pyramid(@x, @y - 1, 1, -1, -1, 0, dist)
end
#Linear(x, y, x increment, y increment, distance)
when 2
case @d
when 2 #down
linear(@x, @y+1, 0, 1, dist)
when 4 #left
linear(@x-1, @y, -1, 0, dist)
when 6 #right
linear(@x+1, @y, 1, 0, dist)
when 8 #up
linear(@x, @y-1, 0, -1, dist)
end
#Circle(distance,type) ONLY USE ODD DISTANCES!
when 3
circle(dist, type)
#Noise(distance,type)
when 4
circle(dist, type) if $game_player.speed > 1 #if not sneaking
end
end
#draws the diamond shape and checks
def diamond(x,y,n)
for i in 0...n
for j in 0...(n - (2 * ((i-n/2).abs)))
a = x + i
b = y + (n/2-i).abs + j
check(a,b)
end
end
end
#draws the pyramid shape and checks
def pyramid(x,y,lr,lri,ud,udi,n)
for i in 0...n
for j in 0..(2*(i+1)-2)
a = x + (i*lr) + (j*lri)
b = y + (i*ud) + (j*udi)
check(a,b)
end
end
end
#draws a straight line and checks
def linear(x,y,ix,iy,n)
for i in 0...n
a = x + (i*ix)
b = y + (i*iy)
check(a,b)
end
end
#draws a right angled triangle and checks
def triangle(x, y, lr, lri, ud, udi, n)
for i in 0...n
for j in 0...(n-i)
a = x + (i*lr) + (j*lri)
b = y + (i*ud) + (j*udi)
check(a,b)
end
end
#reset the diagonal direction after the check
$game_map.events[@id].direction_9 = 0
end
#draws a circle(actually its a diamond) around the event and checks
def circle(n,type)
#if running and type 4 double the circle distance
n = (n * 2) - 1 if type == 4 and $game_player.speed == 3
#draw the circle
for i in 0...n
for j in 0...(n - (2 * ((i-n/2).abs)))
a = @x - n/2 + i
b = @y - n/2 + (n/2-i).abs + j
#perform check if type is diamond or circle
check(a,b) if type == 0 or type == 3
#perform noise check if type is noise
noise(a,b) if type == 4
end
end
#reset the diagonal direction after the check if doing diagonal checks
$game_map.events[@id].direction_9 = 0 if type = 0
end
def check(x,y)
#highlight the coords if L is pressed
$game_temp.highlight_new_coords << [x, y] if Input.press?(Espionage::HIGHLIGHT_K)
#if the player is in the checked co-ordinates
if x == $game_player.x and y == $game_player.y
#set self switch to true
$game_self_switches[@key] = true
#update self switches
$game_map.need_refresh = true
end
end
def noise(x,y)
#volume = 0 when sneaking, 50 when walking, 100 when running
volume = 50 + 50 * ($game_player.speed - 2)
#play sound effect
Audio.se_play('Audio/SE/' + Espionage::SOUND, volume, 100)
#local variable for the events selfswitch A
key = [$game_map.map_id,$game_map.check_event(x,y),@switch]
#set self switch to true
$game_self_switches[key] = true
#update self switches
$game_map.need_refresh = true
end
end
#===============================================================================
#Coordinate Highlighter
#by Night Runner
#===============================================================================
class Game_Temp
attr_accessor :highlight_new_coords
alias nr_FOV_initialize initialize unless $@
def initialize( *args )
# Create a temporary holding, that keeps all the new coordinates that
# need to be shaded
@highlight_new_coords = []
# Run the original Game_Temp
return nr_FOV_initialize( *args )
end
end
class Spriteset_Map
alias nr_FOV_initialize initialize unless $@
alias nr_FOV_update update unless $@
def initialize( *args )
@highlighted_squares = {}
return nr_FOV_initialize( *args )
end
def update( *args )
# Load the new coords
for x, y in $game_temp.highlight_new_coords
o_data = @highlighted_squares[ [ x, y ] ]
if not o_data.nil?
o_sprite = o_data[:sprite]
o_sprite.bitmap.dispose unless o_sprite.bitmap.disposed?
o_sprite.dispose unless o_sprite.disposed?
end
o_sprite = Sprite.new(@viewport1)
o_sprite.bitmap = Bitmap.new(32, 32)
o_sprite.bitmap.fill_rect(0, 0, 32, 32, Color.new(255, 0, 0, 100))
o_data = { :sprite => o_sprite, :time_left => 3 }
@highlighted_squares[ [ x, y ] ] = o_data
end
$game_temp.highlight_new_coords = []
# Move the sprites to their coordinates
@highlighted_squares.each do |key, data|
data[:time_left] -= 1
if data[:time_left] == 0
data[:sprite].bitmap.dispose
data[:sprite].dispose
@highlighted_squares.delete(key)
else
x, y = key
screen_x = (x * 128 - $game_map.display_x + 3) / 4
screen_y = (y * 128 - $game_map.display_y + 3) / 4
data[:sprite].x = screen_x
data[:sprite].y = screen_y
data[:sprite].update
end
end
# Run the original update
return nr_FOV_update( *args )
end
end
#===============================================================================
#Nine Directional facing.
#
#When making a turn events will face towards a diagonal or towards there
#center(below or above them) before completing there turn. You can use the
#number pad as a reference or follow the reference bellow.
#
#top left up top right 7 8 9
#left center right 4 5 6
#bottom left down bottom right 1 2 3
#===============================================================================
class Game_Character
#create a variable for 9 directional facing
attr_accessor :direction_9
alias max_direction_initialize_later initialize
alias max_turn_left_later turn_left
alias max_turn_right_later turn_right
alias max_turn_up_later turn_up
alias max_turn_down_later turn_down
def initialize
#initialize the variable
@direction_9 = 0
max_direction_initialize_later
end
def turn_left
case @direction
#when facing down, right or up and turning to the left
when 2,6,8
#face 1,3,7
@direction_9 = @direction - 1
end
max_turn_left_later
end
def turn_right
case @direction
#when facing down, left or up and turning to the right
when 2,4,8
#face 3,5,9
@direction_9 = @direction + 1
end
max_turn_right_later
end
def turn_up
case @direction
#when facing down, left or right and turning up
when 2,4,6
#face 5,7,9
@direction_9 = @direction + 3
end
max_turn_up_later
end
def turn_down
case @direction
#when facing left,right or up and turning down
when 4,6,8
#face 1,3,5
@direction_9 = @direction - 3
end
max_turn_down_later
end
end
#===============================================================================
#Cancel/Menu button split
#===============================================================================
class Scene_Map
if Espionage::MENU_SPLIT
alias max_split_update_later update
def update
# If new input button for menu is pressed
if Input.trigger?(Espionage::MENU_K)
# If event is running, or menu is not forbidden
unless $game_system.map_interpreter.running? or
$game_system.menu_disabled
# Set menu calling flag or beep flag
$game_temp.menu_calling = true
$game_temp.menu_beep = true
end
end
# Cancel old menu input
if Input.trigger?(Input::B)
return
end
max_split_update_later
end
end
end
class Scene_Menu
if Espionage::MENU_SPLIT
alias max_split_update_command_later update_command
def update_command
#if new input button is pushed
if Input.trigger?(Espionage::MENU_K)
# Play cancel SE
$game_system.se_play($data_system.cancel_se)
# Switch to map screen
$scene = Scene_Map.new
return
end
max_split_update_command_later
end
end
end
#===============================================================================
#Walk Run Sneak
#===============================================================================
class WRS
def self.run_disable #disable running
$run_allow = false
$game_map.need_refresh = true
end
def self.sneak_disable #disable sneaking
$sneak_allow = false
$game_map.need_refresh = true
end
def self.both_disable #disable both running and sneaking
$run_allow = false
$sneak_allow = false
$game_map.need_refresh = true
end
def self.run_enable #enable running
$run_allow = true
$game_map.need_refresh = true
end
def self.sneak_enable #enable sneaking
$sneak_allow = true
$game_map.need_refresh = true
end
def self.both_enable #enable both running and sneaking
$run_allow = true
$sneak_allow = true
$game_map.need_refresh = true
end
end
class Game_Character
attr_accessor :move_speed
attr_accessor :speed
alias max_wrs_initialize_later initialize
def initialize
#sneaking = 1, walking = 2, running = 3
@speed = 2
max_wrs_initialize_later
end
end
class Scene_Map
alias max_wrs_update_later update
def update
#if both sneak and run buttons are pressed and both
#sneaking and running is allowed
if Input.press?(Espionage::RUN_K) and Input.press?(Espionage::SNEAK_K) and
$run_allow and $sneak_allow
#walk
$game_player.move_speed = Espionage::WALK_S
$game_player.speed = 2
#if run button is pressed and running is allowed
elsif Input.press?(Espionage::RUN_K) and $run_allow
#run
$game_player.move_speed = Espionage::RUN_S
$game_player.speed = 3
#if sneak button is pressed and sneaking is allowed
elsif Input.press?(Espionage::SNEAK_K) and $sneak_allow
#sneak
$game_player.move_speed = Espionage::SNEAK_S
$game_player.speed = 1
#if nothing is pressed and either sneaking or running is allowed
elsif $sneak_allow or $run_allow
#walk
$game_player.move_speed = Espionage::WALK_S
$game_player.speed = 2
end
max_wrs_update_later
end
end