int WorldGenerator::genChairsByFurniture( Level& level, Room& room, Level::Furniture& furniture, short leftIndex, short frontIndex, short rightIndex, short backIndex ) { int chairCount = furniture.getType() == Level::Furniture::Desk ? mRand.gen(1, 2) : mRand.gen(1, 8 ); int gennedChairs = 0; int attempts = 0; float chairRoll = mRand.genNorm(); //If we fail the chair roll, don't generate any chairs if( chairRoll > mLevelRanges->rooms[ room.type ].furnitureChances[ Level::Furniture::Chair ] ){ return 0; } while( gennedChairs < chairCount ){ attempts++; if( attempts > WORLD_GEN_ATTEMPTS ){ break; } int side = mRand.gen(0, 4); int gX = 0; int gZ = 0; int yRot = mRand.gen(0, 4); switch( side ){ case 0: gX = leftIndex - 1; gZ = mRand.gen( frontIndex + 1, backIndex - 1 ); yRot = 2; break; case 1: gX = mRand.gen( leftIndex + 1, rightIndex - 1 ); gZ = frontIndex - 1; yRot = 1; break; case 2: gX = rightIndex + 1; gZ = mRand.gen( frontIndex + 1, backIndex - 1 ); yRot = 0; break; case 3: gX = mRand.gen( leftIndex + 1, rightIndex - 1 ); gZ = backIndex + 1; yRot = 3; break; default: break; } //If we are out of bounds of the room, try again if( gX < room.left || gX > room.right || gZ < room.top || gZ > room.bottom ){ continue; } Level::Furniture furniture; furniture.setType( Level::Furniture::Type::Chair ); //Position the furniture furniture.getPosition().x = ( static_cast<float>( gX ) * 0.3f ) + 0.15f; furniture.getPosition().z = ( static_cast<float>( gZ ) * 0.3f ) + 0.15f; furniture.getPosition().y = 0.0f; //Rotate the furniture furniture.setYRotation( static_cast<float>( yRot ) * ( 3.14159f / 2.0f ) ); float left, front, right, back; //Calculate bounding box level.getFurnitureAABoundingSquare( furniture, left, front, right, back ); //Convert to indices touched short iLeft = static_cast<short>( left / 0.3f ); short iFront = static_cast<short>( front / 0.3f ); short iRight = static_cast<short>( right / 0.3f ); short iBack = static_cast<short>( back / 0.3f ); //Make sure the area we want to set to furniture is clear if( !level.isRectOfBlocksOpen(iLeft, iRight, iFront, iBack) ){ continue; } ushort addedFurnitureIndex = level.addFurniture( furniture ); Level::Furniture* addedFurniture = &level.getFurniture( addedFurnitureIndex ); //Set the blocks in the touched indicies to be furniture blocks for(int i = iLeft; i <= iRight; i++){ for(int j = iFront; j <= iBack; j++){ level.getBlock( i, j ).setFurniture( addedFurniture ); } } if( !pathExistsToDoors( level, room ) ){ level.removeFurniture( addedFurnitureIndex ); for(int i = iLeft; i <= iRight; i++){ for(int j = iFront; j <= iBack; j++){ level.getBlock( i, j ).setOpen(); } } continue; } gennedChairs++; } return gennedChairs; }
void WorldGenerator::genLevelRoomFurniture( Level& level, Room& room, float blockDimension ) { float genFurnitureDensity = mLevelRanges->rooms[ room.type ].furnitureDensity.gen( mRand ); int furnitureCount = static_cast<int>(static_cast<float>((room.right - room.left) * (room.bottom - room.top)) * genFurnitureDensity); int gennedFurnitureBlocks = 0; int attempts = 0; while( gennedFurnitureBlocks < furnitureCount ){ Level::Furniture furniture; float furnitureRoll = mRand.genNorm(); float check = 0.0f; attempts++; if( attempts > WORLD_GEN_ATTEMPTS ){ break; } //Generate the type of furniture for(int i = Level::Furniture::Type::Desk; i < LEVEL_FURNITURE_TYPE_COUNT; i++){ check += mLevelRanges->rooms[ room.type ].furnitureChances[ i ]; if( furnitureRoll < check ){ furniture.setType( (Level::Furniture::Type)(i) ); break; } } //Gen position int gX = mRand.gen( room.left, room.right + 1 ); int gZ = mRand.gen( room.top, room.bottom + 1 ); //Gen rotation int yRot = mRand.gen( 0, 4 ); //TODO: Regenerate values against the wall if( furniture.getType() == Level::Furniture::Type::Desk ){ int wall = mRand.gen( 0, 4 ); int furnWidth = static_cast<int>( ( level.getFurnitureDimensions( Level::Furniture::Type::Desk ).x / 2.0f ) / blockDimension ); int furnDepth = static_cast<int>( ( level.getFurnitureDimensions( Level::Furniture::Type::Desk ).z / 2.0f ) / blockDimension ); switch( wall ){ case 0: gZ = room.top + furnDepth; gX = mRand.gen( room.left, room.right + 1 ); yRot = 3; break; case 1: gX = room.left + furnWidth; gZ = mRand.gen( room.top, room.bottom + 1 ); yRot = 0; break; case 2: gZ = room.bottom - furnDepth; gX = mRand.gen( room.left, room.right + 1 ); yRot = 1; break; case 3: gX = room.right - furnWidth; gZ = mRand.gen( room.top, room.bottom + 1 ); yRot = 2; break; default: break; } } //Position the furniture furniture.getPosition().x = ( static_cast<float>( gX ) * blockDimension ) + blockDimension / 2.0f; furniture.getPosition().z = ( static_cast<float>( gZ ) * blockDimension ) + blockDimension / 2.0f; furniture.getPosition().y = 0.0f; //Rotate the furniture furniture.setYRotation( static_cast<float>( yRot ) * ( 3.14159f / 2.0f ) ); float left, front, right, back; //Calculate bounding box level.getFurnitureAABoundingSquare( furniture, left, front, right, back ); //Convert to indices touched short iLeft = static_cast<short>( left / blockDimension ); short iFront = static_cast<short>( front / blockDimension ); short iRight = static_cast<short>( right / blockDimension ); short iBack = static_cast<short>( back / blockDimension ); //Make sure the area we want to set to furniture is clear if( !level.isRectOfBlocksOpen(iLeft, iRight, iFront, iBack) ){ continue; } ushort addedFurnitureIndex = level.addFurniture( furniture ); Level::Furniture* addedFurniture = &level.getFurniture( addedFurnitureIndex ); //Set the blocks in the touched indicies to be furniture blocks for(int i = iLeft; i <= iRight; i++){ for(int j = iFront; j <= iBack; j++){ level.getBlock( i, j ).setFurniture( addedFurniture ); } } //If there isn't a path, undo what we added if( !pathExistsToDoors( level, room ) ){ for(int i = iLeft; i <= iRight; i++){ for(int j = iFront; j <= iBack; j++){ level.getBlock( i, j ).setOpen(); } } level.removeFurniture( addedFurnitureIndex ); continue; } //Increment by furniture width * height gennedFurnitureBlocks += ( ( iRight - iLeft ) + 1 ) * ( ( iBack - iFront ) + 1); //Generate a chair if it is a table or desk if( furniture.getType() == Level::Furniture::Type::Table || furniture.getType() == Level::Furniture::Type::Desk ){ gennedFurnitureBlocks += genChairsByFurniture( level, room, furniture, iLeft, iFront, iRight, iBack ); } } }