More blocks added, adjustments for initialization.
Chests are treated as single chests always, so there is a little potential for interaction getting through (blockinteract.visible). Snow is just treated as before, data-based height adjustment (to be added as a model, as Bukkit supports getting the level in a generic way, same for water).
This commit is contained in:
parent
cbc5d3b4aa
commit
9d37763264
|
@ -27,6 +27,7 @@ import fr.neatmonster.nocheatplus.compat.bukkit.model.BukkitShapeModel;
|
||||||
import fr.neatmonster.nocheatplus.compat.bukkit.model.BukkitShulkerBox;
|
import fr.neatmonster.nocheatplus.compat.bukkit.model.BukkitShulkerBox;
|
||||||
import fr.neatmonster.nocheatplus.compat.bukkit.model.BukkitSlab;
|
import fr.neatmonster.nocheatplus.compat.bukkit.model.BukkitSlab;
|
||||||
import fr.neatmonster.nocheatplus.compat.bukkit.model.BukkitStairs;
|
import fr.neatmonster.nocheatplus.compat.bukkit.model.BukkitStairs;
|
||||||
|
import fr.neatmonster.nocheatplus.compat.bukkit.model.BukkitStatic;
|
||||||
import fr.neatmonster.nocheatplus.config.WorldConfigProvider;
|
import fr.neatmonster.nocheatplus.config.WorldConfigProvider;
|
||||||
import fr.neatmonster.nocheatplus.utilities.map.BlockCache;
|
import fr.neatmonster.nocheatplus.utilities.map.BlockCache;
|
||||||
import fr.neatmonster.nocheatplus.utilities.map.BlockFlags;
|
import fr.neatmonster.nocheatplus.utilities.map.BlockFlags;
|
||||||
|
@ -37,15 +38,46 @@ public class MCAccessBukkitModern extends MCAccessBukkit {
|
||||||
|
|
||||||
protected final Map<Material, BukkitShapeModel> shapeModels = new HashMap<Material, BukkitShapeModel>();
|
protected final Map<Material, BukkitShapeModel> shapeModels = new HashMap<Material, BukkitShapeModel>();
|
||||||
|
|
||||||
|
// Blocks that change shape based on interaction or redstone.
|
||||||
|
private static final BukkitShapeModel MODEL_GATE = new BukkitGate(
|
||||||
|
0.375, 1.5);
|
||||||
|
private static final BukkitShapeModel MODEL_SHULKER_BOX = new BukkitShulkerBox();
|
||||||
|
|
||||||
|
|
||||||
|
// Blocks that have a different shape, based on how they have been placed.
|
||||||
private static final BukkitShapeModel MODEL_SLAB = new BukkitSlab();
|
private static final BukkitShapeModel MODEL_SLAB = new BukkitSlab();
|
||||||
private static final BukkitShapeModel MODEL_STAIRS= new BukkitStairs();
|
private static final BukkitShapeModel MODEL_STAIRS= new BukkitStairs();
|
||||||
|
|
||||||
|
// Blocks that have a different shape with neighbor blocks (bukkit takes care though).
|
||||||
private static final BukkitShapeModel MODEL_THIN_FENCE = new BukkitFence(
|
private static final BukkitShapeModel MODEL_THIN_FENCE = new BukkitFence(
|
||||||
0.1375 + 0.3, 0.8625 - 0.3, 1.0);
|
0.4375, 1.0);
|
||||||
private static final BukkitShapeModel MODEL_THICK_FENCE = new BukkitFence(
|
private static final BukkitShapeModel MODEL_THICK_FENCE = new BukkitFence(
|
||||||
0.075 + 0.3, 0.925 - 0.3, 1.5);
|
0.375, 1.5);
|
||||||
private static final BukkitShapeModel MODEL_GATE = new BukkitGate(
|
|
||||||
0.075 + 0.3, 0.925 - 0.3, 1.5);
|
|
||||||
private static final BukkitShapeModel MODEL_SHULKER_BOX = new BukkitShulkerBox();
|
// Static blocks.
|
||||||
|
private static final BukkitShapeModel MODEL_FLOWER_POT = new BukkitStatic(
|
||||||
|
0.33, 0.375); // TODO: XZ really?
|
||||||
|
private static final BukkitShapeModel MODEL_GROUND_HEAD= new BukkitStatic(
|
||||||
|
0.25, 0.5); // TODO: XZ-really? 275 ?
|
||||||
|
private static final BukkitShapeModel MODEL_SINGLE_CHEST = new BukkitStatic(
|
||||||
|
0.062, .875);
|
||||||
|
private static final BukkitShapeModel MODEL_XZ100_HEIGHT16_1 = new BukkitStatic(
|
||||||
|
0.0625);
|
||||||
|
private static final BukkitShapeModel MODEL_XZ100_HEIGHT16_9 = new BukkitStatic(
|
||||||
|
0.5625);
|
||||||
|
private static final BukkitShapeModel MODEL_XZ100_HEIGHT16_15 = new BukkitStatic(
|
||||||
|
0.9375);
|
||||||
|
private static final BukkitShapeModel MODEL_XZ100_HEIGHT8_1 = new BukkitStatic(
|
||||||
|
0.125);
|
||||||
|
private static final BukkitShapeModel MODEL_XZ100_HEIGHT8_3 = new BukkitStatic(
|
||||||
|
0.375);
|
||||||
|
|
||||||
|
// TODO: enchanting table
|
||||||
|
// TODO: doors, trap doors
|
||||||
|
// TODO: Portals, end portal frame, ...
|
||||||
|
// TODO: END_ROD: 0.075 + 0.3, 0.925 - 0.3 / 1.0 -> BukkitCenteredFacing +-
|
||||||
|
// TODO: wall heads, chorus flower, other static, CAKE?
|
||||||
|
|
||||||
public MCAccessBukkitModern() {
|
public MCAccessBukkitModern() {
|
||||||
super();
|
super();
|
||||||
|
@ -64,36 +96,90 @@ public class MCAccessBukkitModern extends MCAccessBukkit {
|
||||||
return new BlockCacheBukkitModern(shapeModels);
|
return new BlockCacheBukkitModern(shapeModels);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addModel(Material mat, BukkitShapeModel model) {
|
||||||
|
processedBlocks.add(mat);
|
||||||
|
shapeModels.put(mat, model);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setupBlockProperties(final WorldConfigProvider<?> worldConfigProvider) {
|
public void setupBlockProperties(final WorldConfigProvider<?> worldConfigProvider) {
|
||||||
|
|
||||||
|
// TODO: Also consider removing flags (passable_x4 etc).
|
||||||
|
|
||||||
// Directly keep blocks as is.
|
// Directly keep blocks as is.
|
||||||
for (final Material mat : new Material[] {
|
for (final Material mat : new Material[] {
|
||||||
BridgeMaterial.MOVING_PISTON,
|
BridgeMaterial.MOVING_PISTON,
|
||||||
Material.SNOW
|
Material.SNOW,
|
||||||
|
BridgeMaterial.COBWEB
|
||||||
}) {
|
}) {
|
||||||
processedBlocks.add(mat);
|
processedBlocks.add(mat);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Also consider removing flags (passable_x4 etc).
|
// 16/15 height, full xz bounds.
|
||||||
|
for (Material mat : new Material[] {
|
||||||
|
Material.GRASS_PATH, BridgeMaterial.FARMLAND
|
||||||
|
}) {
|
||||||
|
addModel(mat, MODEL_XZ100_HEIGHT16_15);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1/8 height.
|
||||||
|
for (Material mat : new Material[] {
|
||||||
|
BridgeMaterial.REPEATER,
|
||||||
|
Material.COMPARATOR
|
||||||
|
}) {
|
||||||
|
addModel(mat, MODEL_XZ100_HEIGHT8_1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3/8 height.
|
||||||
|
for (Material mat : new Material[] {
|
||||||
|
Material.DAYLIGHT_DETECTOR
|
||||||
|
}) {
|
||||||
|
addModel(mat, MODEL_XZ100_HEIGHT8_3);
|
||||||
|
}
|
||||||
|
|
||||||
// Thin fence: Glass panes, iron bars.
|
// Thin fence: Glass panes, iron bars.
|
||||||
for (final Material mat : MaterialUtil.addBlocks(
|
for (final Material mat : MaterialUtil.addBlocks(
|
||||||
MaterialUtil.GLASS_PANES, BridgeMaterial.IRON_BARS)) {
|
MaterialUtil.GLASS_PANES, BridgeMaterial.IRON_BARS)) {
|
||||||
processedBlocks.add(mat);
|
addModel(mat, MODEL_THIN_FENCE);
|
||||||
shapeModels.put(mat, MODEL_THIN_FENCE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Slabs
|
// Slabs
|
||||||
for (final Material mat : MaterialUtil.SLABS) {
|
for (final Material mat : MaterialUtil.SLABS) {
|
||||||
processedBlocks.add(mat);
|
addModel(mat, MODEL_SLAB);
|
||||||
shapeModels.put(mat, MODEL_SLAB);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shulker boxes.
|
// Shulker boxes.
|
||||||
for (final Material mat : MaterialUtil.SHULKER_BOXES) {
|
for (final Material mat : MaterialUtil.SHULKER_BOXES) {
|
||||||
processedBlocks.add(mat);
|
addModel(mat, MODEL_SHULKER_BOX);
|
||||||
shapeModels.put(mat, MODEL_SHULKER_BOX);
|
}
|
||||||
|
|
||||||
|
// Chests.
|
||||||
|
// TOOD: Might add a facing/directional extension for double chests.
|
||||||
|
for (Material mat : BridgeMaterial.getAllBlocks(
|
||||||
|
"chest", "trapped_chest",
|
||||||
|
"ender_chest"
|
||||||
|
)) {
|
||||||
|
addModel(mat, MODEL_SINGLE_CHEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Beds
|
||||||
|
for (Material mat : MaterialUtil.BEDS) {
|
||||||
|
addModel(mat, MODEL_XZ100_HEIGHT16_9);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flower pots.
|
||||||
|
for (Material mat : MaterialUtil.FLOWER_POTS) {
|
||||||
|
addModel(mat, MODEL_FLOWER_POT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Carpets
|
||||||
|
for (final Material mat : MaterialUtil.CARPETS) {
|
||||||
|
addModel(mat, MODEL_XZ100_HEIGHT16_1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ground heads.
|
||||||
|
for (final Material mat : MaterialUtil.HEADS_GROUND) {
|
||||||
|
addModel(mat, MODEL_GROUND_HEAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort to processed by flags.
|
// Sort to processed by flags.
|
||||||
|
@ -101,26 +187,21 @@ public class MCAccessBukkitModern extends MCAccessBukkit {
|
||||||
final long flags = BlockProperties.getBlockFlags(mat);
|
final long flags = BlockProperties.getBlockFlags(mat);
|
||||||
// Stairs.
|
// Stairs.
|
||||||
if (BlockFlags.hasAnyFlag(flags, BlockProperties.F_STAIRS)) {
|
if (BlockFlags.hasAnyFlag(flags, BlockProperties.F_STAIRS)) {
|
||||||
processedBlocks.add(mat);
|
addModel(mat, MODEL_STAIRS);
|
||||||
shapeModels.put(mat, MODEL_STAIRS);
|
|
||||||
}
|
}
|
||||||
// Fences, cobblestone wall.
|
// Fences, cobblestone wall.
|
||||||
if (BlockFlags.hasAnyFlag(flags, BlockProperties.F_THICK_FENCE)) {
|
if (BlockFlags.hasAnyFlag(flags, BlockProperties.F_THICK_FENCE)) {
|
||||||
processedBlocks.add(mat);
|
|
||||||
if (BlockFlags.hasAnyFlag(flags, BlockProperties.F_PASSABLE_X4)) {
|
if (BlockFlags.hasAnyFlag(flags, BlockProperties.F_PASSABLE_X4)) {
|
||||||
// TODO: Perhaps another model flag.
|
// TODO: Perhaps another model flag.
|
||||||
shapeModels.put(mat, MODEL_GATE);
|
addModel(mat, MODEL_GATE);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
shapeModels.put(mat, MODEL_THICK_FENCE);
|
addModel(mat, MODEL_THICK_FENCE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ... (chests, snow, heads, static)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
super.setupBlockProperties(worldConfigProvider);
|
super.setupBlockProperties(worldConfigProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
package fr.neatmonster.nocheatplus.compat.bukkit.model;
|
||||||
|
|
||||||
|
import org.bukkit.World;
|
||||||
|
|
||||||
|
import fr.neatmonster.nocheatplus.utilities.map.BlockCache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bottom center cuboid.
|
||||||
|
*
|
||||||
|
* @author asofold
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class BukkitBottomCentered implements BukkitShapeModel {
|
||||||
|
|
||||||
|
private final double minXZ;
|
||||||
|
private final double maxXZ;
|
||||||
|
private final double height;
|
||||||
|
|
||||||
|
// TODO: Add modifications (shape alteration interface).
|
||||||
|
|
||||||
|
public BukkitBottomCentered(double inset, double height) {
|
||||||
|
this(inset, 1.0 - inset, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BukkitBottomCentered(double minXZ, double maxXZ, double height) {
|
||||||
|
this.minXZ = minXZ;
|
||||||
|
this.maxXZ = maxXZ;
|
||||||
|
this.height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double[] getShape(final BlockCache blockCache,
|
||||||
|
final World world, final int x, final int y, final int z) {
|
||||||
|
return new double[] {minXZ, 0.0, minXZ, maxXZ, height, maxXZ};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFakeData(final BlockCache blockCache,
|
||||||
|
final World world, final int x, final int y, final int z) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -29,6 +29,10 @@ public class BukkitFence implements BukkitShapeModel {
|
||||||
private final double maxXZ;
|
private final double maxXZ;
|
||||||
private final double height;
|
private final double height;
|
||||||
|
|
||||||
|
public BukkitFence(double inset, double height) {
|
||||||
|
this(inset, 1.0 - inset, height);
|
||||||
|
}
|
||||||
|
|
||||||
public BukkitFence(double minXZ, double maxXZ, double height) {
|
public BukkitFence(double minXZ, double maxXZ, double height) {
|
||||||
this.minXZ = minXZ;
|
this.minXZ = minXZ;
|
||||||
this.maxXZ = maxXZ;
|
this.maxXZ = maxXZ;
|
||||||
|
|
|
@ -29,6 +29,10 @@ public class BukkitGate implements BukkitShapeModel {
|
||||||
private final double maxXZ;
|
private final double maxXZ;
|
||||||
private final double height;
|
private final double height;
|
||||||
|
|
||||||
|
public BukkitGate(double inset, double height) {
|
||||||
|
this(inset, 1.0 - inset, height);
|
||||||
|
}
|
||||||
|
|
||||||
public BukkitGate(double minXZ, double maxXZ, double height) {
|
public BukkitGate(double minXZ, double maxXZ, double height) {
|
||||||
this.minXZ = minXZ;
|
this.minXZ = minXZ;
|
||||||
this.maxXZ = maxXZ;
|
this.maxXZ = maxXZ;
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
package fr.neatmonster.nocheatplus.compat.bukkit.model;
|
||||||
|
|
||||||
|
import org.bukkit.World;
|
||||||
|
|
||||||
|
import fr.neatmonster.nocheatplus.utilities.map.BlockCache;
|
||||||
|
|
||||||
|
public class BukkitStatic implements BukkitShapeModel {
|
||||||
|
|
||||||
|
private final double minX;
|
||||||
|
private final double minY;
|
||||||
|
private final double minZ;
|
||||||
|
private final double maxX;
|
||||||
|
private final double maxY;
|
||||||
|
private final double maxZ;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize with the given height and with full xz-bounds.
|
||||||
|
*
|
||||||
|
* @param height
|
||||||
|
*/
|
||||||
|
public BukkitStatic(double height) {
|
||||||
|
this(0.0, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize with the given height and xz-inset.
|
||||||
|
*
|
||||||
|
* @param xzInset
|
||||||
|
* @param height
|
||||||
|
*/
|
||||||
|
public BukkitStatic(double xzInset, double height) {
|
||||||
|
this(xzInset, 0.0, xzInset, 1.0 - xzInset, height, 1.0 - xzInset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BukkitStatic(double minX, double minY, double minZ,
|
||||||
|
double maxX, double maxY, double maxZ) {
|
||||||
|
this.minX = minX;
|
||||||
|
this.minY = minY;
|
||||||
|
this.minZ = minZ;
|
||||||
|
this.maxX = maxX;
|
||||||
|
this.maxY = maxY;
|
||||||
|
this.maxZ = maxZ;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double[] getShape(final BlockCache blockCache,
|
||||||
|
final World world, final int x, final int y, final int z) {
|
||||||
|
return new double[] {minX, minY, minZ, maxX, maxY, maxZ};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFakeData(final BlockCache blockCache,
|
||||||
|
final World world, final int x, final int y, final int z) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -77,7 +77,9 @@ public class BlocksMC1_5 implements BlockPropertiesSetup {
|
||||||
|
|
||||||
// 151 Daylight Sensor
|
// 151 Daylight Sensor
|
||||||
// BlockFlags.addFlags(151, BlockProperties.F_IGN_PASSABLE | BlockProperties.F_GROUND | BlockProperties.F_GROUND_HEIGHT);
|
// BlockFlags.addFlags(151, BlockProperties.F_IGN_PASSABLE | BlockProperties.F_GROUND | BlockProperties.F_GROUND_HEIGHT);
|
||||||
BlockInit.setAs("DAYLIGHT_DETECTOR", Material.VINE);
|
BlockInit.setPropsAs("DAYLIGHT_DETECTOR", Material.VINE);
|
||||||
|
BlockProperties.setBlockFlags("DAYLIGHT_DETECTOR", BlockFlags.SOLID_GROUND
|
||||||
|
| BlockProperties.F_XZ100);
|
||||||
|
|
||||||
// 152 Block of Redstone
|
// 152 Block of Redstone
|
||||||
BlockInit.setAs("REDSTONE_BLOCK", BridgeMaterial.ENCHANTING_TABLE);
|
BlockInit.setAs("REDSTONE_BLOCK", BridgeMaterial.ENCHANTING_TABLE);
|
||||||
|
|
|
@ -1044,6 +1044,9 @@ public class BlockProperties {
|
||||||
Material.COCOA, Material.SNOW, Material.BREWING_STAND,
|
Material.COCOA, Material.SNOW, Material.BREWING_STAND,
|
||||||
BridgeMaterial.PISTON_HEAD,
|
BridgeMaterial.PISTON_HEAD,
|
||||||
BridgeMaterial.STONE_SLAB,
|
BridgeMaterial.STONE_SLAB,
|
||||||
|
BridgeMaterial.REPEATER,
|
||||||
|
BridgeMaterial.getBlock("comparator"),
|
||||||
|
BridgeMaterial.getBlock("daylight_detector")
|
||||||
}) {
|
}) {
|
||||||
if (mat != null) {
|
if (mat != null) {
|
||||||
setFlag(mat, F_GROUND);
|
setFlag(mat, F_GROUND);
|
||||||
|
@ -1232,7 +1235,9 @@ public class BlockProperties {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cobweb
|
// Cobweb
|
||||||
setFlag(BridgeMaterial.COBWEB, F_COBWEB);
|
setFlag(BridgeMaterial.COBWEB, F_COBWEB | BlockFlags.FULL_BOUNDS
|
||||||
|
| F_IGN_PASSABLE);
|
||||||
|
|
||||||
// Huge mushroom type (...)
|
// Huge mushroom type (...)
|
||||||
for (Material mat : new Material[]{
|
for (Material mat : new Material[]{
|
||||||
Material.VINE, Material.COCOA}) {
|
Material.VINE, Material.COCOA}) {
|
||||||
|
|
|
@ -331,11 +331,12 @@ public class MaterialUtil {
|
||||||
"piston", "sticky_piston", "piston_base", "piston_sticky_base",
|
"piston", "sticky_piston", "piston_base", "piston_sticky_base",
|
||||||
"dispenser", "dropper", "furnace",
|
"dispenser", "dropper", "furnace",
|
||||||
"pumpkin", "melon_block", "hay_block", "bone_block",
|
"pumpkin", "melon_block", "hay_block", "bone_block",
|
||||||
"nether_wart_block", "cobweb", "web",
|
"nether_wart_block",
|
||||||
"snow_block", "ice", "magma_block",
|
"snow_block", "ice", "magma_block",
|
||||||
"diamond_block", "gold_block", "iron_block", "coal_block",
|
"diamond_block", "gold_block", "iron_block", "coal_block",
|
||||||
"emerald_block", "lapis_block", "redstone_block",
|
"emerald_block", "lapis_block", "redstone_block",
|
||||||
"purpur_block", "smooth_stone", "smooth_quartz", "quartz_block",
|
"purpur_block", "smooth_stone", "smooth_quartz", "quartz_block",
|
||||||
|
"quartz_pillar",
|
||||||
"sand", "stone", "gravel", "dirt", "grass_block", "grass",
|
"sand", "stone", "gravel", "dirt", "grass_block", "grass",
|
||||||
"sea_lantern", "redstone_lamp", "glowstone", "sponge", "wet_sponge"
|
"sea_lantern", "redstone_lamp", "glowstone", "sponge", "wet_sponge"
|
||||||
));
|
));
|
||||||
|
|
Loading…
Reference in New Issue