2013-01-25 03:45:39 +00:00
/ *
GriefPrevention Server Plugin for Minecraft
Copyright ( C ) 2012 Ryan Hamshire
This program is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
* /
2020-06-09 04:57:55 +00:00
package me.ryanhamshire.GriefPrevention ;
2013-01-25 03:45:39 +00:00
import org.bukkit.Location ;
import org.bukkit.Material ;
2018-08-13 13:53:14 +00:00
import org.bukkit.Tag ;
2013-01-25 03:45:39 +00:00
import org.bukkit.World.Environment ;
import org.bukkit.block.Biome ;
2018-08-13 13:53:14 +00:00
import org.bukkit.block.data.Levelled ;
import org.bukkit.block.data.type.Leaves ;
2013-01-25 03:45:39 +00:00
import org.bukkit.entity.Player ;
2020-06-09 04:57:55 +00:00
import java.util.ArrayList ;
2013-01-25 03:45:39 +00:00
//non-main-thread task which processes world data to repair the unnatural
//after processing is complete, creates a main thread task to make the necessary changes to the world
2020-06-09 04:57:55 +00:00
class RestoreNatureProcessingTask implements Runnable
2013-01-25 03:45:39 +00:00
{
2020-06-09 04:57:55 +00:00
//world information captured from the main thread
//will be updated and sent back to main thread to be applied to the world
private BlockSnapshot [ ] [ ] [ ] snapshots ;
//other information collected from the main thread.
//not to be updated, only to be passed back to main thread to provide some context about the operation
private int miny ;
private Environment environment ;
private Location lesserBoundaryCorner ;
private Location greaterBoundaryCorner ;
private Player player ; //absolutely must not be accessed. not thread safe.
private Biome biome ;
private boolean creativeMode ;
private int seaLevel ;
private boolean aggressiveMode ;
//two lists of materials
private ArrayList < Material > notAllowedToHang ; //natural blocks which don't naturally hang in their air
private ArrayList < Material > playerBlocks ; //a "complete" list of player-placed blocks. MUST BE MAINTAINED as patches introduce more
2020-06-20 19:28:21 +00:00
2016-01-20 21:56:31 +00:00
public RestoreNatureProcessingTask ( BlockSnapshot [ ] [ ] [ ] snapshots , int miny , Environment environment , Biome biome , Location lesserBoundaryCorner , Location greaterBoundaryCorner , int seaLevel , boolean aggressiveMode , boolean creativeMode , Player player )
2020-06-09 04:57:55 +00:00
{
this . snapshots = snapshots ;
this . miny = miny ;
if ( this . miny < 0 ) this . miny = 0 ;
this . environment = environment ;
this . lesserBoundaryCorner = lesserBoundaryCorner ;
this . greaterBoundaryCorner = greaterBoundaryCorner ;
this . biome = biome ;
this . seaLevel = seaLevel ;
this . aggressiveMode = aggressiveMode ;
this . player = player ;
this . creativeMode = creativeMode ;
this . notAllowedToHang = new ArrayList < Material > ( ) ;
this . notAllowedToHang . add ( Material . DIRT ) ;
this . notAllowedToHang . add ( Material . GRASS ) ;
this . notAllowedToHang . add ( Material . SNOW ) ;
this . notAllowedToHang . add ( Material . OAK_LOG ) ;
this . notAllowedToHang . add ( Material . SPRUCE_LOG ) ;
this . notAllowedToHang . add ( Material . BIRCH_LOG ) ;
this . notAllowedToHang . add ( Material . JUNGLE_LOG ) ;
this . notAllowedToHang . add ( Material . ACACIA_LOG ) ;
this . notAllowedToHang . add ( Material . DARK_OAK_LOG ) ;
if ( this . aggressiveMode )
{
this . notAllowedToHang . add ( Material . GRASS ) ;
this . notAllowedToHang . add ( Material . STONE ) ;
}
this . playerBlocks = new ArrayList < Material > ( ) ;
this . playerBlocks . addAll ( RestoreNatureProcessingTask . getPlayerBlocks ( this . environment , this . biome ) ) ;
//in aggressive or creative world mode, also treat these blocks as user placed, to be removed
//this is helpful in the few cases where griefers intentionally use natural blocks to grief,
//like a single-block tower of iron ore or a giant penis constructed with melons
if ( this . aggressiveMode | | this . creativeMode )
{
this . playerBlocks . add ( Material . IRON_ORE ) ;
this . playerBlocks . add ( Material . GOLD_ORE ) ;
this . playerBlocks . add ( Material . DIAMOND_ORE ) ;
this . playerBlocks . add ( Material . MELON ) ;
this . playerBlocks . add ( Material . MELON_STEM ) ;
this . playerBlocks . add ( Material . BEDROCK ) ;
this . playerBlocks . add ( Material . COAL_ORE ) ;
this . playerBlocks . add ( Material . PUMPKIN ) ;
this . playerBlocks . add ( Material . PUMPKIN_STEM ) ;
}
if ( this . aggressiveMode )
{
this . playerBlocks . add ( Material . OAK_LEAVES ) ;
this . playerBlocks . add ( Material . SPRUCE_LEAVES ) ;
this . playerBlocks . add ( Material . BIRCH_LEAVES ) ;
this . playerBlocks . add ( Material . JUNGLE_LEAVES ) ;
this . playerBlocks . add ( Material . ACACIA_LEAVES ) ;
this . playerBlocks . add ( Material . DARK_OAK_LEAVES ) ;
this . playerBlocks . add ( Material . OAK_LOG ) ;
this . playerBlocks . add ( Material . SPRUCE_LOG ) ;
this . playerBlocks . add ( Material . BIRCH_LOG ) ;
this . playerBlocks . add ( Material . JUNGLE_LOG ) ;
this . playerBlocks . add ( Material . ACACIA_LOG ) ;
this . playerBlocks . add ( Material . DARK_OAK_LOG ) ;
this . playerBlocks . add ( Material . VINE ) ;
}
}
@Override
public void run ( )
{
//order is important!
//remove sandstone which appears to be unnatural
this . removeSandstone ( ) ;
//remove any blocks which are definitely player placed
this . removePlayerBlocks ( ) ;
//reduce large outcroppings of stone, sandstone
this . reduceStone ( ) ;
//reduce logs, except in jungle biomes
this . reduceLogs ( ) ;
//remove natural blocks which are unnaturally hanging in the air
this . removeHanging ( ) ;
//remove natural blocks which are unnaturally stacked high
this . removeWallsAndTowers ( ) ;
//fill unnatural thin trenches and single-block potholes
this . fillHolesAndTrenches ( ) ;
//fill water depressions and fix unnatural surface ripples
//this.fixWater();
//remove water/lava above sea level
this . removeDumpedFluids ( ) ;
//cover surface stone and gravel with sand or grass, as the biome requires
this . coverSurfaceStone ( ) ;
//remove any player-placed leaves
///this.removePlayerLeaves();
//schedule main thread task to apply the result to the world
RestoreNatureExecutionTask task = new RestoreNatureExecutionTask ( this . snapshots , this . miny , this . lesserBoundaryCorner , this . greaterBoundaryCorner , this . player ) ;
GriefPrevention . instance . getServer ( ) . getScheduler ( ) . scheduleSyncDelayedTask ( GriefPrevention . instance , task ) ;
}
2020-06-20 19:28:21 +00:00
2016-01-20 21:56:31 +00:00
private void removePlayerLeaves ( )
2020-06-09 04:57:55 +00:00
{
if ( this . seaLevel < 1 ) return ;
for ( int x = 1 ; x < snapshots . length - 1 ; x + + )
{
for ( int z = 1 ; z < snapshots [ 0 ] [ 0 ] . length - 1 ; z + + )
{
for ( int y = this . seaLevel - 1 ; y < snapshots [ 0 ] . length ; y + + )
{
BlockSnapshot block = snapshots [ x ] [ y ] [ z ] ;
if ( Tag . LEAVES . isTagged ( block . typeId ) & & ( ( Leaves ) block . data ) . isPersistent ( ) )
{
block . typeId = Material . AIR ;
}
}
}
}
}
//converts sandstone adjacent to sand to sand, and any other sandstone to air
2020-06-20 19:28:21 +00:00
2016-01-20 21:56:31 +00:00
private void removeSandstone ( )
2020-06-09 04:57:55 +00:00
{
for ( int x = 1 ; x < snapshots . length - 1 ; x + + )
{
for ( int z = 1 ; z < snapshots [ 0 ] [ 0 ] . length - 1 ; z + + )
{
for ( int y = snapshots [ 0 ] . length - 2 ; y > miny ; y - - )
{
if ( snapshots [ x ] [ y ] [ z ] . typeId ! = Material . SANDSTONE ) continue ;
BlockSnapshot leftBlock = this . snapshots [ x + 1 ] [ y ] [ z ] ;
BlockSnapshot rightBlock = this . snapshots [ x - 1 ] [ y ] [ z ] ;
BlockSnapshot upBlock = this . snapshots [ x ] [ y ] [ z + 1 ] ;
BlockSnapshot downBlock = this . snapshots [ x ] [ y ] [ z - 1 ] ;
BlockSnapshot underBlock = this . snapshots [ x ] [ y - 1 ] [ z ] ;
BlockSnapshot aboveBlock = this . snapshots [ x ] [ y + 1 ] [ z ] ;
//skip blocks which may cause a cave-in
if ( aboveBlock . typeId = = Material . SAND & & underBlock . typeId = = Material . AIR ) continue ;
//count adjacent non-air/non-leaf blocks
if ( leftBlock . typeId = = Material . SAND | |
rightBlock . typeId = = Material . SAND | |
upBlock . typeId = = Material . SAND | |
downBlock . typeId = = Material . SAND | |
aboveBlock . typeId = = Material . SAND | |
underBlock . typeId = = Material . SAND )
{
snapshots [ x ] [ y ] [ z ] . typeId = Material . SAND ;
2020-06-09 06:15:52 +00:00
}
else
2020-06-09 04:57:55 +00:00
{
snapshots [ x ] [ y ] [ z ] . typeId = Material . AIR ;
}
}
}
}
}
2020-06-20 19:28:21 +00:00
2016-01-20 21:56:31 +00:00
private void reduceStone ( )
2020-06-09 04:57:55 +00:00
{
if ( this . seaLevel < 1 ) return ;
for ( int x = 1 ; x < snapshots . length - 1 ; x + + )
{
for ( int z = 1 ; z < snapshots [ 0 ] [ 0 ] . length - 1 ; z + + )
{
int thisy = this . highestY ( x , z , true ) ;
while ( thisy > this . seaLevel - 1 & & ( this . snapshots [ x ] [ thisy ] [ z ] . typeId = = Material . STONE | | this . snapshots [ x ] [ thisy ] [ z ] . typeId = = Material . SANDSTONE ) )
{
BlockSnapshot leftBlock = this . snapshots [ x + 1 ] [ thisy ] [ z ] ;
BlockSnapshot rightBlock = this . snapshots [ x - 1 ] [ thisy ] [ z ] ;
BlockSnapshot upBlock = this . snapshots [ x ] [ thisy ] [ z + 1 ] ;
BlockSnapshot downBlock = this . snapshots [ x ] [ thisy ] [ z - 1 ] ;
//count adjacent non-air/non-leaf blocks
byte adjacentBlockCount = 0 ;
if ( leftBlock . typeId ! = Material . AIR & & ! Tag . LEAVES . isTagged ( leftBlock . typeId ) & & leftBlock . typeId ! = Material . VINE )
{
adjacentBlockCount + + ;
}
if ( rightBlock . typeId ! = Material . AIR & & ! Tag . LEAVES . isTagged ( rightBlock . typeId ) & & rightBlock . typeId ! = Material . VINE )
{
adjacentBlockCount + + ;
}
if ( downBlock . typeId ! = Material . AIR & & ! Tag . LEAVES . isTagged ( downBlock . typeId ) & & downBlock . typeId ! = Material . VINE )
{
adjacentBlockCount + + ;
}
if ( upBlock . typeId ! = Material . AIR & & ! Tag . LEAVES . isTagged ( upBlock . typeId ) & & upBlock . typeId ! = Material . VINE )
{
adjacentBlockCount + + ;
}
if ( adjacentBlockCount < 3 )
{
this . snapshots [ x ] [ thisy ] [ z ] . typeId = Material . AIR ;
}
thisy - - ;
}
}
}
}
2020-06-20 19:28:21 +00:00
2016-01-20 21:56:31 +00:00
private void reduceLogs ( )
2020-06-09 04:57:55 +00:00
{
if ( this . seaLevel < 1 ) return ;
boolean jungleBiome = this . biome = = Biome . JUNGLE | | this . biome = = Biome . JUNGLE_HILLS ;
//scan all blocks above sea level
for ( int x = 1 ; x < snapshots . length - 1 ; x + + )
{
for ( int z = 1 ; z < snapshots [ 0 ] [ 0 ] . length - 1 ; z + + )
{
for ( int y = this . seaLevel - 1 ; y < snapshots [ 0 ] . length ; y + + )
{
BlockSnapshot block = snapshots [ x ] [ y ] [ z ] ;
//skip non-logs
if ( ! Tag . LOGS . isTagged ( block . typeId ) ) continue ;
//if in jungle biome, skip jungle logs
if ( jungleBiome & & block . typeId = = Material . JUNGLE_LOG ) continue ;
//examine adjacent blocks for logs
BlockSnapshot leftBlock = this . snapshots [ x + 1 ] [ y ] [ z ] ;
BlockSnapshot rightBlock = this . snapshots [ x - 1 ] [ y ] [ z ] ;
BlockSnapshot upBlock = this . snapshots [ x ] [ y ] [ z + 1 ] ;
BlockSnapshot downBlock = this . snapshots [ x ] [ y ] [ z - 1 ] ;
//if any, remove the log
if ( Tag . LOGS . isTagged ( leftBlock . typeId ) | | Tag . LOGS . isTagged ( rightBlock . typeId ) | | Tag . LOGS . isTagged ( upBlock . typeId ) | | Tag . LOGS . isTagged ( downBlock . typeId ) )
{
this . snapshots [ x ] [ y ] [ z ] . typeId = Material . AIR ;
}
}
}
}
}
2020-06-20 19:28:21 +00:00
2016-01-20 21:56:31 +00:00
private void removePlayerBlocks ( )
2020-06-09 04:57:55 +00:00
{
int miny = this . miny ;
if ( miny < 1 ) miny = 1 ;
//remove all player blocks
for ( int x = 1 ; x < snapshots . length - 1 ; x + + )
{
for ( int z = 1 ; z < snapshots [ 0 ] [ 0 ] . length - 1 ; z + + )
{
for ( int y = miny ; y < snapshots [ 0 ] . length - 1 ; y + + )
{
BlockSnapshot block = snapshots [ x ] [ y ] [ z ] ;
if ( this . playerBlocks . contains ( block . typeId ) )
{
block . typeId = Material . AIR ;
}
}
}
}
}
2020-06-20 19:28:21 +00:00
2016-01-20 21:56:31 +00:00
private void removeHanging ( )
2020-06-09 04:57:55 +00:00
{
int miny = this . miny ;
if ( miny < 1 ) miny = 1 ;
for ( int x = 1 ; x < snapshots . length - 1 ; x + + )
{
for ( int z = 1 ; z < snapshots [ 0 ] [ 0 ] . length - 1 ; z + + )
{
for ( int y = miny ; y < snapshots [ 0 ] . length - 1 ; y + + )
{
BlockSnapshot block = snapshots [ x ] [ y ] [ z ] ;
BlockSnapshot underBlock = snapshots [ x ] [ y - 1 ] [ z ] ;
if ( underBlock . typeId = = Material . AIR | | underBlock . typeId = = Material . WATER | | Tag . LEAVES . isTagged ( underBlock . typeId ) )
{
if ( this . notAllowedToHang . contains ( block . typeId ) )
{
block . typeId = Material . AIR ;
}
}
}
}
}
}
2020-06-20 19:28:21 +00:00
2016-01-20 21:56:31 +00:00
private void removeWallsAndTowers ( )
2020-06-09 04:57:55 +00:00
{
Material [ ] excludedBlocksArray = new Material [ ]
{
Material . CACTUS ,
Material . GRASS ,
Material . RED_MUSHROOM ,
Material . BROWN_MUSHROOM ,
Material . DEAD_BUSH ,
Material . DANDELION ,
Material . POPPY ,
Material . ALLIUM ,
Material . BLUE_ORCHID ,
Material . AZURE_BLUET ,
Material . RED_TULIP ,
Material . ORANGE_TULIP ,
Material . WHITE_TULIP ,
Material . PINK_TULIP ,
Material . OXEYE_DAISY ,
Material . SUGAR_CANE ,
Material . VINE ,
Material . PUMPKIN ,
Material . LILY_PAD
} ;
ArrayList < Material > excludedBlocks = new ArrayList < Material > ( ) ;
for ( int i = 0 ; i < excludedBlocksArray . length ; i + + ) excludedBlocks . add ( excludedBlocksArray [ i ] ) ;
excludedBlocks . addAll ( Tag . SAPLINGS . getValues ( ) ) ;
excludedBlocks . addAll ( Tag . LEAVES . getValues ( ) ) ;
boolean changed ;
do
{
changed = false ;
for ( int x = 1 ; x < snapshots . length - 1 ; x + + )
{
for ( int z = 1 ; z < snapshots [ 0 ] [ 0 ] . length - 1 ; z + + )
{
int thisy = this . highestY ( x , z , false ) ;
if ( excludedBlocks . contains ( this . snapshots [ x ] [ thisy ] [ z ] . typeId ) ) continue ;
int righty = this . highestY ( x + 1 , z , false ) ;
int lefty = this . highestY ( x - 1 , z , false ) ;
while ( lefty < thisy & & righty < thisy )
{
this . snapshots [ x ] [ thisy - - ] [ z ] . typeId = Material . AIR ;
changed = true ;
}
int upy = this . highestY ( x , z + 1 , false ) ;
int downy = this . highestY ( x , z - 1 , false ) ;
while ( upy < thisy & & downy < thisy )
{
this . snapshots [ x ] [ thisy - - ] [ z ] . typeId = Material . AIR ;
changed = true ;
}
}
}
} while ( changed ) ;
}
2020-06-20 19:28:21 +00:00
2016-01-20 21:56:31 +00:00
private void coverSurfaceStone ( )
2020-06-09 04:57:55 +00:00
{
for ( int x = 1 ; x < snapshots . length - 1 ; x + + )
{
for ( int z = 1 ; z < snapshots [ 0 ] [ 0 ] . length - 1 ; z + + )
{
int y = this . highestY ( x , z , true ) ;
BlockSnapshot block = snapshots [ x ] [ y ] [ z ] ;
if ( block . typeId = = Material . STONE | | block . typeId = = Material . GRAVEL | | block . typeId = = Material . FARMLAND | | block . typeId = = Material . DIRT | | block . typeId = = Material . SANDSTONE )
{
if ( this . biome = = Biome . DESERT | | this . biome = = Biome . DESERT_HILLS | | this . biome = = Biome . BEACH )
{
this . snapshots [ x ] [ y ] [ z ] . typeId = Material . SAND ;
2020-06-09 06:15:52 +00:00
}
else
2020-06-09 04:57:55 +00:00
{
this . snapshots [ x ] [ y ] [ z ] . typeId = Material . GRASS_BLOCK ;
}
}
}
}
}
2020-06-20 19:28:21 +00:00
2016-01-20 21:56:31 +00:00
private void fillHolesAndTrenches ( )
2020-06-09 04:57:55 +00:00
{
ArrayList < Material > fillableBlocks = new ArrayList < Material > ( ) ;
fillableBlocks . add ( Material . AIR ) ;
fillableBlocks . add ( Material . WATER ) ;
fillableBlocks . add ( Material . LAVA ) ;
fillableBlocks . add ( Material . GRASS ) ;
ArrayList < Material > notSuitableForFillBlocks = new ArrayList < Material > ( ) ;
notSuitableForFillBlocks . add ( Material . GRASS ) ;
notSuitableForFillBlocks . add ( Material . CACTUS ) ;
notSuitableForFillBlocks . add ( Material . WATER ) ;
notSuitableForFillBlocks . add ( Material . LAVA ) ;
notSuitableForFillBlocks . addAll ( Tag . LOGS . getValues ( ) ) ;
boolean changed ;
do
{
changed = false ;
for ( int x = 1 ; x < snapshots . length - 1 ; x + + )
{
for ( int z = 1 ; z < snapshots [ 0 ] [ 0 ] . length - 1 ; z + + )
{
for ( int y = 0 ; y < snapshots [ 0 ] . length - 1 ; y + + )
{
BlockSnapshot block = this . snapshots [ x ] [ y ] [ z ] ;
if ( ! fillableBlocks . contains ( block . typeId ) ) continue ;
BlockSnapshot leftBlock = this . snapshots [ x + 1 ] [ y ] [ z ] ;
BlockSnapshot rightBlock = this . snapshots [ x - 1 ] [ y ] [ z ] ;
if ( ! fillableBlocks . contains ( leftBlock . typeId ) & & ! fillableBlocks . contains ( rightBlock . typeId ) )
{
if ( ! notSuitableForFillBlocks . contains ( rightBlock . typeId ) )
{
block . typeId = rightBlock . typeId ;
changed = true ;
}
}
BlockSnapshot upBlock = this . snapshots [ x ] [ y ] [ z + 1 ] ;
BlockSnapshot downBlock = this . snapshots [ x ] [ y ] [ z - 1 ] ;
if ( ! fillableBlocks . contains ( upBlock . typeId ) & & ! fillableBlocks . contains ( downBlock . typeId ) )
{
if ( ! notSuitableForFillBlocks . contains ( downBlock . typeId ) )
{
block . typeId = downBlock . typeId ;
changed = true ;
}
}
}
}
}
} while ( changed ) ;
}
2020-06-20 19:28:21 +00:00
2016-01-20 21:56:31 +00:00
private void fixWater ( )
2020-06-09 04:57:55 +00:00
{
int miny = this . miny ;
if ( miny < 1 ) miny = 1 ;
boolean changed ;
//remove hanging water or lava
for ( int x = 1 ; x < snapshots . length - 1 ; x + + )
{
for ( int z = 1 ; z < snapshots [ 0 ] [ 0 ] . length - 1 ; z + + )
{
for ( int y = miny ; y < snapshots [ 0 ] . length - 1 ; y + + )
{
BlockSnapshot block = this . snapshots [ x ] [ y ] [ z ] ;
BlockSnapshot underBlock = this . snapshots [ x ] [ y - - ] [ z ] ;
if ( block . typeId = = Material . WATER | | block . typeId = = Material . LAVA )
{
// check if block below is air or is a non-source fluid block (level 1-7 = flowing, 8 = falling)
if ( underBlock . typeId = = Material . AIR | | ( underBlock . typeId = = Material . WATER & & ( ( ( Levelled ) underBlock . data ) . getLevel ( ) ! = 0 ) ) )
{
block . typeId = Material . AIR ;
}
}
}
}
}
//fill water depressions
do
{
changed = false ;
for ( int y = Math . max ( this . seaLevel - 10 , 0 ) ; y < = this . seaLevel ; y + + )
{
for ( int x = 1 ; x < snapshots . length - 1 ; x + + )
{
for ( int z = 1 ; z < snapshots [ 0 ] [ 0 ] . length - 1 ; z + + )
{
BlockSnapshot block = snapshots [ x ] [ y ] [ z ] ;
//only consider air blocks and flowing water blocks for upgrade to water source blocks
if ( block . typeId = = Material . AIR | | ( block . typeId = = Material . WATER & & ( ( Levelled ) block . data ) . getLevel ( ) ! = 0 ) )
{
BlockSnapshot leftBlock = this . snapshots [ x + 1 ] [ y ] [ z ] ;
BlockSnapshot rightBlock = this . snapshots [ x - 1 ] [ y ] [ z ] ;
BlockSnapshot upBlock = this . snapshots [ x ] [ y ] [ z + 1 ] ;
BlockSnapshot downBlock = this . snapshots [ x ] [ y ] [ z - 1 ] ;
BlockSnapshot underBlock = this . snapshots [ x ] [ y - 1 ] [ z ] ;
//block underneath MUST be source water
if ( ! ( underBlock . typeId = = Material . WATER & & ( ( Levelled ) underBlock . data ) . getLevel ( ) = = 0 ) )
continue ;
//count adjacent source water blocks
byte adjacentSourceWaterCount = 0 ;
if ( leftBlock . typeId = = Material . WATER & & ( ( Levelled ) leftBlock . data ) . getLevel ( ) = = 0 )
{
adjacentSourceWaterCount + + ;
}
if ( rightBlock . typeId = = Material . WATER & & ( ( Levelled ) rightBlock . data ) . getLevel ( ) = = 0 )
{
adjacentSourceWaterCount + + ;
}
if ( upBlock . typeId = = Material . WATER & & ( ( Levelled ) upBlock . data ) . getLevel ( ) = = 0 )
{
adjacentSourceWaterCount + + ;
}
if ( downBlock . typeId = = Material . WATER & & ( ( Levelled ) downBlock . data ) . getLevel ( ) = = 0 )
{
adjacentSourceWaterCount + + ;
}
//at least two adjacent blocks must be source water
if ( adjacentSourceWaterCount > = 2 )
{
block . typeId = Material . WATER ;
( ( Levelled ) downBlock . data ) . setLevel ( 0 ) ;
changed = true ;
}
}
}
}
}
} while ( changed ) ;
}
2020-06-20 19:28:21 +00:00
2016-01-20 21:56:31 +00:00
private void removeDumpedFluids ( )
2020-06-09 04:57:55 +00:00
{
if ( this . seaLevel < 1 ) return ;
//remove any surface water or lava above sea level, presumed to be placed by players
//sometimes, this is naturally generated. but replacing it is very easy with a bucket, so overall this is a good plan
if ( this . environment = = Environment . NETHER ) return ;
for ( int x = 1 ; x < snapshots . length - 1 ; x + + )
{
for ( int z = 1 ; z < snapshots [ 0 ] [ 0 ] . length - 1 ; z + + )
{
for ( int y = this . seaLevel - 1 ; y < snapshots [ 0 ] . length - 1 ; y + + )
{
BlockSnapshot block = snapshots [ x ] [ y ] [ z ] ;
if ( block . typeId = = Material . WATER | | block . typeId = = Material . LAVA )
{
block . typeId = Material . AIR ;
}
}
}
}
}
2020-06-20 19:28:21 +00:00
2020-06-09 04:57:55 +00:00
private int highestY ( int x , int z , boolean ignoreLeaves )
{
int y ;
for ( y = snapshots [ 0 ] . length - 1 ; y > 0 ; y - - )
{
BlockSnapshot block = this . snapshots [ x ] [ y ] [ z ] ;
if ( block . typeId ! = Material . AIR & &
! ( ignoreLeaves & & block . typeId = = Material . SNOW ) & &
! ( ignoreLeaves & & Tag . LEAVES . isTagged ( block . typeId ) ) & &
! ( block . typeId = = Material . WATER ) & &
! ( block . typeId = = Material . LAVA ) )
{
return y ;
}
}
return y ;
}
2020-06-20 19:28:21 +00:00
2020-06-09 04:57:55 +00:00
static ArrayList < Material > getPlayerBlocks ( Environment environment , Biome biome )
{
//NOTE on this list. why not make a list of natural blocks?
//answer: better to leave a few player blocks than to remove too many natural blocks. remember we're "restoring nature"
//a few extra player blocks can be manually removed, but it will be impossible to guess exactly which natural materials to use in manual repair of an overzealous block removal
ArrayList < Material > playerBlocks = new ArrayList < Material > ( ) ;
playerBlocks . add ( Material . FIRE ) ;
playerBlocks . add ( Material . WHITE_BED ) ;
playerBlocks . add ( Material . ORANGE_BED ) ;
playerBlocks . add ( Material . MAGENTA_BED ) ;
playerBlocks . add ( Material . LIGHT_BLUE_BED ) ;
playerBlocks . add ( Material . YELLOW_BED ) ;
playerBlocks . add ( Material . LIME_BED ) ;
playerBlocks . add ( Material . PINK_BED ) ;
playerBlocks . add ( Material . GRAY_BED ) ;
playerBlocks . add ( Material . LIGHT_GRAY_BED ) ;
playerBlocks . add ( Material . CYAN_BED ) ;
playerBlocks . add ( Material . PURPLE_BED ) ;
playerBlocks . add ( Material . BLUE_BED ) ;
playerBlocks . add ( Material . BROWN_BED ) ;
playerBlocks . add ( Material . GREEN_BED ) ;
playerBlocks . add ( Material . RED_BED ) ;
playerBlocks . add ( Material . BLACK_BED ) ;
playerBlocks . add ( Material . OAK_PLANKS ) ;
playerBlocks . add ( Material . SPRUCE_PLANKS ) ;
playerBlocks . add ( Material . BIRCH_PLANKS ) ;
playerBlocks . add ( Material . JUNGLE_PLANKS ) ;
playerBlocks . add ( Material . ACACIA_PLANKS ) ;
playerBlocks . add ( Material . DARK_OAK_PLANKS ) ;
playerBlocks . add ( Material . BOOKSHELF ) ;
playerBlocks . add ( Material . BREWING_STAND ) ;
playerBlocks . add ( Material . BRICK ) ;
playerBlocks . add ( Material . COBBLESTONE ) ;
playerBlocks . add ( Material . GLASS ) ;
playerBlocks . add ( Material . LAPIS_BLOCK ) ;
playerBlocks . add ( Material . DISPENSER ) ;
playerBlocks . add ( Material . NOTE_BLOCK ) ;
playerBlocks . add ( Material . POWERED_RAIL ) ;
playerBlocks . add ( Material . DETECTOR_RAIL ) ;
playerBlocks . add ( Material . STICKY_PISTON ) ;
playerBlocks . add ( Material . PISTON ) ;
playerBlocks . add ( Material . PISTON_HEAD ) ;
playerBlocks . add ( Material . MOVING_PISTON ) ;
playerBlocks . add ( Material . WHITE_WOOL ) ;
playerBlocks . add ( Material . ORANGE_WOOL ) ;
playerBlocks . add ( Material . MAGENTA_WOOL ) ;
playerBlocks . add ( Material . LIGHT_BLUE_WOOL ) ;
playerBlocks . add ( Material . YELLOW_WOOL ) ;
playerBlocks . add ( Material . LIME_WOOL ) ;
playerBlocks . add ( Material . PINK_WOOL ) ;
playerBlocks . add ( Material . GRAY_WOOL ) ;
playerBlocks . add ( Material . LIGHT_GRAY_WOOL ) ;
playerBlocks . add ( Material . CYAN_WOOL ) ;
playerBlocks . add ( Material . PURPLE_WOOL ) ;
playerBlocks . add ( Material . BLUE_WOOL ) ;
playerBlocks . add ( Material . BROWN_WOOL ) ;
playerBlocks . add ( Material . GREEN_WOOL ) ;
playerBlocks . add ( Material . RED_WOOL ) ;
playerBlocks . add ( Material . BLACK_WOOL ) ;
playerBlocks . add ( Material . GOLD_BLOCK ) ;
playerBlocks . add ( Material . IRON_BLOCK ) ;
playerBlocks . add ( Material . OAK_SLAB ) ;
playerBlocks . add ( Material . SPRUCE_SLAB ) ;
playerBlocks . add ( Material . BIRCH_SLAB ) ;
playerBlocks . add ( Material . JUNGLE_SLAB ) ;
playerBlocks . add ( Material . ACACIA_SLAB ) ;
playerBlocks . add ( Material . DARK_OAK_SLAB ) ;
playerBlocks . add ( Material . STONE_SLAB ) ;
playerBlocks . add ( Material . SANDSTONE_SLAB ) ;
playerBlocks . add ( Material . PETRIFIED_OAK_SLAB ) ;
playerBlocks . add ( Material . COBBLESTONE_SLAB ) ;
playerBlocks . add ( Material . BRICK_SLAB ) ;
playerBlocks . add ( Material . STONE_BRICK_SLAB ) ;
playerBlocks . add ( Material . NETHER_BRICK_SLAB ) ;
playerBlocks . add ( Material . QUARTZ_SLAB ) ;
playerBlocks . add ( Material . RED_SANDSTONE_SLAB ) ;
playerBlocks . add ( Material . PURPUR_SLAB ) ;
playerBlocks . add ( Material . PRISMARINE_SLAB ) ;
playerBlocks . add ( Material . PRISMARINE_BRICK_SLAB ) ;
playerBlocks . add ( Material . DARK_PRISMARINE_SLAB ) ;
playerBlocks . add ( Material . WHEAT ) ;
playerBlocks . add ( Material . TNT ) ;
playerBlocks . add ( Material . MOSSY_COBBLESTONE ) ;
playerBlocks . add ( Material . TORCH ) ;
playerBlocks . add ( Material . FIRE ) ;
playerBlocks . add ( Material . OAK_STAIRS ) ;
playerBlocks . add ( Material . SPRUCE_STAIRS ) ;
playerBlocks . add ( Material . BIRCH_STAIRS ) ;
playerBlocks . add ( Material . JUNGLE_STAIRS ) ;
playerBlocks . add ( Material . ACACIA_STAIRS ) ;
playerBlocks . add ( Material . DARK_OAK_STAIRS ) ;
playerBlocks . add ( Material . CHEST ) ;
playerBlocks . add ( Material . REDSTONE_WIRE ) ;
playerBlocks . add ( Material . DIAMOND_BLOCK ) ;
playerBlocks . add ( Material . CRAFTING_TABLE ) ;
playerBlocks . add ( Material . FURNACE ) ;
playerBlocks . add ( Material . OAK_DOOR ) ;
playerBlocks . add ( Material . ACACIA_SIGN ) ;
playerBlocks . addAll ( Tag . SIGNS . getValues ( ) ) ;
playerBlocks . addAll ( Tag . WALL_SIGNS . getValues ( ) ) ;
playerBlocks . add ( Material . LADDER ) ;
playerBlocks . add ( Material . RAIL ) ;
playerBlocks . add ( Material . COBBLESTONE_STAIRS ) ;
playerBlocks . add ( Material . STONE_PRESSURE_PLATE ) ;
playerBlocks . add ( Material . LEVER ) ;
playerBlocks . add ( Material . IRON_DOOR ) ;
playerBlocks . add ( Material . OAK_PRESSURE_PLATE ) ;
playerBlocks . add ( Material . SPRUCE_PRESSURE_PLATE ) ;
playerBlocks . add ( Material . BIRCH_PRESSURE_PLATE ) ;
playerBlocks . add ( Material . JUNGLE_PRESSURE_PLATE ) ;
playerBlocks . add ( Material . ACACIA_PRESSURE_PLATE ) ;
playerBlocks . add ( Material . DARK_OAK_PRESSURE_PLATE ) ;
playerBlocks . add ( Material . REDSTONE_TORCH ) ;
playerBlocks . add ( Material . STONE_BUTTON ) ;
playerBlocks . add ( Material . SNOW_BLOCK ) ;
playerBlocks . add ( Material . JUKEBOX ) ;
playerBlocks . add ( Material . OAK_FENCE ) ;
playerBlocks . add ( Material . SPRUCE_FENCE ) ;
playerBlocks . add ( Material . BIRCH_FENCE ) ;
playerBlocks . add ( Material . JUNGLE_FENCE ) ;
playerBlocks . add ( Material . ACACIA_FENCE ) ;
playerBlocks . add ( Material . DARK_OAK_FENCE ) ;
playerBlocks . add ( Material . NETHER_PORTAL ) ;
playerBlocks . add ( Material . JACK_O_LANTERN ) ;
playerBlocks . add ( Material . CAKE ) ;
playerBlocks . add ( Material . REPEATER ) ;
playerBlocks . add ( Material . OAK_TRAPDOOR ) ;
playerBlocks . add ( Material . SPRUCE_TRAPDOOR ) ;
playerBlocks . add ( Material . BIRCH_TRAPDOOR ) ;
playerBlocks . add ( Material . JUNGLE_TRAPDOOR ) ;
playerBlocks . add ( Material . ACACIA_TRAPDOOR ) ;
playerBlocks . add ( Material . DARK_OAK_TRAPDOOR ) ;
playerBlocks . add ( Material . STONE_BRICKS ) ;
playerBlocks . add ( Material . MOSSY_STONE_BRICKS ) ;
playerBlocks . add ( Material . CRACKED_STONE_BRICKS ) ;
playerBlocks . add ( Material . CHISELED_STONE_BRICKS ) ;
playerBlocks . add ( Material . MUSHROOM_STEM ) ;
playerBlocks . add ( Material . RED_MUSHROOM_BLOCK ) ;
playerBlocks . add ( Material . BROWN_MUSHROOM_BLOCK ) ;
playerBlocks . add ( Material . IRON_BARS ) ;
playerBlocks . add ( Material . GLASS_PANE ) ;
playerBlocks . add ( Material . MELON_STEM ) ;
playerBlocks . add ( Material . OAK_FENCE_GATE ) ;
playerBlocks . add ( Material . SPRUCE_FENCE_GATE ) ;
playerBlocks . add ( Material . BIRCH_FENCE_GATE ) ;
playerBlocks . add ( Material . JUNGLE_FENCE_GATE ) ;
playerBlocks . add ( Material . ACACIA_FENCE_GATE ) ;
playerBlocks . add ( Material . DARK_OAK_FENCE_GATE ) ;
playerBlocks . add ( Material . BRICK_STAIRS ) ;
playerBlocks . add ( Material . ENCHANTING_TABLE ) ;
playerBlocks . add ( Material . BREWING_STAND ) ;
playerBlocks . add ( Material . CAULDRON ) ;
playerBlocks . add ( Material . COBWEB ) ;
playerBlocks . add ( Material . SPONGE ) ;
playerBlocks . add ( Material . GRAVEL ) ;
playerBlocks . add ( Material . EMERALD_BLOCK ) ;
playerBlocks . add ( Material . SANDSTONE ) ;
playerBlocks . add ( Material . ENDER_CHEST ) ;
playerBlocks . add ( Material . SANDSTONE_STAIRS ) ;
playerBlocks . add ( Material . COMMAND_BLOCK ) ;
playerBlocks . add ( Material . REPEATING_COMMAND_BLOCK ) ;
playerBlocks . add ( Material . CHAIN_COMMAND_BLOCK ) ;
playerBlocks . add ( Material . BEACON ) ;
playerBlocks . add ( Material . COBBLESTONE_WALL ) ;
playerBlocks . add ( Material . MOSSY_COBBLESTONE_WALL ) ;
playerBlocks . add ( Material . FLOWER_POT ) ;
playerBlocks . add ( Material . CARROT ) ;
playerBlocks . add ( Material . POTATO ) ;
playerBlocks . add ( Material . OAK_BUTTON ) ;
playerBlocks . add ( Material . SPRUCE_BUTTON ) ;
playerBlocks . add ( Material . BIRCH_BUTTON ) ;
playerBlocks . add ( Material . JUNGLE_BUTTON ) ;
playerBlocks . add ( Material . ACACIA_BUTTON ) ;
playerBlocks . add ( Material . DARK_OAK_BUTTON ) ;
playerBlocks . add ( Material . SKELETON_SKULL ) ;
playerBlocks . add ( Material . WITHER_SKELETON_SKULL ) ;
playerBlocks . add ( Material . CREEPER_HEAD ) ;
playerBlocks . add ( Material . ZOMBIE_HEAD ) ;
playerBlocks . add ( Material . PLAYER_HEAD ) ;
playerBlocks . add ( Material . DRAGON_HEAD ) ;
playerBlocks . add ( Material . ANVIL ) ;
playerBlocks . add ( Material . SPONGE ) ;
playerBlocks . add ( Material . WHITE_STAINED_GLASS ) ;
playerBlocks . add ( Material . ORANGE_STAINED_GLASS ) ;
playerBlocks . add ( Material . MAGENTA_STAINED_GLASS ) ;
playerBlocks . add ( Material . LIGHT_BLUE_STAINED_GLASS ) ;
playerBlocks . add ( Material . YELLOW_STAINED_GLASS ) ;
playerBlocks . add ( Material . LIME_STAINED_GLASS ) ;
playerBlocks . add ( Material . PINK_STAINED_GLASS ) ;
playerBlocks . add ( Material . GRAY_STAINED_GLASS ) ;
playerBlocks . add ( Material . LIGHT_GRAY_STAINED_GLASS ) ;
playerBlocks . add ( Material . CYAN_STAINED_GLASS ) ;
playerBlocks . add ( Material . PURPLE_STAINED_GLASS ) ;
playerBlocks . add ( Material . BLUE_STAINED_GLASS ) ;
playerBlocks . add ( Material . BROWN_STAINED_GLASS ) ;
playerBlocks . add ( Material . GREEN_STAINED_GLASS ) ;
playerBlocks . add ( Material . RED_STAINED_GLASS ) ;
playerBlocks . add ( Material . BLACK_STAINED_GLASS ) ;
playerBlocks . add ( Material . WHITE_STAINED_GLASS_PANE ) ;
playerBlocks . add ( Material . ORANGE_STAINED_GLASS_PANE ) ;
playerBlocks . add ( Material . MAGENTA_STAINED_GLASS_PANE ) ;
playerBlocks . add ( Material . LIGHT_BLUE_STAINED_GLASS_PANE ) ;
playerBlocks . add ( Material . YELLOW_STAINED_GLASS_PANE ) ;
playerBlocks . add ( Material . LIME_STAINED_GLASS_PANE ) ;
playerBlocks . add ( Material . PINK_STAINED_GLASS_PANE ) ;
playerBlocks . add ( Material . GRAY_STAINED_GLASS_PANE ) ;
playerBlocks . add ( Material . LIGHT_GRAY_STAINED_GLASS_PANE ) ;
playerBlocks . add ( Material . CYAN_STAINED_GLASS_PANE ) ;
playerBlocks . add ( Material . PURPLE_STAINED_GLASS_PANE ) ;
playerBlocks . add ( Material . BLUE_STAINED_GLASS_PANE ) ;
playerBlocks . add ( Material . BROWN_STAINED_GLASS_PANE ) ;
playerBlocks . add ( Material . GREEN_STAINED_GLASS_PANE ) ;
playerBlocks . add ( Material . RED_STAINED_GLASS_PANE ) ;
playerBlocks . add ( Material . BLACK_STAINED_GLASS_PANE ) ;
playerBlocks . add ( Material . WHITE_BANNER ) ;
playerBlocks . add ( Material . ORANGE_BANNER ) ;
playerBlocks . add ( Material . MAGENTA_BANNER ) ;
playerBlocks . add ( Material . LIGHT_BLUE_BANNER ) ;
playerBlocks . add ( Material . YELLOW_BANNER ) ;
playerBlocks . add ( Material . LIME_BANNER ) ;
playerBlocks . add ( Material . PINK_BANNER ) ;
playerBlocks . add ( Material . GRAY_BANNER ) ;
playerBlocks . add ( Material . LIGHT_GRAY_BANNER ) ;
playerBlocks . add ( Material . CYAN_BANNER ) ;
playerBlocks . add ( Material . PURPLE_BANNER ) ;
playerBlocks . add ( Material . BLUE_BANNER ) ;
playerBlocks . add ( Material . BROWN_BANNER ) ;
playerBlocks . add ( Material . GREEN_BANNER ) ;
playerBlocks . add ( Material . RED_BANNER ) ;
playerBlocks . add ( Material . BLACK_BANNER ) ;
playerBlocks . add ( Material . TRAPPED_CHEST ) ;
playerBlocks . add ( Material . LIGHT_WEIGHTED_PRESSURE_PLATE ) ;
playerBlocks . add ( Material . HEAVY_WEIGHTED_PRESSURE_PLATE ) ;
playerBlocks . add ( Material . COMPARATOR ) ;
playerBlocks . add ( Material . DAYLIGHT_DETECTOR ) ;
playerBlocks . add ( Material . REDSTONE_BLOCK ) ;
playerBlocks . add ( Material . HOPPER ) ;
playerBlocks . add ( Material . QUARTZ_BLOCK ) ;
playerBlocks . add ( Material . QUARTZ_STAIRS ) ;
playerBlocks . add ( Material . DROPPER ) ;
playerBlocks . add ( Material . SLIME_BLOCK ) ;
playerBlocks . add ( Material . IRON_TRAPDOOR ) ;
playerBlocks . add ( Material . PRISMARINE ) ;
playerBlocks . add ( Material . HAY_BLOCK ) ;
playerBlocks . add ( Material . WHITE_CARPET ) ;
playerBlocks . add ( Material . ORANGE_CARPET ) ;
playerBlocks . add ( Material . MAGENTA_CARPET ) ;
playerBlocks . add ( Material . LIGHT_BLUE_CARPET ) ;
playerBlocks . add ( Material . YELLOW_CARPET ) ;
playerBlocks . add ( Material . LIME_CARPET ) ;
playerBlocks . add ( Material . PINK_CARPET ) ;
playerBlocks . add ( Material . GRAY_CARPET ) ;
playerBlocks . add ( Material . LIGHT_GRAY_CARPET ) ;
playerBlocks . add ( Material . CYAN_CARPET ) ;
playerBlocks . add ( Material . PURPLE_CARPET ) ;
playerBlocks . add ( Material . BLUE_CARPET ) ;
playerBlocks . add ( Material . BROWN_CARPET ) ;
playerBlocks . add ( Material . GREEN_CARPET ) ;
playerBlocks . add ( Material . RED_CARPET ) ;
playerBlocks . add ( Material . BLACK_CARPET ) ;
playerBlocks . add ( Material . SEA_LANTERN ) ;
playerBlocks . add ( Material . RED_SANDSTONE_STAIRS ) ;
playerBlocks . add ( Material . ACACIA_FENCE ) ;
playerBlocks . add ( Material . ACACIA_FENCE_GATE ) ;
playerBlocks . add ( Material . BIRCH_FENCE ) ;
playerBlocks . add ( Material . BIRCH_FENCE_GATE ) ;
playerBlocks . add ( Material . DARK_OAK_FENCE ) ;
playerBlocks . add ( Material . DARK_OAK_FENCE_GATE ) ;
playerBlocks . add ( Material . JUNGLE_FENCE ) ;
playerBlocks . add ( Material . JUNGLE_FENCE_GATE ) ;
playerBlocks . add ( Material . SPRUCE_FENCE ) ;
playerBlocks . add ( Material . SPRUCE_FENCE_GATE ) ;
playerBlocks . add ( Material . ACACIA_DOOR ) ;
playerBlocks . add ( Material . SPRUCE_DOOR ) ;
playerBlocks . add ( Material . DARK_OAK_DOOR ) ;
playerBlocks . add ( Material . JUNGLE_DOOR ) ;
playerBlocks . add ( Material . BIRCH_DOOR ) ;
playerBlocks . add ( Material . COAL_BLOCK ) ;
playerBlocks . add ( Material . REDSTONE_LAMP ) ;
playerBlocks . add ( Material . PURPUR_BLOCK ) ;
playerBlocks . add ( Material . PURPUR_SLAB ) ;
playerBlocks . add ( Material . PURPUR_PILLAR ) ;
playerBlocks . add ( Material . PURPUR_STAIRS ) ;
playerBlocks . add ( Material . NETHER_WART_BLOCK ) ;
playerBlocks . add ( Material . RED_NETHER_BRICKS ) ;
playerBlocks . add ( Material . BONE_BLOCK ) ;
//these are unnatural in the standard world, but not in the nether
if ( environment ! = Environment . NETHER )
{
playerBlocks . add ( Material . NETHERRACK ) ;
playerBlocks . add ( Material . SOUL_SAND ) ;
2020-07-03 03:24:18 +00:00
playerBlocks . add ( Material . SOUL_SOIL ) ;
2020-06-09 04:57:55 +00:00
playerBlocks . add ( Material . GLOWSTONE ) ;
playerBlocks . add ( Material . NETHER_BRICK ) ;
playerBlocks . add ( Material . NETHER_BRICK_FENCE ) ;
playerBlocks . add ( Material . NETHER_BRICK_STAIRS ) ;
playerBlocks . add ( Material . MAGMA_BLOCK ) ;
2020-07-03 03:24:18 +00:00
playerBlocks . add ( Material . ANCIENT_DEBRIS ) ;
playerBlocks . add ( Material . BASALT ) ;
playerBlocks . add ( Material . BLACKSTONE ) ;
playerBlocks . add ( Material . GILDED_BLACKSTONE ) ;
playerBlocks . add ( Material . CHAIN ) ;
playerBlocks . add ( Material . SHROOMLIGHT ) ;
playerBlocks . add ( Material . NETHER_GOLD_ORE ) ;
playerBlocks . add ( Material . NETHER_SPROUTS ) ;
playerBlocks . add ( Material . CRIMSON_FUNGUS ) ;
playerBlocks . add ( Material . CRIMSON_NYLIUM ) ;
playerBlocks . add ( Material . CRIMSON_ROOTS ) ;
playerBlocks . add ( Material . CRIMSON_STEM ) ;
playerBlocks . add ( Material . NETHER_WART_BLOCK ) ;
playerBlocks . add ( Material . WEEPING_VINES ) ;
playerBlocks . add ( Material . WEEPING_VINES_PLANT ) ;
playerBlocks . add ( Material . WARPED_FUNGUS ) ;
playerBlocks . add ( Material . WARPED_NYLIUM ) ;
playerBlocks . add ( Material . WARPED_ROOTS ) ;
playerBlocks . add ( Material . WARPED_STEM ) ;
playerBlocks . add ( Material . WARPED_WART_BLOCK ) ;
playerBlocks . add ( Material . TWISTING_VINES ) ;
playerBlocks . add ( Material . TWISTING_VINES_PLANT ) ;
2020-06-09 04:57:55 +00:00
}
//these are unnatural in the standard and nether worlds, but not in the end
if ( environment ! = Environment . THE_END )
{
playerBlocks . add ( Material . OBSIDIAN ) ;
playerBlocks . add ( Material . END_STONE ) ;
playerBlocks . add ( Material . END_PORTAL_FRAME ) ;
playerBlocks . add ( Material . CHORUS_PLANT ) ;
playerBlocks . add ( Material . CHORUS_FLOWER ) ;
}
//these are unnatural in sandy biomes, but not elsewhere
if ( biome = = Biome . DESERT | | biome = = Biome . DESERT_HILLS | | biome = = Biome . BEACH | | environment ! = Environment . NORMAL )
{
playerBlocks . add ( Material . OAK_LEAVES ) ;
playerBlocks . add ( Material . SPRUCE_LEAVES ) ;
playerBlocks . add ( Material . BIRCH_LEAVES ) ;
playerBlocks . add ( Material . JUNGLE_LEAVES ) ;
playerBlocks . add ( Material . ACACIA_LEAVES ) ;
playerBlocks . add ( Material . DARK_OAK_LEAVES ) ;
playerBlocks . add ( Material . OAK_LOG ) ;
playerBlocks . add ( Material . SPRUCE_LOG ) ;
playerBlocks . add ( Material . BIRCH_LOG ) ;
playerBlocks . add ( Material . JUNGLE_LOG ) ;
playerBlocks . add ( Material . ACACIA_LOG ) ;
playerBlocks . add ( Material . DARK_OAK_LOG ) ;
}
return playerBlocks ;
}
2013-01-25 03:45:39 +00:00
}