Explicit height flag for grass path. Bukkit model for stairs.

This commit is contained in:
asofold 2018-08-21 13:01:07 +02:00
parent 56f1a37969
commit b89c3af589
9 changed files with 144 additions and 26 deletions

View File

@ -29,7 +29,15 @@ public class BlockCacheBukkitModern extends BlockCacheBukkit {
@Override
public int fetchData(int x, int y, int z) {
// TODO: Might fake here too.
Material mat = getType(x, y, z);
final BukkitShapeModel shapeModel = shapeModels.get(mat);
if (shapeModel != null) {
final int data = shapeModel.getFakeData(this, world, x, y, z);
if (data != Integer.MAX_VALUE) {
return data;
}
}
return super.fetchData(x, y, z);
}

View File

@ -51,6 +51,19 @@ public class MCAccessBukkitBase implements MCAccess {
*/
protected final Set<Material> processedBlocks = new LinkedHashSet<Material>();
/**
* Constructor to let it fail.
*/
public MCAccessBukkitBase() {
// TODO: Add more that might fail if not supported ?
testItchyBlock();
// TODO: Deactivate checks that might not work. => MCAccess should have availability method, NCP deactivates check on base of that.
// TODO: Move getHeight and the like to EntityAccessXY.
bukkitHasGetHeightAndGetWidth = ReflectionUtil.getMethodNoArgs(Entity.class, "getHeight", double.class) != null
&& ReflectionUtil.getMethodNoArgs(Entity.class, "getWidth", double.class) != null;
}
@SuppressWarnings("deprecation")
private boolean guessItchyBlockPre1_13(final Material mat) {
return !mat.isOccluding() || !mat.isSolid() || mat.isTransparent();
}
@ -81,10 +94,12 @@ public class MCAccessBukkitBase implements MCAccess {
return true;
}
}
long testFlags = (BlockProperties.F_SOLID | BlockProperties.F_XZ100
| BlockProperties.F_HEIGHT100);
if (BlockFlags.hasAllFlags(flags, testFlags)) {
// Fully solid block.
long testFlags1 = (BlockProperties.F_SOLID | BlockProperties.F_XZ100);
long testFlags2 = (BlockProperties.F_HEIGHT100
| BlockProperties.F_HEIGHT16_15);
if (BlockFlags.hasAllFlags(flags, testFlags1)
&& BlockFlags.hasAnyFlag(flags, testFlags2)) {
// Solid blocks with explicitly set bounds.
return false;
}
@ -97,18 +112,6 @@ public class MCAccessBukkitBase implements MCAccess {
guessItchyBlockPre1_13(Material.AIR);
}
/**
* Constructor to let it fail.
*/
public MCAccessBukkitBase() {
// TODO: Add more that might fail if not supported ?
testItchyBlock();
// TODO: Deactivate checks that might not work. => MCAccess should have availability method, NCP deactivates check on base of that.
// TODO: Move getHeight and the like to EntityAccessXY.
bukkitHasGetHeightAndGetWidth = ReflectionUtil.getMethodNoArgs(Entity.class, "getHeight", double.class) != null
&& ReflectionUtil.getMethodNoArgs(Entity.class, "getWidth", double.class) != null;
}
@Override
public String getMCVersion() {
// Bukkit API.

View File

@ -5,9 +5,11 @@ import java.util.Map;
import org.bukkit.Material;
import fr.neatmonster.nocheatplus.compat.BridgeMaterial;
import fr.neatmonster.nocheatplus.compat.blocks.init.BlockInit;
import fr.neatmonster.nocheatplus.compat.bukkit.model.BukkitShapeModel;
import fr.neatmonster.nocheatplus.compat.bukkit.model.BukkitSlab;
import fr.neatmonster.nocheatplus.compat.bukkit.model.BukkitStairs;
import fr.neatmonster.nocheatplus.config.WorldConfigProvider;
import fr.neatmonster.nocheatplus.utilities.map.BlockCache;
import fr.neatmonster.nocheatplus.utilities.map.BlockFlags;
@ -19,11 +21,13 @@ public class MCAccessBukkitModern extends MCAccessBukkit {
protected final Map<Material, BukkitShapeModel> shapeModels = new HashMap<Material, BukkitShapeModel>();
private static final BukkitShapeModel MODEL_SLAB = new BukkitSlab();
private static final BukkitShapeModel MODEL_STAIRS= new BukkitStairs();
public MCAccessBukkitModern() {
super();
// TODO: Generic setup via Bukkit interface existence/relations, +- fetching methods.
BlockInit.assertMaterialExists("OAK_LOG");
BlockInit.assertMaterialExists("VOID_AIR");
BlockInit.assertMaterialExists("CAVE_AIR");
}
@Override
@ -39,6 +43,13 @@ public class MCAccessBukkitModern extends MCAccessBukkit {
@Override
public void setupBlockProperties(final WorldConfigProvider<?> worldConfigProvider) {
// Directly keep blocks as is.
for (final Material mat : new Material[] {
BridgeMaterial.MOVING_PISTON
}) {
processedBlocks.add(mat);
}
// Pre-process for flags.
// TODO: Also consider removing flags (passable_x4 etc).
for (final Material mat : Material.values()) {
@ -52,10 +63,15 @@ public class MCAccessBukkitModern extends MCAccessBukkit {
final long flags = BlockProperties.getBlockFlags(mat);
// Step.
if (BlockFlags.hasAnyFlag(flags, BlockProperties.F_MODEL_SLAB)) {
// TODO: Should scrap the flag and just register the shape model.
processedBlocks.add(mat);
shapeModels.put(mat, MODEL_SLAB);
}
// Stairs.
if (BlockFlags.hasAnyFlag(flags, BlockProperties.F_STAIRS)) {
processedBlocks.add(mat);
shapeModels.put(mat, MODEL_STAIRS);
}
// Fences. // TODO: May need specialized models for edge cases?
// Thin fences.
// ... (heads, chests, static, shulker box ...)

View File

@ -28,10 +28,15 @@ public class BukkitSlab implements BukkitShapeModel {
break;
default:
break;
}
}
return new double[] {0.0, 0.0, 0.0, 1.0, 1.0, 1.0};
}
@Override
public int getFakeData(final BlockCache blockCache,
final World world, final int x, final int y, final int z) {
return 0;
}
}

View File

@ -0,0 +1,64 @@
package fr.neatmonster.nocheatplus.compat.bukkit.model;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.data.Bisected.Half;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.type.Stairs;
import fr.neatmonster.nocheatplus.utilities.map.BlockCache;
public class BukkitStairs implements BukkitShapeModel {
@Override
public double[] getShape(final BlockCache blockCache,
final World world, final int x, final int y, final int z) {
// TODO: With fake data, this could simply return full bounds.
// final Block block = world.getBlockAt(x, y, z);
// final BlockState state = block.getState();
// final BlockData blockData = state.getBlockData();
//
// if (blockData instanceof Stairs) {
// final Stairs stairs = (Stairs) blockData;
// final Half half = stairs.getHalf();
// //final Shape shape = stairs.getShape();
// // TODO: Refine later, with sub shapes.
// switch (half) {
// case BOTTOM:
// return new double[] {0.0, 0.0, 0.0, 1.0, 0.5, 1.0};
// case TOP:
// return new double[] {0.0, 0.5, 0.0, 1.0, 1.0, 1.0};
// default:
// break;
//
// }
// }
return new double[] {0.0, 0.0, 0.0, 1.0, 1.0, 1.0};
}
@Override
public int getFakeData(final BlockCache blockCache,
final World world, final int x, final int y, final int z) {
final Block block = world.getBlockAt(x, y, z);
final BlockState state = block.getState();
final BlockData blockData = state.getBlockData();
if (blockData instanceof Stairs) {
final Stairs stairs = (Stairs) blockData;
final Half half = stairs.getHalf();
//final Shape shape = stairs.getShape();
// TODO: Refine later, with sub shapes.
switch (half) {
case TOP:
return 0x4;
default:
break;
}
}
return 0;
}
}

View File

@ -4,7 +4,19 @@ import fr.neatmonster.nocheatplus.utilities.map.BlockCache;
public interface ShapeModel<W> {
// TODO: Rather fill in all into node directly (data as well), avoid redundant casting etc.
// TODO: Best route passable workaround through here too (base on a flag), + getGroundMinHeight?.
// TODO: Refine +- might have BukkitBlockCacheNode etc.
public double[] getShape(BlockCache blockCache, W world, int x, int y, int z);
/**
* Allow faking data.
*
* @return Integer.MAX_VALUE, in case fake data is not supported, and the
* Bukkit method is used (as long as possible). 0 may be returned
* for performance.
*/
public int getFakeData(BlockCache blockCache, W world, int x, int y, int z);
}

View File

@ -94,12 +94,6 @@ public class BlocksMC1_13 implements BlockPropertiesSetup {
// Blue ice.
BlockInit.setAs("BLUE_ICE", Material.ICE);
// Grass path.
// TODO: HEIGHT16_15 instead.
BlockFlags.addFlags(Material.GRASS_PATH, BlockProperties.F_MIN_HEIGHT16_15
| BlockProperties.F_HEIGHT100
| BlockProperties.F_GROUND_HEIGHT);
// Wet sponge.
BlockInit.setAs("WET_SPONGE", Material.SPONGE);
@ -176,6 +170,11 @@ public class BlocksMC1_13 implements BlockPropertiesSetup {
BlockProperties.setBlockProps("TURTLE_EGG", new BlockProps(
BlockProperties.noTool, 0.5f, BlockProperties.secToMs(0.7)));
// Grass path.
// TODO: HEIGHT16_15 instead.
BlockFlags.removeFlags(Material.GRASS_PATH, BlockProperties.F_HEIGHT100);
BlockFlags.addFlags(Material.GRASS_PATH,
BlockProperties.F_XZ100 | BlockProperties.F_HEIGHT16_15);
StaticLog.logInfo("Added block-info for Minecraft 1.13 blocks.");
}

View File

@ -106,6 +106,10 @@ public class BlockFlags {
BlockProperties.setBlockFlags(id, BlockProperties.getBlockFlags(id) & ~flags);
}
public static void removeFlags(Material mat, long flags) {
BlockProperties.setBlockFlags(mat, BlockProperties.getBlockFlags(mat) & ~flags);
}
/**
* Test if any flags within testFlags are contained.
*

View File

@ -860,6 +860,9 @@ public class BlockProperties {
*/
public static final long F_MODEL_SLAB = f_flag();
/** Height 15/16 (0.9375 = 1 - 0.0625). */
public static final long F_HEIGHT16_15 = f_flag();
// TODO: Convenience constants combining all height / minheight flags.
// TODO: When flags are out, switch to per-block classes :p.
@ -3904,6 +3907,10 @@ public class BlockProperties {
bminY = 0;
bmaxY = 1.0;
}
else if ((flags & F_HEIGHT16_15) != 0) {
bminY = 0;
bmaxY = 0.9375;
}
else if ((flags & F_HEIGHT_8SIM_DEC) != 0) {
bminY = 0;
final int data = node.getData(access, x, y, z);