Good job finding this bug. There is definitely something wrong with the wall algorithm:
#--------------------------------------------------------------------------
# wall?
# char - the character
# x - x-coordinate
# y - y-coordinate
# Checks if between the char and the target is a "wall". Walls prevent
# perception.
#--------------------------------------------------------------------------
def wall?(char, x, y)
# abort instantly if not using this option
return false if Config::WALL_TAGS.size == 0
# get pixel movement rate
pix = $BlizzABS.pixel
# get coordinate difference
dx, dy = (x-char.x)/pix, (y-char.y)/pix
# if x difference is not 0 and x difference is greater
if dx != 0 && dx.abs > dy.abs
# return any wall tile between
return (0..dx.abs).any? {|i| Config::WALL_TAGS.include?($game_map.
terrain_tag(char.x/pix+dx.sgn*i, char.y/pix+(i.to_f*dy/dx).round))}
# if y difference is not 0 and y difference is greater
elsif dy != 0 && dy.abs > dx.abs
# return any wall tile between
return (0..dy.abs).any? {|i| Config::WALL_TAGS.include?($game_map.
terrain_tag(char.x/pix+(i.to_f*dx/dy).round, char.y/pix+dy.sgn*i))}
end
# no wall between
return false
end
For the bottom right corner in your demo, the (dx, dy) is (3, 3). Because dx == dy, the two if-statements are ignored, and the method returns false.
For the bottom left area, we're running through this part of the method:
# return any wall tile between
return (0..dx.abs).any? {|i| Config::WALL_TAGS.include?($game_map.
terrain_tag(char.x/pix+dx.sgn*i, char.y/pix+(i.to_f*dy/dx).round))}
The problem is that, as the loop iterates, it is checking the tile to the left and
UP, starting from the enemy's position.
Your event is at (9, 7). When i = 1, it checks if tile (8, 6) is a wall, which it isn't. It should be checking (8, 8 ) instead.
Not currently in a position to fix it, but letting you know why it's behaving that way.