func (f *Fov) process(origin space.Location, radius int, begin, end angle) { if begin.radius > radius { return } group := f.group(origin, begin.point()) for a := begin; a.isBelow(end); a = a.next() { pt := a.point() if f.group(origin, pt) != group { // The type of terrain changed, recurse a deeper process with // current arc and start a new arc. if !group.blocksSight { f.process(origin.Beyond(group.portal), radius, begin.above(), a.above()) } f.process(origin, radius, a, end) return } f.markSeen(pt, f.mf.Offset(origin, pt)) } // Recurse after finishing the whole arc. if !group.blocksSight { f.process(origin.Beyond(group.portal), radius, begin.above(), end.above()) } }
func (f *Fov) group(origin space.Location, offset image.Point) group { rawLoc := origin.Add(offset) return group{f.blocksSight(f.mf.Traverse(rawLoc)), f.mf.Portal(rawLoc)} }