OK, I went back to this after a while, and got somewhat of a 'hack' fix for the above issues; it seems to work in testing (even when running XAS Ace, no less). While this fix will likely screw up plans for complex & precise height checking across varied terrain and event heights, it at least allows you to have a stealth action game where you can crouch behind waist-high obstacles in order to remain hidden, and you get seen when you stand up in the enemy's line of sight. It will also cause obstacles taller than the height of an event to block that event's line of sight.
I'm not a scripter so this may be inefficient/buggy, but this solution seems to work, provided you're OK with the above tradeoffs. (And I am. Assuming your map terrain was probably going to be mostly flat anyway, and the 'characters' in your stealth sequences have mostly the same heights, it works and makes sense. This probably also works best with Mack-sized charas, since that makes ducking look & work more naturally with the settings below.)
Basically, there are four steps to get it working. Note that you *DO* have to do some manual terrain tagging of your tilesets.
1. Find the code in my post above and replace it with this:
tiles.each {|coords, heights| next if coords == [self.x, self.y] sx = self.x - char.x sy = self.y - char.y if sx.abs > sy.abs direction = sx > 0 ? 4 : 6 elsif sy != 0 direction = sy > 0 ? 8 : 2 end height = $game_map.total_height(coords[0], coords[1], direction) return false if height >= self.height case direction when 2 return false if ((height >= char.height) and (char.x == coords[0]) and (char.y == coords[1] + 1)) when 8 return false if ((height >= char.height) and (char.x == coords[0]) and (char.y == coords[1] - 1)) when 4 return false if ((height >= char.height) and (char.x == coords[0]-1) and (char.y == coords[1])) when 6 return false if ((height >= char.height) and (char.x == coords[0]+1) and (char.y == coords[1])) end if heights[1] < 0 return false end }Note that "heights[1] < 0" replaces "heights[1] <= 0"--this is crucial, as it fixes the "invisible in direct line of sight" issue. I have no idea what that variable evens means, though; I haven't encountered any bugs with it, but there could be some. It just seems to work.
Also note that when the player is ducking behind an object of a height less than that of the 'enemy' event's height, the player will *only* be hidden if he is right next to the tile and on the far side of it in the enemy's line of sight. I suppose you could also change the code above to have the cutoff height be based on the player's instead of the enemy event's. Meh. As I said, I'm no coder, so I go with whatever works for me regardless of elegance/precision/efficiency.
2. Change "UNPASSABLE_HEIGHT = (1.0 / 0.0)" to just "UNPASSABLE_HEIGHT = (1.0)"--that should fix the div by zero issue causing the "-infinity" result described in my previous post.
3. Define custom terrain heights. These are the ones I used, which assume that all other settings are left as default. Descriptions included below.
TERRAIN_HEIGHTS = { 1 => 5.0, # Wall 2 => 2.0, # Two-tile-high impassable object 3 => -1.0, # Impassable object that player shouldn't be able to duck behind }4. Apply the terrain tags to your tiles.
You need to apply Terrain 1 to ALL wall & ceiling tiles--otherwise the default impassable height of 1.0 will cause enemies to have magic x-ray vision and see the player through walls (since the height of the player is 1.7 by default).
Like it says, Terrain 2 should be applied to two-tile-high impassable objects. This will allow you to hide behind the obstacle without ducking. The terrain tag should *only be applied to the base tile* of the object, though.
Terrain 3 is for tiles that are impassable but which the player shouldn't be able to hide behind by ducking--beer bottles, bones, things of that nature. The -1 offsets the default impassable terrain height of 1.
-----
OK, that about covers it. I won't be supporting this workaround b/c I really have no idea what I'm doing in the first place.
Adding in scripts for sound detection or backstabbing (via XAS) would be interesting, but I'm not up to the task. Happy stealthing.