Oh, and if you are interested in what I came up with (keep in mind I'm an amateur too, so be gentle!!), this is a cut/paste of the entirety of my Line-of-sight code:
variables:
intCurrentX and intCurrentY are the players current coordinates
intCurrentVisualRange is the distance you can see (as a radius)
I have a function called (Passable(X1, Y1) as Boolean) which simple returns True/False based on whether you can see/move through the square or not, and I also wrote a little distance calculating function (Distance(X1, Y1, X2, Y2) as single).
I try to keep my code fairly readable, as being an amateur I often have to refigure my logic months later when I am changing something.
'LINE OF SIGHT
'first, show everything in the light radius (and later subtract out what can't be seen)
For intXCounter = (intCurrentX - intCurrentVisualRange) To (intCurrentX + intCurrentVisualRange)
For intYCounter = (intCurrentY - intCurrentVisualRange) To (intCurrentY + intCurrentVisualRange)
'make sure you don't calcualte off the edge of the map
If (intXCounter > 0) And (intXCounter < MAX_MAP_DIMENSION + 1) And (intYCounter > 0) And (intYCounter < MAX_MAP_DIMENSION + 1) Then
If Distance(intCurrentX, intCurrentY, intXCounter, intYCounter) < intCurrentVisualRange Then
With Tile(intCurrentLevel, intXCounter, intYCounter)
If .TileType <> STONE Then .Visible = True
End With
End If
End If
Next intYCounter
Next intXCounter
'next, blank out squares which are blocked by .Passable = false tiles
'the 8 tiles nearest the player are always visible, so don't change them
For intCounter = 1 To intCurrentVisualRange
For intSectionCounter = 0 To intCounter
If Tile(intCurrentLevel, intCurrentX + intCounter, intCurrentY + intSectionCounter).Passable = False Or Tile(intCurrentLevel, intCurrentX + intCounter, intCurrentY + intSectionCounter).Visible = False Then
If intSectionCounter <> intCounter Or intCounter = 1 Then Tile(intCurrentLevel, intCurrentX + intCounter + 1, intCurrentY + intSectionCounter).Visible = False
If intSectionCounter > 0 Then Tile(intCurrentLevel, intCurrentX + intCounter + 1, intCurrentY + intSectionCounter + 1).Visible = False
End If
If Tile(intCurrentLevel, intCurrentX - intCounter, intCurrentY + intSectionCounter).Passable = False Or Tile(intCurrentLevel, intCurrentX - intCounter, intCurrentY + intSectionCounter).Visible = False Then
If intSectionCounter <> intCounter Or intCounter = 1 Then Tile(intCurrentLevel, intCurrentX - intCounter - 1, intCurrentY + intSectionCounter).Visible = False
If intSectionCounter > 0 Then Tile(intCurrentLevel, intCurrentX - intCounter - 1, intCurrentY + intSectionCounter + 1).Visible = False
End If
If Tile(intCurrentLevel, intCurrentX + intCounter, intCurrentY - intSectionCounter).Passable = False Or Tile(intCurrentLevel, intCurrentX + intCounter, intCurrentY - intSectionCounter).Visible = False Then
If intSectionCounter <> intCounter Or intCounter = 1 Then Tile(intCurrentLevel, intCurrentX + intCounter + 1, intCurrentY - intSectionCounter).Visible = False
If intSectionCounter > 0 Then Tile(intCurrentLevel, intCurrentX + intCounter + 1, intCurrentY - intSectionCounter - 1).Visible = False
End If
If Tile(intCurrentLevel, intCurrentX - intCounter, intCurrentY - intSectionCounter).Passable = False Or Tile(intCurrentLevel, intCurrentX - intCounter, intCurrentY - intSectionCounter).Visible = False Then
If intSectionCounter <> intCounter Or intCounter = 1 Then Tile(intCurrentLevel, intCurrentX - intCounter - 1, intCurrentY - intSectionCounter).Visible = False
If intSectionCounter > 0 Then Tile(intCurrentLevel, intCurrentX - intCounter - 1, intCurrentY - intSectionCounter - 1).Visible = False
End If
If Tile(intCurrentLevel, intCurrentX + intSectionCounter, intCurrentY + intCounter).Passable = False Or Tile(intCurrentLevel, intCurrentX + intSectionCounter, intCurrentY + intCounter).Visible = False Then
If intSectionCounter <> intCounter Or intCounter = 1 Then Tile(intCurrentLevel, intCurrentX + intSectionCounter, intCurrentY + intCounter + 1).Visible = False
If intSectionCounter > 0 Then Tile(intCurrentLevel, intCurrentX + intSectionCounter + 1, intCurrentY + intCounter + 1).Visible = False
End If
If Tile(intCurrentLevel, intCurrentX - intSectionCounter, intCurrentY + intCounter).Passable = False Or Tile(intCurrentLevel, intCurrentX - intSectionCounter, intCurrentY + intCounter).Visible = False Then
If intSectionCounter <> intCounter Or intCounter = 1 Then Tile(intCurrentLevel, intCurrentX - intSectionCounter, intCurrentY + intCounter + 1).Visible = False
If intSectionCounter > 0 Then Tile(intCurrentLevel, intCurrentX - intSectionCounter - 1, intCurrentY + intCounter + 1).Visible = False
End If
If Tile(intCurrentLevel, intCurrentX + intSectionCounter, intCurrentY - intCounter).Passable = False Or Tile(intCurrentLevel, intCurrentX + intSectionCounter, intCurrentY - intCounter).Visible = False Then
If intSectionCounter <> intCounter Or intCounter = 1 Then Tile(intCurrentLevel, intCurrentX + intSectionCounter, intCurrentY - intCounter - 1).Visible = False
If intSectionCounter > 0 Then Tile(intCurrentLevel, intCurrentX + intSectionCounter + 1, intCurrentY - intCounter - 1).Visible = False
End If
If Tile(intCurrentLevel, intCurrentX - intSectionCounter, intCurrentY - intCounter).Passable = False Or Tile(intCurrentLevel, intCurrentX - intSectionCounter, intCurrentY - intCounter).Visible = False Then
If intSectionCounter <> intCounter Or intCounter = 1 Then Tile(intCurrentLevel, intCurrentX - intSectionCounter, intCurrentY - intCounter - 1).Visible = False
If intSectionCounter > 0 Then Tile(intCurrentLevel, intCurrentX - intSectionCounter - 1, intCurrentY - intCounter - 1).Visible = False
End If
Next intSectionCounter
Next intCounter
And that's it. As you can see, I make everything in the view radius visible first, and then blank out blocked squares manually. For small view radii (under 10), it works great. Larger radii seem to produce some anomalies due to me forcing 45 degree checks on light from each square. (My code doesn't look at shallower angles and block vision if a tiny piece of a blocked square impedes vision.) It's a bit bulky and brute force, and not flexible at all, but it works. I wish I was good enough to come up with something small and efficient, but for my skill level I am happy.