// // IsOpenDoor // This function is pretty obsolete now, since doors get replaced by zeros in the // map when open and with DOOR_INDEX when closed // bool Raycaster::IsOpenDoor() { static int doorX, doorY; int i; for(i=0; i<1; i++) { switch(i) { case 0: doorX = (int)posX; doorY = (int)posY; break; case 1: doorX = (int)(posX+MIN_WALL_DIST); doorY = (int)(posY+MIN_WALL_DIST); break; case 2: doorX = (int)(posX-MIN_WALL_DIST); doorY = (int)(posY-MIN_WALL_DIST); break; case 3: doorX = (int)(posX+MIN_WALL_DIST); doorY = (int)posY; break; case 4: doorX = (int)posX; doorY = (int)(posY+MIN_WALL_DIST); break; case 5: doorX = (int)posX; doorY = (int)(posY-MIN_WALL_DIST); break; case 6: doorX = (int)(posX-MIN_WALL_DIST); doorY = (int)(posY); break; } if(map[doorY][doorX] == DOOR_INDEX) { Door *door = GetDoorAt(doorX, doorY); if(door->IsOpen() && !door->GetClosing()) return true; } } return false; }
// // CastThroughIntersections // float Raycaster::CastThroughIntersections(float angle, IntersectionDir dir, int *texIndex, float *texelX) { float fx, fy; float dx, dy; float distance; float a, b; int mapX, mapY; switch(dir) { case ID_HORIZONTAL: if(UP(angle)) { fy = -(posY - (int)posY); dy = -1; } else { fy = (int)posY + 1 - posY; dy = 1; } fx = (float)(ABS(fy)) / (float)(TAN(angle)); dx = (float)(ABS(dy)) / (float)(TAN(angle)); fx = ABS(fx); dx = ABS(dx); if(LEFT(angle)) { dx = -dx; fx = -fx; } fx = posX + fx; fy = posY + fy; break; case ID_VERTICAL: if(LEFT(angle)) { fx = -(posX - (int)posX); dx = -1; } else { fx = (int)posX + 1 - posX; dx = 1; } fy = (float)(TAN(angle)) * (float)(ABS(fx)); dy = (float)(TAN(angle)) * (float)(ABS(dx)); fy = ABS(fy); dy = ABS(dy); if(UP(angle)) { fy = -fy; dy = -dy; } fx = posX + fx; fy = posY + fy; break; } while(true) { mapY = (int)fy; mapX = (int)fx; if(dy == -1 && dir == ID_HORIZONTAL) mapY -= 1; else if(dx == -1 && dir == ID_VERTICAL) mapX -= 1; if(mapX < 0 || mapY < 0 || mapX >= mapW || mapY >= mapH) break; else if(map[mapY][mapX] > 0 && map[mapY][mapX] != DOOR_INDEX && map[mapY][mapX] != LOCKED_DOOR_INDEX) { hit: if(dir == ID_HORIZONTAL) *texelX = fx - (float)mapX; else *texelX = fy - (float)mapY; *texIndex = map[mapY][mapX] - 1; break; } else if(map[mapY][mapX] == DOOR_INDEX || map[mapY][mapX] == LOCKED_DOOR_INDEX) { Door *door = GetDoorAt(mapX, mapY); if(door->GetOpening() || door->GetClosing()) { float xval; if(dir == ID_HORIZONTAL) xval = fx - (float)mapX; else xval = fy - (float)mapY; if(door->GetOpenedWidth() < xval) goto hit; } else if(!door->IsOpen()) goto hit; } fx += dx; fy += dy; } a = ABS((fy - posY)); b = ABS((fx - posX)); distance = sqrt(a*a+b*b); return distance; }
// // OpenDoor // void Raycaster::OpenDoor(bool hasKey, bool *needAKey) { static int doorPosX, doorPosY; static Uint32 lDoorOpen = 0; int i; // Don't close doors we're standing in if(map[(int)posY][(int)posX] == DOOR_INDEX) return; for(i=0; i<4; i++) { switch(i) { case 0: doorPosX = (int)posX; doorPosY = (int)posY + 1; break; case 1: doorPosX = (int)posX + 1; doorPosY = (int)posY; break; case 2: doorPosX = (int)posX; doorPosY = (int)posY - 1; break; case 3: doorPosX = (int)posX - 1; doorPosY = (int)posY; break; } if(doorPosX < 0 || doorPosY < 0) continue; if(map[doorPosY][doorPosX] == DOOR_INDEX || map[doorPosY][doorPosX] == LOCKED_DOOR_INDEX) { if(lDoorOpen == 0) lDoorOpen = SDL_GetTicks(); else if(SDL_GetTicks() - lDoorOpen < DOOR_CHG_TIME) continue; Door *door = GetDoorAt(doorPosX, doorPosY); //door->SetOpen(!door->IsOpen()); if(!door->IsLockedDoor() || hasKey) { if(!door->IsOpen()) door->SetOpening(true); else door->SetClosing(true); lDoorOpen = SDL_GetTicks(); } else if(door->IsLockedDoor()) *needAKey = true; return; } else if(map[doorPosY][doorPosX] == EXIT_DOOR_INDEX) mapChange = true; } }