Skip to content

Commit

Permalink
Explicit height flag for grass path. Bukkit model for stairs.
Browse files Browse the repository at this point in the history
  • Loading branch information
asofold committed Aug 21, 2018
1 parent 56f1a37 commit b89c3af
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 26 deletions.
Expand Up @@ -29,7 +29,15 @@ public BlockCacheBukkitModern(World world) {

@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);
}

Expand Down
Expand Up @@ -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();
}
Expand Down Expand Up @@ -81,10 +94,12 @@ protected boolean guessItchyBlock(final Material mat) {
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;
}

Expand All @@ -97,18 +112,6 @@ private void testItchyBlock() {
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.
Expand Down
Expand Up @@ -5,9 +5,11 @@

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;
Expand All @@ -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
Expand All @@ -39,6 +43,13 @@ public BlockCache getBlockCache() {
@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()) {
Expand All @@ -52,10 +63,15 @@ public void setupBlockProperties(final WorldConfigProvider<?> worldConfigProvide
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 ...)
Expand Down
Expand Up @@ -28,10 +28,15 @@ public double[] getShape(final BlockCache blockCache,
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;
}

}
@@ -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;
}

}
Expand Up @@ -4,7 +4,19 @@

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);

}
Expand Up @@ -94,12 +94,6 @@ public void setupBlockProperties(WorldConfigProvider<?> worldConfigProvider) {
// 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);

Expand Down Expand Up @@ -176,6 +170,11 @@ public void setupBlockProperties(WorldConfigProvider<?> worldConfigProvider) {
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.");
}
Expand Down
Expand Up @@ -106,6 +106,10 @@ public static void removeFlags(String id, long flags) {
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.
*
Expand Down
Expand Up @@ -860,6 +860,9 @@ private static long f_flag() {
*/
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.
Expand Down Expand Up @@ -3904,6 +3907,10 @@ else if ((flags & F_HEIGHT100) != 0) {
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);
Expand Down

0 comments on commit b89c3af

Please sign in to comment.