void CLevel::RecurseReachable(const CCoord<int>& aPos, bool aHoriz) { if (!InLevel(aPos)) return; if (Collision(aPos)) return; if (Reachable(aPos)) return; if (aHoriz) { int xmin=aPos.X(), xmax=aPos.X(),y=aPos.Y(),a; do { xmin--; } while (!Collision(xmin,y)&&!Reachable(CCoord<int>(xmin,y))&&InLevel(xmin,y)); do { xmax++; } while (!Collision(xmax,y)&&!Reachable(CCoord<int>(xmax,y))&&InLevel(xmax,y)); for (a=xmin+1;a<xmax;a++) iReachableBlock[y*iWidth + a] = true; if (y-1>=0) for (a=xmin+1;a<xmax;a++) RecurseReachable(CCoord<int>(a,y-1),!aHoriz); if (y+1<iHeight) for (a=xmin+1;a<xmax;a++) RecurseReachable(CCoord<int>(a,y+1),!aHoriz); } else { int ymin=aPos.Y(), ymax=aPos.Y(),x=aPos.X(),a; do { ymin--; } while (!Collision(x,ymin)&&!Reachable(CCoord<int>(x,ymin))&&InLevel(x,ymin)); do { ymax++; } while (!Collision(x,ymax)&&!Reachable(CCoord<int>(x,ymax))&&InLevel(x,ymax)); for (a=ymin+1;a<ymax;a++) iReachableBlock[a*iWidth + x] = true; if (x-1>=0) for (a=ymin+1;a<ymax;a++) RecurseReachable(CCoord<int>(x-1,a),!aHoriz); if (x+1<iWidth) for (a=ymin+1;a<ymax;a++) RecurseReachable(CCoord<int>(x+1,a),!aHoriz); } }
void CalcStampdownPos() { float lv = 4; //if(!InMap(raystart)) {stdownvalid = mapstdownvalid = 0; return;} Vector3 ptt = raystart, vta; NormalizeVector3(&vta, &raydir); vta *= lv; float h; int nlp = farzvalue * 1.5f / lv; int m = (ptt.y < GetHeight(ptt.x, ptt.z)) ? 0 : 1; for(int i = 0; i < nlp; i++) { ptt += vta; if(!InMap(ptt)) continue; //{stdownvalid = mapstdownvalid = 0; return;} h = GetHeight(ptt.x, ptt.z); if(ptt.y == h) break; //if( (!m && (ptt.y > h)) // || (m && (ptt.y < h)) ) if(m ^ ((ptt.y > h)?1:0)) {vta *= -0.5f; m = 1 - m;} } if(InMap(ptt)) {mapstdownpos = ptt; mapstdownpos.y = h; mapstdownvalid = 1;} else mapstdownvalid = 0; if(mapstdownvalid && InLevel(mapstdownpos)) {stdownpos = mapstdownpos; stdownvalid = 1;} else stdownvalid = 0; }
EXPORT bool CLevel::Reachable(const CCoord<int>& aPos) const { ASSERT(iReachableBlock); if (!InLevel(aPos)) return false; return iReachableBlock[aPos.Y()*iWidth + aPos.X()]; }