the switch to be activated when the event see the hero. false if none
SWITCH = 35
class Game_Character
attr_reader :cone
attr_reader :prev_x
attr_reader :prev_y
attr_reader :prev_dir
attr_accessor :sight
alias conesys_gamecharacter_initialize initialize
def initialize
@cone = []
@sight = 0
conesys_gamecharacter_initialize
end
def get_cone(sight = 7)
cone = []
@sight = sight
#This algorithim makes the cone using a 2d array
case self.direction
when 2 #down
#adds the first square
line = 1
cone.push([self.x,self.y + 1])
factor = 1
#now comes the routine to make the cone
while line < sight
line += 1
cone.push([self.x,self.y + line])
1.upto(factor) do |a|
cone.push([self.x - a,self.y + line])
cone.push([self.x + a,self.y + line])
end
factor += 1
end
when 4 #left
line = 1
cone.push([self.x - 1,self.y])
factor = 1
#now comes the routine to make the cone
while line < sight
line += 1
cone.push([self.x - line,self.y])
1.upto(factor) do |a|
cone.push([self.x - line,self.y - a])
cone.push([self.x - line,self.y + a])
end
factor += 1
end
when 6 #right
line = 1
cone.push([self.x + 1,self.y])
factor = 1
#now comes the routine to make the cone
while line < sight
line += 1
cone.push([self.x + line,self.y])
1.upto(factor) do |a|
cone.push([self.x + line,self.y - a])
cone.push([self.x + line,self.y + a])
end
factor += 1
end
when 8 #up
#adds the first square
line = 1
cone.push([self.x,self.y + 1])
factor = 1
#now comes the routine to make the cone
while line < sight
line += 1
cone.push([self.x,self.y - line])
1.upto(factor) do |a|
cone.push([self.x - a,self.y - line])
cone.push([self.x + a,self.y - line])
end
factor += 1
end
end
cone_obstacles(cone)
end
#here any tile that is covered by an obstacle is removed
#from the cone
def cone_obstacles(cone)
for i in 0..cone.length
if cone[i] != nil
if !$game_map.passable?(cone[i][0], cone[i][1], 0)
case self.direction
when 2 #down
#the diference between the sight and the obstacle position
limit = self.sight - (cone[i][1] - self.y)
position = 1
#to make the read easier
index = cone.index([cone[i][0],cone[i][1] + 1])
cone[index] = nil if index != nil
factor = 1
#now comes the routine to remove the bloked tiles
while position < limit
position += 1
index = cone.index([cone[i][0],cone[i][1] + position])
cone[index] = nil if index != nil
1.upto(factor) do |a|
index = cone.index([cone[i][0] - a,cone[i][1] + position])
cone[index] = nil if index != nil
index = cone.index([cone[i][0] + a,cone[i][1] + position])
cone[index] = nil if index != nil
end
factor += 1
end
when 4 #left
#the diference between the sight and the obstacle position
limit = self.sight - (self.x - cone[i][0])
position = 1
#to make the read easier
index = cone.index([cone[i][0] - 1,cone[i][1]])
cone[index] = nil if index != nil
factor = 1
#now comes the routine to remove the bloked tiles
while position < limit
position += 1
index = cone.index([cone[i][0] - position,cone[i][1]])
cone[index] = nil if index != nil
1.upto(factor) do |a|
index = cone.index([cone[i][0] - position,cone[i][1] - a])
cone[index] = nil if index != nil
index = cone.index([cone[i][0] - position,cone[i][1] + a])
cone[index] = nil if index != nil
end
factor += 1
end
when 6 #right
#the diference between the sight and the obstacle position
limit = self.sight - (cone[i][0] - self.x)
position = 1
#to make the read easier
index = cone.index([cone[i][0] + 1,cone[i][1]])
cone[index] = nil if index != nil
factor = 1
#now comes the routine to remove the bloked tiles
while position < limit
position += 1
index = cone.index([cone[i][0] + position,cone[i][1]])
cone[index] = nil if index != nil
1.upto(factor) do |a|
index = cone.index([cone[i][0] + position,cone[i][1] - a])
cone[index] = nil if index != nil
index = cone.index([cone[i][0] + position,cone[i][1] + a])
cone[index] = nil if index != nil
end
factor += 1
end
when 8 #up
#the diference between the sight and the obstacle position
limit = self.sight - (self.y - cone[i][1])
position = 1
#to make the read easier
index = cone.index([cone[i][0],cone[i][1] - 1])
cone[index] = nil if index != nil
factor = 1
#now comes the routine to remove the bloked tiles
while position < limit
position += 1
index = cone.index([cone[i][0],cone[i][1] - position])
cone[index] = nil if index != nil
1.upto(factor) do |a|
index = cone.index([cone[i][0] - a,cone[i][1] - position])
cone[index] = nil if index != nil
index = cone.index([cone[i][0] + a,cone[i][1] - position])
cone[index] = nil if index != nil
end
factor += 1
end
end
end
end
end
#update the variables used to check the need of a refresh
@prev_x = self.x
@prev_y = self.y
@prev_dir = self.direction
@cone = cone
end
def in_cone
#return false if the event do not have a cone
if cone != []
#now it checks if the actual position of the hero is inside the cone
for i in 0...cone.length
if cone[i] != nil
if $game_player.x == cone[i][0] && $game_player.y == cone[i][1]
$game_switches[SWITCH] = true if SWITCH
$game_map.need_refresh = true
move_toward_player
end
end
end
end
end
def move_toward_player
# Get difference in player coordinates
sx = @x - $game_player.x
sy = @y - $game_player.y
# If coordinates are equal
if sx == 0 and sy == 0
return
end
#Now the 8-direction following
#diagonal movements
if sx > 0 && sy > 0; move_upper_left
elsif sx > 0 && sy < 0; move_lower_left
elsif sx < 0 && sy > 0; move_upper_right
elsif sx < 0 && sy < 0; move_lower_right
#normal movement
elsif sx < 0 && sy == 0; move_right
elsif sx > 0 && sy == 0; move_left
elsif sx == 0 && sy < 0; move_down
elsif sx == 0 && sy > 0; move_up
end
end
#these modifications make the "hero touch" work better
#thanks Linkin_T for the help
def check_event_trigger_touch(x, y)
return if not @stop_count > (40 - @move_frequency * 2) * (6 - @move_frequency)
old_touch(x, y)
end
def check_event_trigger_auto
return if not @stop_count > (40 - @move_frequency * 2) * (6 - @move_frequency)
old_auto
end
end
class Game_Event < Game_Character
attr_reader :has_cone
alias conesys_gameevent_initialize initialize
alias old_touch check_event_trigger_touch
alias old_auto check_event_trigger_auto
def initialize(map_id, event)
#a flag that tells if the event is cone-following-enabled or not
@has_cone = false
conesys_gameevent_initialize(map_id, event)
end
#start the cone routine.
def add_cone(sight = 7)
@has_cone = true
get_cone(sight)
end
#stop the "cone following"
def stop_cone
@has_cone = false
end
end
class Game_Player < Game_Character
alias conesys_gameplayer_update update
def update
check_cone
conesys_gameplayer_update
end
def check_cone
#check if the event has a cone
for i in $game_map.events.keys
event = $game_map.events[i]
if event.has_cone && $scene.is_a?(Scene_Map)
#check if the player is inside the cone of vision and make the
#event follow him
event.in_cone
#update the cone if the event moved or the direction is different
if event.x != event.prev_x || event.y != event.prev_y || event.direction != event.prev_dir
event.get_cone(event.sight)
end
end
end
end
end
Credit to Lobosque if used.
To set up a cone, you need to add
$game_map.events[EVENT NUMBER].add_cone(VIEW RANGE)
in a script command, put the event number and the range (in tiles) in the appropriate spots.
http://www.hbgames.org/forums/showthread.php?t=19301