I have been stalled somewhat by tracking down a bug in my field of view code. I learned up on it and based mine off of the improved version that uses the improved variant described on
. There was even a C# implementation that I was able to look at. In either Octant 6 or 7, maybe both there is an error that I can not explain. Here is the code I used:
protected bool In_Range(int x1, int y1, int x2, int y2, int Range)
{
try
{
char i = map.tile[y1, x1].Symbol;
i = map.tile[y2, x2].Symbol;
if (x1 == x2) { return Math.Abs(y1 - y2) <= Range; }
if (y1 == y2) { return Math.Abs(x1 - x2) <= Range; }
return (Math.Pow((x1 - x2), 2) + Math.Pow((y1 - y2), 2)) <= Math.Pow(Range, 2);
}
catch
{
return false;
}
}
private double Get_Slope(double x1, double y1, double x2, double y2)
{
return (x1 - x2) / (y1 - y2);
}
private double Get_SlopeInv(double x1, double y1, double x2, double y2)
{
return (y1 - y2) / (x1 - x2);
}
protected void Set_Visible(int Depth, int Octant, double StartSlope, double EndSlope)
{
int x = 0;
int y = 0;
switch (Octant)
{
case 1:
y = player.Location.Y - Depth;
x = player.Location.X - Convert.ToInt32((StartSlope * Convert.ToDouble(Depth)));
if (x < 0) break;
if (x >= map.Width) break;
if (y < 0) break;
if (y >= map.Height) break;
while (Get_Slope(x, y, player.Location.X, player.Location.Y) >= EndSlope)
{
if (In_Range(player.Location.X, player.Location.Y, x, y, player.Sight_Range))
{
if (!map.tile[y, x].Seethrough)
{
if (map.tile[y, x - 1].Seethrough)
{
Set_Visible(Depth + 1, Octant, StartSlope, Get_Slope(x - 0.5, y + 0.5, player.Location.X, player.Location.Y));
}
}
else
{
if (!map.tile[y, x - 1].Seethrough)
{
StartSlope = Get_Slope(x - 0.5, y - 0.5, player.Location.X, player.Location.Y);
}
}
map.tile[y, x].Visible = true;
if (!map.tile[y, x].Seen) { map.tile[y, x].Seen = true; }
}
x++;
}
x--;
break;
case 2:
y = player.Location.Y - Depth;
x = player.Location.X + Convert.ToInt32((StartSlope * Convert.ToDouble(Depth)));
if (x < 0) break;
if (x >= map.Width) break;
if (y < 0) break;
if (y >= map.Height) break;
while (Get_Slope(x, y, player.Location.X, player.Location.Y) <= EndSlope)
{
if (In_Range(player.Location.X, player.Location.Y, x, y, player.Sight_Range))
{
if (!map.tile[y, x].Seethrough)
{
if (map.tile[y, x + 1].Seethrough)
{
Set_Visible(Depth + 1, Octant, StartSlope, Get_Slope(x + 0.5, y + 0.5, player.Location.X, player.Location.Y));
}
}
else
{
if (!map.tile[y, x + 1].Seethrough)
{
StartSlope = -Get_Slope(x + 0.5, y - 0.5, player.Location.X, player.Location.Y);
}
}
map.tile[y, x].Visible = true;
if (!map.tile[y, x].Seen) { map.tile[y, x].Seen = true; }
}
x--;
}
x++;
break;
case 3:
x = player.Location.X + Depth;
y = player.Location.Y - Convert.ToInt32((StartSlope * Convert.ToDouble(Depth)));
if (x < 0) break;
if (x >= map.Width) break;
if (y < 0) break;
if (y >= map.Height) break;
while (Get_SlopeInv(x, y, player.Location.X, player.Location.Y) <= EndSlope)
{
if (In_Range(player.Location.X, player.Location.Y, x, y, player.Sight_Range))
{
if (!map.tile[y, x].Seethrough)
{
if (map.tile[y - 1, x].Seethrough)
{
Set_Visible(Depth + 1, Octant, StartSlope, Get_Slope(x - 0.5, y - 0.5, player.Location.X, player.Location.Y));
}
}
else
{
if (!map.tile[y - 1, x].Seethrough)
{
StartSlope = -Get_SlopeInv(x + 0.5, y - 0.5, player.Location.X, player.Location.Y);
}
}
map.tile[y, x].Visible = true;
if (!map.tile[y, x].Seen) { map.tile[y, x].Seen = true; }
}
y++;
}
y--;
break;
case 4:
x = player.Location.X + Depth;
y = player.Location.Y + Convert.ToInt32((StartSlope * Convert.ToDouble(Depth)));
if (x < 0) break;
if (x >= map.Width) break;
if (y < 0) break;
if (y >= map.Height) break;
while (Get_SlopeInv(x, y, player.Location.X, player.Location.Y) >= EndSlope)
{
if (In_Range(player.Location.X, player.Location.Y, x, y, player.Sight_Range))
{
if (!map.tile[y, x].Seethrough)
{
if (map.tile[y + 1, x].Seethrough)
{
Set_Visible(Depth + 1, Octant, StartSlope, Get_SlopeInv(x - 0.5, y + 0.5, player.Location.X, player.Location.Y));
}
}
else
{
if (!map.tile[y + 1, x].Seethrough)
{
StartSlope = Get_SlopeInv(x + 0.5, y + 0.5, player.Location.X, player.Location.Y);
}
}
map.tile[y, x].Visible = true;
if (!map.tile[y, x].Seen) { map.tile[y, x].Seen = true; }
}
y--;
}
y++;
break;
case 5:
y = player.Location.Y + Depth;
x = player.Location.X + Convert.ToInt32((StartSlope * Convert.ToDouble(Depth)));
if (x < 0) break;
if (x >= map.Width) break;
if (y < 0) break;
if (y >= map.Height) break;
while (Get_Slope(x, y, player.Location.X, player.Location.Y) >= EndSlope)
{
if (In_Range(player.Location.X, player.Location.Y, x, y, player.Sight_Range))
{
if (!map.tile[y, x].Seethrough)
{
if (map.tile[y, x + 1].Seethrough)
{
Set_Visible(Depth + 1, Octant, StartSlope, Get_Slope(x + 0.5, y - 0.5, player.Location.X, player.Location.Y));
}
}
else
{
if (!map.tile[y, x + 1].Seethrough)
{
StartSlope = Get_Slope(x + 0.5, y + 0.5, player.Location.X, player.Location.Y);
}
}
map.tile[y, x].Visible = true;
if (!map.tile[y, x].Seen) { map.tile[y, x].Seen = true; }
}
x--;
}
x++;
break;
case 6:
y = player.Location.Y + Depth;
x = player.Location.X - Convert.ToInt32((StartSlope * Convert.ToDouble(Depth)));
if (x < 0) break;
if (x >= map.Width) break;
if (y < 0) break;
if (y >= map.Height) break;
while (Get_Slope(x, y, player.Location.X, player.Location.Y) <= EndSlope)
{
if (In_Range(player.Location.X, player.Location.Y, x, y, player.Sight_Range))
{
if (!map.tile[y, x].Seethrough)
{
if (map.tile[y, x - 1].Seethrough)
{
Set_Visible(Depth + 1, Octant, StartSlope, Get_Slope(x - 0.5, y - 0.5, player.Location.X, player.Location.Y));
}
}
else
{
if (!map.tile[y, x - 1].Seethrough)
{
StartSlope = -Get_Slope(x - 0.5, y + 0.5, player.Location.X, player.Location.Y);
}
}
map.tile[y, x].Visible = true;
if (!map.tile[y, x].Seen) { map.tile[y, x].Seen = true; }
}
x++;
}
x--;
break;
case 7:
x = player.Location.X - Depth;
y = player.Location.Y + Convert.ToInt32((StartSlope * Convert.ToDouble(Depth)));
if (x < 0) break;
if (x >= map.Width) break;
if (y < 0) break;
if (y >= map.Height) break;
while (Get_SlopeInv(x, y, player.Location.X, player.Location.Y) <= EndSlope)
{
if (In_Range(player.Location.X, player.Location.Y, x, y, player.Sight_Range))
{
if (!map.tile[y, x].Seethrough)
{
if (map.tile[y + 1, x].Seethrough)
{
Set_Visible(Depth + 1, Octant, StartSlope, Get_SlopeInv(x + 0.5, y + 0.5, player.Location.X, player.Location.Y));
}
}
else
{
if (!map.tile[y + 1, x].Seethrough)
{
StartSlope = Get_SlopeInv(x - 0.5, y + 0.5, player.Location.X, player.Location.Y);
}
}
map.tile[y, x].Visible = true;
if (!map.tile[y, x].Seen) { map.tile[y, x].Seen = true; }
}
y--;
}
y++;
break;
case 8:
x = player.Location.X - Depth;
y = player.Location.Y - Convert.ToInt32((StartSlope * Convert.ToDouble(Depth)));
if (x < 0) break;
if (x >= map.Width) break;
if (y < 0) break;
if (y >= map.Height) break;
while (Get_SlopeInv(x, y, player.Location.X, player.Location.Y) >= EndSlope)
{
if (In_Range(player.Location.X, player.Location.Y, x, y, player.Sight_Range))
{
if (!map.tile[y, x].Seethrough)
{
if (map.tile[y - 1, x].Seethrough)
{
Set_Visible(Depth + 1, Octant, StartSlope, Get_SlopeInv(x + 0.5, y - 0.5, player.Location.X, player.Location.Y));
}
}
else
{
if (!map.tile[y - 1, x].Seethrough)
{
StartSlope = Get_SlopeInv(x - 0.5, y - 0.5, player.Location.X, player.Location.Y);
}
}
map.tile[y, x].Visible = true;
if (!map.tile[y, x].Seen) { map.tile[y, x].Seen = true; }
}
y++;
}
y--;
break;
}
if (x < 0) x = 0;
if (x >= map.Width) x = map.Width - 1;
if (y < 0) y = 0;
if (y >= map.Height) y = map.Height - 1;
if ((In_Range(player.Location.X, player.Location.Y, x, y, player.Sight_Range)) && (map.tile[y, x].Seethrough))
{
Set_Visible(Depth + 1, Octant, StartSlope, EndSlope);
}
}
public void Calculate_Sight()
{
for (int y = 0; y < map.Height; y++)
{
for (int x = 0; x < map.Width; x++)
{
map.tile[y, x].Visible = false;
}
}
for (int Octant = 1; Octant < 9; Octant++)
{
Set_Visible(1, Octant, 1.0, 0.0);
}
}