I'll field this one
and I'll post a solution, so
actual developers please take note!
To answer your question, the second image (more spots targeted) is correct. "But why aren't the north-south breath attacks like this," you ask? Well, as implemented, the cartesian plane is divided into eight
Octants, and only half the octants are capable of displaying diagonals or north-south, east-west edges. This prevents double-counting. However, it is
also responsible for the asymmetry that you found--and how I never notice that before, I have no idea!
I posted the main corrected file as an attachment "fov.c".
I want to cover a couple other issues I found while looking through this section of the code...
You may have noticed that the cardinal directions are brighter than the rest of the targeted area. This is, obviously, because the green targeting image is applied twice. But wait! I just said the asymmetry you noticed is because the algorithm
avoids double-counting! What's going on, then? Well, the core algorithm works (mostly) correctly, but it calls the wrong functions that do the wrong things at the wrong times. Basically, when it calls a function that is
supposed to check whether a specific location is obscured (or blocked) or not, this function does this
as well as performing an action on that location. This, as I see it, is just plain wrong. There is a separate function that is intended to perform that action on a location as needed, but this function often does nothing at all. I'll use the cone breath as an example, but this issue occurs elsewhere(!!!!!!!!!!!!!!!).
From "game/engines/default/engine/Target.lua:display" (near line 118)
Code: Select all
elseif self.target_type.cone and self.target_type.cone > 0 then
core.fov.calc_beam(
radius_x,
radius_y,
game.level.map.w,
game.level.map.h,
self.target_type.cone,
initial_dir,
self.target_type.cone_angle,
function(_, px, py)
self.sg:toScreen(self.display_x + (px - game.level.map.mx) * self.tile_w * Map.zoom,
self.display_y + (py - game.level.map.my) * self.tile_h * Map.zoom,
self.tile_w * Map.zoom,
self.tile_h * Map.zoom)
if self.target_type.block_radius and self.target_type:block_radius(px, py) then return true end
end,
function()end,
nil)
end
should be
Code: Select all
elseif self.target_type.cone and self.target_type.cone > 0 then
core.fov.calc_beam(
radius_x,
radius_y,
game.level.map.w,
game.level.map.h,
self.target_type.cone,
initial_dir,
self.target_type.cone_angle,
function(_, px, py)
if self.target_type.block_radius and self.target_type:block_radius(px, py) then return true end
end,
function(_, px, py)
self.sg:toScreen(self.display_x + (px - game.level.map.mx) * self.tile_w * Map.zoom,
self.display_y + (py - game.level.map.my) * self.tile_h * Map.zoom,
self.tile_w * Map.zoom,
self.tile_h * Map.zoom)
end,
nil)
end
The third-to-last argument is the function intended to check if a location is blocked. The second to last argument is the function to perform an action on that location, but here it was defined as "function()end"--doing nothing! Using the code I provided prevents the extra-highlighted lines in cardinal directions.
Another issue is that the cone (aka beam) algorithm doesn't work correctly if the angle is less than 45 degrees (which it isn't right now in the game, but it
could be in principle). This is a straightforward fix in "src/fov/fov.c:FOV_DEFINE_OCTANT" (near line 221), change
Code: Select all
if (!apply_diag && dy1 == dx) { \
/* We do diagonal lines on every second octant, so they don't get done twice. */ \
--dy1; \
}
to
Code: Select all
if (!apply_diag && dy1 == dx) { \
/* We do diagonal lines on every second octant, so they don't get done twice. */ \
--dy1; \
\
/* But, we still need to check if we can see past it if the slopes are similar */ \
if (dy1 < dy0) { \
if (settings->opaque(data->map, x, y)) { \
return; \
} \
prev_blocked = 0; \
} \
}
I made several more changes to this file (and these functions), so you should probably just download the attached "fov.c" file if you're a developer.
Here are examples I made using these corrections. No more asymmetry! No more lines!

- cut_west.png (176.22 KiB) Viewed 2537 times

- cut_south.png (138.08 KiB) Viewed 2537 times