use of org.bukkit.Material in project NoCheatPlus by NoCheatPlus.
the class BlockBreakListener method checkBlockDamage.
private void checkBlockDamage(final Player player, final Block block, final Cancellable event) {
final long now = System.currentTimeMillis();
final IPlayerData pData = DataManager.getPlayerData(player);
final BlockBreakData data = pData.getGenericInstance(BlockBreakData.class);
// Do not care about null blocks.
if (block == null) {
return;
}
final int tick = TickTask.getTick();
// Skip if already set to the same block without breaking within one tick difference.
final ItemStack stack = Bridge1_9.getItemInMainHand(player);
final Material tool = stack == null ? null : stack.getType();
if (data.toolChanged(tool)) {
// Update.
} else if (tick < data.clickedTick || now < data.fastBreakfirstDamage || now < data.fastBreakBreakTime) {
// Time/tick ran backwards: Update.
// Tick running backwards should not happen in the main thread unless for reload. A plugin could reset it (not intended).
} else if (data.fastBreakBreakTime < data.fastBreakfirstDamage && data.clickedX == block.getX() && data.clickedZ == block.getZ() && data.clickedY == block.getY()) {
// Preserve first damage time.
if (tick - data.clickedTick <= 1) {
return;
}
}
// (Always set, the interact event only fires once: the first time.)
// Only record first damage:
data.setClickedBlock(block, tick, now, tool);
// Compare with BlockInteract data (debug first).
if (pData.isDebugActive(CheckType.BLOCKBREAK)) {
BlockInteractListener.debugBlockVSBlockInteract(player, this.checkType, block, "checkBlockDamage", Action.LEFT_CLICK_BLOCK, pData);
}
}
use of org.bukkit.Material in project NoCheatPlus by NoCheatPlus.
the class FastBreak method check.
/**
* Checks a player for fastbreak. This is NOT for creative mode.
*
* @param player
* the player
* @param block
* the block
* @param isInstaBreak
* @param data
* @param cc
* @param elaspedTime
* @return true, if successful
*/
public boolean check(final Player player, final Block block, final AlmostBoolean isInstaBreak, final BlockBreakConfig cc, final BlockBreakData data, final IPlayerData pData) {
final long now = System.currentTimeMillis();
boolean cancel = false;
// Determine expected breaking time by block type.
final Material blockType = block.getType();
final long expectedBreakingTime = Math.max(0, Math.round((double) BlockProperties.getBreakingDuration(blockType, player) * (double) cc.fastBreakModSurvival / 100D));
final long elapsedTime;
// TODO: Should it be breakingTime instead of 0 for inconsistencies?
if (cc.fastBreakStrict) {
// Counting interact...break.
elapsedTime = (data.fastBreakBreakTime > data.fastBreakfirstDamage) ? 0 : now - data.fastBreakfirstDamage;
} else {
// Counting break...break.
elapsedTime = (data.fastBreakBreakTime > now) ? 0 : now - data.fastBreakBreakTime;
}
// Check if the time used time is lower than expected.
if (isInstaBreak.decideOptimistically()) {
// Ignore those for now.
// TODO: Find out why this was commented out long ago a) did not fix mcMMO b) exploits.
// TODO: Maybe adjust time to min(time, SOMETHING) for MAYBE/YES.
} else if (elapsedTime < 0) {
// Ignore it. TODO: ?
} else if (elapsedTime + cc.fastBreakDelay < expectedBreakingTime) {
// lag or cheat or Minecraft.
// Count in server side lag, if desired.
final float lag = pData.getCurrentWorldDataSafe().shouldAdjustToLag(type) ? TickTask.getLag(expectedBreakingTime, true) : 1f;
final long missingTime = expectedBreakingTime - (long) (lag * elapsedTime);
if (missingTime > 0) {
// Add as penalty
data.fastBreakPenalties.add(now, (float) missingTime);
// Only raise a violation, if the total penalty score exceeds the contention duration (for lag, delay).
if (data.fastBreakPenalties.score(cc.fastBreakBucketFactor) > cc.fastBreakGrace) {
// TODO: maybe add one absolute penalty time for big amounts to stop breaking until then
final double vlAdded = (double) missingTime / 1000.0;
data.fastBreakVL += vlAdded;
final ViolationData vd = new ViolationData(this, player, data.fastBreakVL, vlAdded, cc.fastBreakActions);
if (vd.needsParameters()) {
vd.setParameter(ParameterName.BLOCK_TYPE, blockType.toString());
}
cancel = executeActions(vd).willCancel();
}
// else: still within contention limits.
}
} else if (expectedBreakingTime > cc.fastBreakDelay) {
// Fast breaking does not decrease violation level.
data.fastBreakVL *= 0.9D;
}
// TODO: Rework to use (then hopefully completed) BlockBreakKey.
if (pData.isDebugActive(type)) {
tailDebugStats(player, isInstaBreak, blockType, elapsedTime, expectedBreakingTime, data, pData);
} else {
data.stats = null;
}
return cancel;
}
use of org.bukkit.Material in project NoCheatPlus by NoCheatPlus.
the class BlockProperties method initBlocks.
/**
* Inits the blocks.
*
* @param mcAccessHandle
* the mc access handle
* @param worldConfigProvider
* the world config provider
*/
private static void initBlocks(final IHandle<MCAccess> mcAccessHandle, final WorldConfigProvider<?> worldConfigProvider) {
final MCAccess mcAccess = mcAccessHandle.getHandle();
// Reset tool props.
blocks.clear();
// Generic initialization.
for (Material mat : Material.values()) {
blockFlags.put(mat, 0L);
if (mcAccess.isBlockLiquid(mat).decide()) {
// TODO: do not set F_GROUND for liquids ?
setFlag(mat, F_LIQUID);
if (mcAccess.isBlockSolid(mat).decide())
setFlag(mat, F_SOLID);
} else if (mcAccess.isBlockSolid(mat).decide()) {
setFlag(mat, F_SOLID | F_GROUND);
}
}
// Stairs.
for (final Material mat : new Material[] { Material.NETHER_BRICK_STAIRS, Material.COBBLESTONE_STAIRS, Material.SMOOTH_STAIRS, Material.BRICK_STAIRS, Material.SANDSTONE_STAIRS, Material.WOOD_STAIRS, Material.SPRUCE_WOOD_STAIRS, Material.BIRCH_WOOD_STAIRS, Material.JUNGLE_WOOD_STAIRS }) {
// Set ground too, to be sure.
setFlag(mat, F_STAIRS | F_HEIGHT100 | F_XZ100 | F_GROUND | F_GROUND_HEIGHT);
}
// Step (ground + full width).
for (final Material mat : new Material[] { Material.STEP, Material.WOOD_STEP }) {
setFlag(mat, F_GROUND | F_XZ100);
}
// Rails
for (final Material mat : new Material[] { Material.RAILS, Material.DETECTOR_RAIL, Material.POWERED_RAIL }) {
setFlag(mat, F_RAILS);
}
// WATER.
for (final Material mat : new Material[] { Material.STATIONARY_WATER, Material.WATER }) {
setFlag(mat, F_LIQUID | F_HEIGHT_8SIM_DEC | F_WATER | F_FALLDIST_ZERO);
}
// LAVA.
for (final Material mat : new Material[] { Material.LAVA, Material.STATIONARY_LAVA }) {
setFlag(mat, F_LIQUID | F_HEIGHT_8SIM_DEC | F_LAVA | F_FALLDIST_HALF);
}
// Snow (1.4.x)
setFlag(Material.SNOW, F_HEIGHT_8SIM_INC);
// Climbable
for (final Material mat : new Material[] { Material.VINE, Material.LADDER }) {
setFlag(mat, F_CLIMBABLE);
}
// Ground (can stand on).
for (final Material mat : new Material[] { Material.WATER_LILY, Material.LADDER, Material.DIODE_BLOCK_OFF, Material.DIODE_BLOCK_ON, Material.COCOA, Material.SNOW, Material.BREWING_STAND, Material.PISTON_MOVING_PIECE, Material.PISTON_EXTENSION, Material.STEP, Material.WOOD_STEP }) {
setFlag(mat, F_GROUND);
}
// Full block height.
for (final Material mat : new Material[] { // Material.ENDER_PORTAL_FRAME,
Material.BREWING_STAND, Material.PISTON_EXTENSION, // Server reports the visible shape 0.9375, client moves on full block height.
Material.SOIL }) {
setFlag(mat, F_HEIGHT100);
}
// Full width/xz-bounds.
for (final Material mat : new Material[] { Material.PISTON_EXTENSION, Material.ENDER_PORTAL_FRAME }) {
setFlag(mat, F_XZ100);
}
// ICE
setFlag(Material.ICE, F_ICE);
// Not ground (!).
for (final Material mat : new Material[] { Material.WALL_SIGN, Material.SIGN_POST }) {
// TODO: Might keep solid since it is meant to be related to block shapes rather ("original mc value").
maskFlag(mat, ~(F_GROUND | F_SOLID));
}
// Ignore for passable.
for (final Material mat : new Material[] { // More strictly needed.
Material.WOOD_PLATE, Material.STONE_PLATE, Material.WALL_SIGN, Material.SIGN_POST, Material.DIODE_BLOCK_ON, Material.DIODE_BLOCK_OFF, Material.BREWING_STAND, // Compatibility.
Material.LADDER, // Somewhat needed (xz-bounds vary, not critical to pass through).
Material.CAKE_BLOCK // Workarounds.
// Material.COCOA,
}) {
setFlag(mat, F_IGN_PASSABLE);
}
// Fences, 1.5 block high.
for (final Material mat : new Material[] { Material.FENCE, Material.FENCE_GATE, Material.NETHER_FENCE, Material.COBBLE_WALL }) {
setFlag(mat, F_HEIGHT150 | F_VARIABLE | F_THICK_FENCE);
}
// F_PASSABLE_X4
for (final Material mat : new Material[] { Material.FENCE_GATE, // TODO: Players can stand on - still passable past 1.9?
Material.TRAP_DOOR }) {
// TODO: PASSABLE_X4 is abused for other checks, need another one?
setFlag(mat, F_PASSABLE_X4);
}
// F_VARIABLE_REDSTONE, F_VARIABLE_USE
for (Material material : Material.values()) {
if (material.isBlock()) {
final String name = material.name().toLowerCase();
if (name.endsWith("_door") || name.endsWith("_trapdoor") || name.endsWith("fence_gate")) {
setFlag(material, F_VARIABLE_REDSTONE);
if (!name.contains("iron")) {
setFlag(material, F_VARIABLE_USE);
}
}
}
}
// F_FACING_LOW3D2_NSWE
for (final Material mat : new Material[] { Material.LADDER }) {
setFlag(mat, F_FACING_LOW3D2_NSWE);
}
// F_FACING_LOW2_SNEW
for (final Material mat : new Material[] { Material.TRAP_DOOR }) {
setFlag(mat, F_ATTACHED_LOW2_SNEW);
}
// Thin fences (iron fence, glass panes).
for (final Material mat : new Material[] { Material.IRON_FENCE, Material.THIN_GLASS }) {
setFlag(mat, F_THIN_FENCE | F_VARIABLE);
}
// Flexible ground (height):
for (final Material mat : new Material[] { // Strictly needed (multiple boxes otherwise).
Material.PISTON_EXTENSION, Material.BREWING_STAND, Material.ENDER_PORTAL_FRAME, // XZ-bounds issues.
Material.CAKE_BLOCK, // Issues standing on with F_PASSABLE_X4.
Material.TRAP_DOOR, // 1.10.2 +- client uses the reported height.
Material.SOIL }) {
setFlag(mat, F_GROUND_HEIGHT);
}
// Instantly breakable.
for (final Material mat : instantMat) {
setBlock(mat, instantType);
}
// Leaf type
for (Material mat : new Material[] { Material.LEAVES, Material.BED_BLOCK }) {
setBlock(mat, leafType);
}
setFlag(Material.LEAVES, F_LEAVES);
// Cobweb
setFlag(Material.WEB, F_COBWEB);
// Huge mushroom type (...)
for (Material mat : new Material[] { Material.HUGE_MUSHROOM_1, Material.HUGE_MUSHROOM_2, Material.VINE, Material.COCOA }) {
setBlock(mat, hugeMushroomType);
}
setBlock(Material.SNOW, new BlockProps(getToolProps(Material.WOOD_SPADE), 0.1f, secToMs(0.5, 0.1, 0.05, 0.05, 0.05, 0.05)));
setBlock(Material.SNOW_BLOCK, new BlockProps(getToolProps(Material.WOOD_SPADE), 0.1f, secToMs(1, 0.15, 0.1, 0.05, 0.05, 0.05)));
for (Material mat : new Material[] { Material.REDSTONE_LAMP_ON, Material.REDSTONE_LAMP_OFF, Material.GLOWSTONE, Material.GLASS }) {
setBlock(mat, glassType);
}
setBlock(Material.THIN_GLASS, glassType);
setBlock(Material.NETHERRACK, new BlockProps(woodPickaxe, 0.4f, secToMs(2, 0.3, 0.15, 0.1, 0.1, 0.05)));
setBlock(Material.LADDER, new BlockProps(noTool, 0.4f, secToMs(0.6), 2.5f));
setBlock(Material.CACTUS, new BlockProps(noTool, 0.4f, secToMs(0.6)));
setBlock(Material.WOOD_PLATE, new BlockProps(woodAxe, 0.5f, secToMs(0.75, 0.4, 0.2, 0.15, 0.1, 0.1)));
setBlock(Material.STONE_PLATE, new BlockProps(woodPickaxe, 0.5f, secToMs(2.5, 0.4, 0.2, 0.15, 0.1, 0.07)));
setBlock(Material.SAND, sandType);
setBlock(Material.SOUL_SAND, sandType);
for (Material mat : new Material[] { Material.LEVER, Material.PISTON_BASE, Material.PISTON_EXTENSION, Material.PISTON_STICKY_BASE, Material.STONE_BUTTON, Material.PISTON_MOVING_PIECE }) {
setBlock(mat, leverType);
}
// setBlock(Material.ICE, new BlockProps(woodPickaxe, 0.5f, secToMs(2.5, 0.4, 0.2, 0.15, 0.1, 0.1)));
setBlock(Material.ICE, new BlockProps(woodPickaxe, 0.5f, secToMs(0.7, 0.35, 0.18, 0.12, 0.09, 0.06)));
setBlock(Material.DIRT, sandType);
setBlock(Material.CAKE_BLOCK, leverType);
setBlock(Material.BREWING_STAND, new BlockProps(woodPickaxe, 0.5f, secToMs(2.5, 0.4, 0.2, 0.15, 0.1, 0.1)));
setBlock(Material.SPONGE, new BlockProps(noTool, 0.6f, secToMs(0.9)));
for (Material mat : new Material[] { Material.MYCEL, Material.GRAVEL, Material.GRASS, Material.SOIL, Material.CLAY }) {
setBlock(mat, gravelType);
}
for (Material mat : new Material[] { Material.RAILS, Material.POWERED_RAIL, Material.DETECTOR_RAIL }) {
setBlock(mat, new BlockProps(woodPickaxe, 0.7f, railsTimes));
}
setBlock(Material.MONSTER_EGGS, new BlockProps(noTool, 0.75f, secToMs(1.15)));
setBlock(Material.WOOL, new BlockProps(noTool, 0.8f, secToMs(1.2), 3f));
setBlock(Material.SANDSTONE, sandStoneType);
setBlock(Material.SANDSTONE_STAIRS, sandStoneType);
for (Material mat : new Material[] { Material.STONE, Material.SMOOTH_BRICK, Material.SMOOTH_STAIRS }) {
setBlock(mat, stoneType);
}
setBlock(Material.NOTE_BLOCK, new BlockProps(woodAxe, 0.8f, secToMs(1.2, 0.6, 0.3, 0.2, 0.15, 0.1)));
final BlockProps pumpkinType = new BlockProps(woodAxe, 1, secToMs(1.5, 0.75, 0.4, 0.25, 0.2, 0.15));
setBlock(Material.WALL_SIGN, pumpkinType);
setBlock(Material.SIGN_POST, pumpkinType);
setBlock(Material.PUMPKIN, pumpkinType);
setBlock(Material.JACK_O_LANTERN, pumpkinType);
setBlock(Material.MELON_BLOCK, new BlockProps(noTool, 1, secToMs(1.45), 3));
setBlock(Material.BOOKSHELF, new BlockProps(woodAxe, 1.5f, secToMs(2.25, 1.15, 0.6, 0.4, 0.3, 0.2)));
for (Material mat : new Material[] { Material.WOOD_STAIRS, Material.WOOD, Material.WOOD_STEP, Material.LOG, Material.FENCE, Material.FENCE_GATE, Material.JUKEBOX, Material.JUNGLE_WOOD_STAIRS, Material.SPRUCE_WOOD_STAIRS, Material.BIRCH_WOOD_STAIRS, // ?
Material.WOOD_DOUBLE_STEP // double slabs ?
}) {
setBlock(mat, woodType);
}
for (Material mat : new Material[] { Material.COBBLESTONE_STAIRS, Material.COBBLESTONE, Material.NETHER_BRICK, Material.NETHER_BRICK_STAIRS, Material.NETHER_FENCE, Material.CAULDRON, Material.BRICK, Material.BRICK_STAIRS, Material.MOSSY_COBBLESTONE, Material.BRICK, Material.BRICK_STAIRS, // ?
Material.STEP, // ?
Material.DOUBLE_STEP }) {
setBlock(mat, brickType);
}
setBlock(Material.WORKBENCH, chestType);
setBlock(Material.CHEST, chestType);
setBlock(Material.WOODEN_DOOR, woodDoorType);
setBlock(Material.TRAP_DOOR, woodDoorType);
for (Material mat : new Material[] { Material.ENDER_STONE, Material.COAL_ORE }) {
setBlock(mat, coalType);
}
// Former: coalType.
setBlock(Material.DRAGON_EGG, new BlockProps(noTool, 3f, secToMs(4.5)));
final long[] ironTimes = secToMs(15, 15, 1.15, 0.75, 0.6, 15);
final BlockProps ironType = new BlockProps(stonePickaxe, 3, ironTimes);
for (Material mat : new Material[] { Material.LAPIS_ORE, Material.LAPIS_BLOCK, Material.IRON_ORE }) {
setBlock(mat, ironType);
}
final long[] diamondTimes = secToMs(15, 15, 15, 0.75, 0.6, 15);
final BlockProps diamondType = new BlockProps(ironPickaxe, 3, diamondTimes);
for (Material mat : new Material[] { Material.REDSTONE_ORE, Material.GLOWING_REDSTONE_ORE, Material.EMERALD_ORE, Material.GOLD_ORE, Material.DIAMOND_ORE }) {
setBlock(mat, diamondType);
}
setBlock(Material.GOLD_BLOCK, goldBlockType);
setBlock(Material.FURNACE, dispenserType);
setBlock(Material.BURNING_FURNACE, dispenserType);
setBlock(Material.DISPENSER, dispenserType);
setBlock(Material.WEB, new BlockProps(woodSword, 4, secToMs(20, 0.4, 0.4, 0.4, 0.4, 0.4)));
for (Material mat : new Material[] { Material.MOB_SPAWNER, Material.IRON_DOOR_BLOCK, Material.IRON_FENCE, Material.ENCHANTMENT_TABLE, Material.EMERALD_BLOCK }) {
setBlock(mat, ironDoorType);
}
setBlock(Material.IRON_BLOCK, ironBlockType);
setBreakingTimeOverridesByEfficiency(new BlockBreakKey().blockType(Material.IRON_BLOCK).toolType(ToolType.PICKAXE).materialBase(MaterialBase.WOOD), ironBlockType.breakingTimes[1], 6200L, 3500L, 2050L, 1350L, 900L);
setBlock(Material.DIAMOND_BLOCK, diamondBlockType);
setBlock(Material.ENDER_CHEST, new BlockProps(woodPickaxe, 22.5f));
setBlock(Material.OBSIDIAN, new BlockProps(diamondPickaxe, 50, secToMs(250, 125, 62.5, 41.6, 9.4, 20.8)));
// More 1.4 (not insta).
// TODO: Either move all to an extra setup class, or integrate above.
// TODO
setBlock(Material.BEACON, new BlockProps(noTool, 25f, secToMs(4.45)));
setBlock(Material.COBBLE_WALL, brickType);
setFlag(Material.COBBLE_WALL, F_HEIGHT150);
setBlock(Material.WOOD_BUTTON, leverType);
// TODO
setBlock(Material.SKULL, new BlockProps(noTool, 8.5f, secToMs(1.45)));
setFlag(Material.SKULL, F_GROUND);
// TODO
setBlock(Material.ANVIL, new BlockProps(woodPickaxe, 5f));
setFlag(Material.FLOWER_POT, F_GROUND);
// Indestructible.
for (Material mat : new Material[] { Material.AIR, Material.ENDER_PORTAL, Material.ENDER_PORTAL_FRAME, Material.PORTAL, Material.LAVA, Material.WATER, Material.BEDROCK, Material.STATIONARY_LAVA, Material.STATIONARY_WATER }) {
setBlock(mat, indestructibleType);
}
// 95 Locked chest
// blocks[95] = indestructibleType; // Locked chest (prevent crash with 1.7).
Material mat = BlockInit.getMaterial("LOCKED_CHEST");
if (mat != null) {
BlockFlags.setFlagsAs(mat.name(), Material.CHEST);
// Breaks like chest later on.
setBlockProps(mat.name(), BlockProperties.instantType);
}
}
use of org.bukkit.Material in project NoCheatPlus by NoCheatPlus.
the class BlockProperties method isOnGround.
/**
* Check for ground at a certain block position, assuming checking order is
* top down within an x-z loop.
*
* @param access
* @param minX
* @param minY
* @param minZ
* @param maxX
* @param maxY
* @param maxZ
* @param ignoreFlags
* @param x
* @param y
* @param z
* @param iMaxY
* Math.min(iteration max block y, world max block y)
* @param node
* @param nodeAbove
* May be null.
* @return YES if certainly on ground, MAYBE if not on ground with the
* possibility of being on ground underneath, NO if not on ground
* without the possibility to be on ground with checking lower
* y-coordinates.
*/
public static final AlmostBoolean isOnGround(final BlockCache access, final double minX, final double minY, final double minZ, final double maxX, final double maxY, final double maxZ, final long ignoreFlags, final int x, final int y, final int z, final IBlockCacheNode node, IBlockCacheNode nodeAbove) {
// TODO: Relevant methods called here should be changed to use IBlockCacheNode (node, nodeAbove).
// TODO: Pass on the node (signatures...).
final Material id = node.getType();
final long flags = getBlockFlags(id);
// (IGN_PASSABLE might still allow standing on.)
if ((flags & F_GROUND) == 0 || (flags & ignoreFlags) != 0) {
return AlmostBoolean.MAYBE;
}
// Might collide.
final double[] bounds = node.getBounds(access, x, y, z);
if (bounds == null) {
// TODO: Safety check, uncertain.
return AlmostBoolean.YES;
}
if (!collidesBlock(access, minX, minY, minZ, maxX, maxY, maxZ, x, y, z, node, nodeAbove, flags)) {
return AlmostBoolean.MAYBE;
}
// Check if the block can be passed through with the bounding box (disregard the ignore flag).
if (isPassableWorkaround(access, x, y, z, minX - x, minY - y, minZ - z, node, maxX - minX, maxY - minY, maxZ - minZ, 1.0)) {
// TODO: Add getMinGroundHeight, getMaxGroundHeight.
if ((flags & F_GROUND_HEIGHT) == 0 || getGroundMinHeight(access, x, y, z, node, flags) > maxY - y) {
// Don't break, though could for some cases (?), since a block below still can be ground.
return AlmostBoolean.MAYBE;
}
}
// height >= ?
if (getGroundMinHeight(access, x, y, z, node, flags) > maxY - y) {
// Within block, this x and z is no candidate for ground.
if (isFullBounds(bounds)) {
return AlmostBoolean.NO;
} else {
return AlmostBoolean.MAYBE;
}
}
if (maxY - y < 1.0) {
// No need to check the block above (half slabs, stairs).
return AlmostBoolean.YES;
}
if (y >= access.getMaxBlockY()) {
// Only air above.
return AlmostBoolean.YES;
}
// Check above, ensure nodeAbove is set.
if (nodeAbove == null) {
nodeAbove = access.getOrCreateBlockCacheNode(x, y + 1, z, false);
}
final Material aboveId = nodeAbove.getType();
final long aboveFlags = getBlockFlags(aboveId);
if ((aboveFlags & F_IGN_PASSABLE) != 0) {
// TODO: Should this always apply ?
return AlmostBoolean.YES;
}
if ((aboveFlags & F_GROUND) == 0 || (aboveFlags & F_LIQUID) != 0 || (aboveFlags & ignoreFlags) != 0) {
return AlmostBoolean.YES;
}
boolean variable = (flags & F_VARIABLE) != 0;
variable |= (aboveFlags & F_VARIABLE) != 0;
// Check if it is the same id (walls!) and similar.
if (!variable && id == aboveId) {
// Exclude stone walls "quickly", can not stand on.
if (isFullBounds(bounds)) {
return AlmostBoolean.NO;
} else {
return AlmostBoolean.MAYBE;
}
}
// Check against spider type hacks.
final double[] aboveBounds = nodeAbove.getBounds(access, x, y + 1, z);
if (aboveBounds == null) {
return AlmostBoolean.YES;
}
// TODO: 1.49 might be obsolete !
if (!collidesBlock(access, minX, minY, minZ, maxX, Math.max(maxY, 1.49 + y), maxZ, x, y + 1, z, nodeAbove, null, aboveFlags)) {
return AlmostBoolean.YES;
}
// Check passable workaround without checking ignore flag.
if (isPassableWorkaround(access, x, y + 1, z, minX - x, minY - (y + 1), minZ - z, nodeAbove, maxX - minX, maxY - minY, maxZ - minZ, 1.0)) {
return AlmostBoolean.YES;
}
if (isFullBounds(aboveBounds)) {
// Can not be ground at this x - z position.
return AlmostBoolean.NO;
}
// TODO: More distinction necessary here.
if (variable) {
// TODO: Needs passable workaround check.
if (isSameShape(bounds, aboveBounds)) {
// There could be ground underneath (block vs. fence).
return AlmostBoolean.MAYBE;
// continue;
} else {
return AlmostBoolean.YES;
}
}
// Not regarded as ground,
return AlmostBoolean.MAYBE;
}
use of org.bukkit.Material in project NoCheatPlus by NoCheatPlus.
the class BlockProperties method getGroundMinHeight.
/**
* Reference block height for on-ground judgment: player must be at this or
* greater height to stand on this block.<br>
* <br>
* TODO: Check naming convention, might change to something with max ...
* volatile! <br>
* This might return 0 or somewhat arbitrary values for some blocks that
* don't have full bounds (!), might return 0 for blocks with the
* F_GROUND_HEIGHT flag, unless they are treated individually here.
*
* @param access
* the access
* @param x
* the x
* @param y
* the y
* @param z
* the z
* @param node
* The node at the given block coordinates.
* @param flags
* Flags for this block.
* @return the ground min height
*/
public static double getGroundMinHeight(final BlockCache access, final int x, final int y, final int z, final IBlockCacheNode node, final long flags) {
final Material id = node.getType();
final double[] bounds = node.getBounds(access, x, y, z);
// TODO: Check which ones are really needed !
if ((flags & F_HEIGHT_8SIM_INC) != 0) {
final int data = (node.getData(access, x, y, z) & 0xF) % 8;
if (data < 3) {
return 0;
} else {
return 0.5;
}
} else if ((flags & F_HEIGHT_8_INC) != 0) {
final int data = (node.getData(access, x, y, z) & 0xF) % 8;
return 0.125 * (double) data;
} else // Height 100 is ignored (!).
if ((flags & F_HEIGHT150) != 0) {
return 1.5;
} else if ((flags & F_STAIRS) != 0) {
if ((node.getData(access, x, y, z) & 0x4) != 0) {
return 1.0;
} else {
// what with >= 1?
return 0.5;
}
} else if ((flags & F_THICK_FENCE) != 0) {
return Math.min(1.0, bounds[4]);
} else if (id == Material.SOUL_SAND) {
return 0.875;
} else // }
if (id == Material.CAULDRON) {
// TODO: slightly over 0.
return 0.3125;
} else if (id == Material.CACTUS) {
return 0.9375;
} else if (id == Material.PISTON_EXTENSION) {
return 0.625;
} else if (id == Material.ENDER_PORTAL_FRAME) {
// Allow moving as if no eye was inserted.
return 0.8125;
} else if (bounds == null) {
return 0.0;
} else if ((flags & F_GROUND_HEIGHT) != 0) {
// Subsequent min height flags.
if ((flags & F_MIN_HEIGHT16_1) != 0) {
// 1/16
return 0.0625;
}
if ((flags & F_MIN_HEIGHT16_15) != 0) {
// 15/16
return 0.9375;
}
// Default height is used.
if (id == Material.SOIL) {
return bounds[4];
}
// Assume open gates/trapdoors/things to only allow standing on to, if at all.
if ((flags & F_PASSABLE_X4) != 0 && (node.getData(access, x, y, z) & 0x04) != 0) {
return bounds[4];
}
// All blocks that are not treated individually are ground all through.
return 0;
} else {
// TODO: Consider using Math.min(1.0, bounds[4]) for compatibility rather?
return bounds[4];
}
}
Aggregations