Skip to content

Commit

Permalink
Improve carpet stairs hitboxes
Browse files Browse the repository at this point in the history
  • Loading branch information
KnightMiner committed Jul 18, 2019
1 parent 5f22c9c commit 276b59d
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 81 deletions.
Expand Up @@ -7,6 +7,7 @@
import knightminer.inspirations.common.Config;
import knightminer.inspirations.library.InspirationsRegistry;
import knightminer.inspirations.library.PropertyUnlistedInteger;
import knightminer.inspirations.library.Util;
import knightminer.inspirations.library.util.TextureBlockUtil;
import net.minecraft.block.BlockHorizontal;
import net.minecraft.block.ITileEntityProvider;
Expand Down Expand Up @@ -238,20 +239,7 @@ public RayTraceResult collisionRayTrace(IBlockState state, @Nonnull World world,
list.add(rayTrace(pos, start, end, bound));
}

// compare results
RayTraceResult result = null;
double max = 0.0D;
for(RayTraceResult raytraceresult : list) {
if(raytraceresult != null) {
double distance = raytraceresult.hitVec.squareDistanceTo(end);
if(distance > max) {
result = raytraceresult;
max = distance;
}
}
}

return result;
return Util.closestResult(list, end);
}

/*
Expand Down
43 changes: 32 additions & 11 deletions src/main/java/knightminer/inspirations/library/Util.java
@@ -1,16 +1,7 @@
package knightminer.inspirations.library;

import java.util.Arrays;
import java.util.List;
import java.util.Locale;

import javax.annotation.Nullable;

import knightminer.inspirations.library.util.ReflectionUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import knightminer.inspirations.Inspirations;
import knightminer.inspirations.library.util.ReflectionUtil;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
Expand All @@ -24,10 +15,18 @@
import net.minecraft.util.NonNullList;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.util.text.translation.I18n;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import javax.annotation.Nullable;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;

@SuppressWarnings("deprecation")
public class Util {
public static String resource(String name) {
return String.format("%s:%s", Inspirations.modID, name.toLowerCase(Locale.US));
Expand Down Expand Up @@ -199,4 +198,26 @@ public static EnumDyeColor getDyeForColor(int color) {
}
return null;
}

/**
* Returns the closest raytrace result from a list
* @param list List of ray traces
* @param end Ending vector of the trace
* @return Cloest result
*/
public static RayTraceResult closestResult(List<RayTraceResult> list, Vec3d end) {
RayTraceResult closest = null;
double max = 0.0D;
for(RayTraceResult raytraceresult : list) {
if(raytraceresult != null) {
double distance = raytraceresult.hitVec.squareDistanceTo(end);
if(distance > max) {
closest = raytraceresult;
max = distance;
}
}
}

return closest;
}
}
Expand Up @@ -3,6 +3,7 @@
import com.google.common.collect.Lists;
import knightminer.inspirations.common.Config;
import knightminer.inspirations.library.InspirationsRegistry;
import knightminer.inspirations.library.Util;
import knightminer.inspirations.library.util.TextureBlockUtil;
import knightminer.inspirations.recipes.client.BoilingParticle;
import knightminer.inspirations.recipes.tileentity.TileCauldron;
Expand Down Expand Up @@ -299,19 +300,7 @@ public RayTraceResult collisionRayTrace(IBlockState state, @Nonnull World world,
list.add(rayTrace(pos, start, end, axisalignedbb));
}

RayTraceResult closest = null;
double max = 0.0D;
for(RayTraceResult raytraceresult : list) {
if(raytraceresult != null) {
double distance = raytraceresult.hitVec.squareDistanceTo(end);
if(distance > max) {
closest = raytraceresult;
max = distance;
}
}
}

return closest;
return Util.closestResult(list, end);
}

public static enum CauldronContents implements IStringSerializable {
Expand Down
@@ -1,20 +1,26 @@
package knightminer.inspirations.tweaks.block;

import javax.annotation.Nullable;

import net.minecraft.block.Block;
import knightminer.inspirations.library.Util;
import net.minecraft.block.BlockCarpet;
import net.minecraft.block.BlockStairs;
import net.minecraft.block.SoundType;
import net.minecraft.block.BlockStairs.EnumHalf;
import net.minecraft.block.BlockStairs.EnumShape;
import net.minecraft.block.SoundType;
import net.minecraft.block.properties.PropertyBool;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.item.EnumDyeColor;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;

public class BlockFittedCarpet extends BlockCarpet {

Expand Down Expand Up @@ -48,23 +54,99 @@ protected BlockStateContainer createBlockState() {
*/
@Override
public IBlockState getActualState(IBlockState state, IBlockAccess world, BlockPos pos) {
BlockPos down = pos.down();
IBlockState below = world.getBlockState(down);
Block block = below.getBlock();
//if(block instanceof BlockSlab && !((BlockSlab)block).isDouble() && below.getValue(BlockSlab.HALF) == EnumBlockHalf.BOTTOM) {
// state = setProperties(state, 0b1111);
//} else
if(block instanceof BlockStairs && below.getValue(BlockStairs.HALF) == EnumHalf.BOTTOM) {
below = below.getActualState(world, down);
state = setProperties(state, getStairShape(below));
return setProperties(state, getStairShape(world, pos.down()));
}

@Override
@Deprecated
@Nullable
public AxisAlignedBB getCollisionBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos) {
// if any of the parts are lowered, no collision box
if(getStairShape(world, pos) > 0) {
return NULL_AABB;
}
return state;
return super.getCollisionBoundingBox(state, world, pos);
}

private int getStairShape(IBlockState stairs) {
EnumShape shape = stairs.getValue(BlockStairs.SHAPE);
private static final AxisAlignedBB[] BOUNDS;
private static final AxisAlignedBB BOUNDS_NW = new AxisAlignedBB(0.0, 0.0, 0.0, 0.5625, 0.0625, 0.5625);
private static final AxisAlignedBB BOUNDS_NE = new AxisAlignedBB(0.4375, 0.0, 0.0, 1.0, 0.0625, 0.5625);
private static final AxisAlignedBB BOUNDS_SW = new AxisAlignedBB(0.0, 0.0, 0.4375, 0.5625, 0.0625, 1.0);
private static final AxisAlignedBB BOUNDS_SE = new AxisAlignedBB(0.4375, 0.0, 0.4375, 1.0, 0.0625, 1.0);
static {
// bits are NW NE SW SE
BOUNDS = new AxisAlignedBB[]{
CARPET_AABB, // 0000
CARPET_AABB, // SE: 0001
CARPET_AABB, // SW: 0010
new AxisAlignedBB(0.0, 0.0, 0.0, 1.0, 0.0625, 0.5625), // 0011, NORTH
CARPET_AABB, // NE: 0100
new AxisAlignedBB(0.0, 0.0, 0.0, 0.5625, 0.0625, 1.0), // 0101, WEST
CARPET_AABB, // 0110
BOUNDS_NW, // 0111
CARPET_AABB, // 1000
CARPET_AABB, // 1001
new AxisAlignedBB(0.4375, 0.0, 0.0, 1.0, 0.0625, 1.0), // 1010, EAST
BOUNDS_NE, // 1011
new AxisAlignedBB(0.0, 0.0, 0.4375, 1.0, 0.0625, 1.0), // 1100, SOUTH
BOUNDS_SW, // 1101
BOUNDS_SE, // 1110
CARPET_AABB, // 1111
};
}
@Override
@Deprecated
public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos) {
return BOUNDS[getStairShape(source, pos.down())];
}

@Deprecated
@Override
public RayTraceResult collisionRayTrace(IBlockState state, @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Vec3d start, @Nonnull Vec3d end) {
int shape = getStairShape(world, pos.down());
// if three corners up or checkerboard, run on just up
switch(shape) {
case 0b0001:
case 0b0010:
case 0b0100:
case 0b0110:
case 0b1000:
case 0b1001:
break;
default:
return super.collisionRayTrace(state, world, pos, start, end);
}

// basically the same BlockStairs does
// Raytrace through all AABBs (plate, legs) and return the nearest one
List<RayTraceResult> list = new ArrayList<>();
if ((shape & 0b1000) == 0) list.add(rayTrace(pos, start, end, BOUNDS_NW));
if ((shape & 0b0100) == 0) list.add(rayTrace(pos, start, end, BOUNDS_NE));
if ((shape & 0b0010) == 0) list.add(rayTrace(pos, start, end, BOUNDS_SW));
if ((shape & 0b0001) == 0) list.add(rayTrace(pos, start, end, BOUNDS_SE));

return Util.closestResult(list, end);
}


/* Utils */

/**
* Gets the shape for the carpet from the given stairs
* @param world World access
* @param pos Stairs position
* @return 4 bit integer with bits in order NW, NE, SW, SE. If the bit is set, the carpet is down
*/
private int getStairShape(IBlockAccess world, BlockPos pos) {
IBlockState stairs = world.getBlockState(pos);
if (!(stairs.getBlock() instanceof BlockStairs) || stairs.getValue(BlockStairs.HALF) == EnumHalf.TOP) {
return 0b0000;
}

// seemed like the simplest way, convert each shape to four bits
// bits are NW NE SW SE
stairs = stairs.getActualState(world, pos);
EnumShape shape = stairs.getValue(BlockStairs.SHAPE);
switch(stairs.getValue(BlockStairs.FACING)) {
case NORTH:
switch(shape) {
Expand Down Expand Up @@ -99,26 +181,20 @@ private int getStairShape(IBlockState stairs) {
case OUTER_RIGHT: return 0b1110;
}
}
return 0;
return 0b0000;
}

/**
* Sets the state properties based on the given shape
* @param state Carpet block state
* @param i Shape integer from {@link #getStairShape(IBlockAccess, BlockPos)}
* @return New stairs shape
*/
private IBlockState setProperties(IBlockState state, int i) {
return state
.withProperty(NORTHWEST, (i & 8) > 0)
.withProperty(NORTHEAST, (i & 4) > 0)
.withProperty(SOUTHWEST, (i & 2) > 0)
.withProperty(SOUTHEAST, (i & 1) > 0);
}

@Override
@Deprecated
@Nullable
public AxisAlignedBB getCollisionBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos) {
// if any of the parts are lowered, no collision box
state = state.getActualState(world, pos);
if(state.getValue(NORTHWEST) || state.getValue(NORTHEAST) || state.getValue(SOUTHWEST) || state.getValue(SOUTHEAST)) {
return NULL_AABB;
}
return super.getCollisionBoundingBox(state, world, pos);
}
}
Expand Up @@ -2,6 +2,7 @@

import knightminer.inspirations.Inspirations;
import knightminer.inspirations.common.Config;
import knightminer.inspirations.library.Util;
import knightminer.inspirations.utility.InspirationsUtility;
import knightminer.inspirations.utility.tileentity.TilePipe;
import net.minecraft.block.Block;
Expand Down Expand Up @@ -274,19 +275,6 @@ public RayTraceResult collisionRayTrace(IBlockState state, @Nonnull World world,
list.add(rayTrace(pos, start, end, BOUNDS_EAST_CONNECT));
}

// compare results
RayTraceResult result = null;
double max = 0.0D;
for(RayTraceResult raytraceresult : list) {
if(raytraceresult != null) {
double distance = raytraceresult.hitVec.squareDistanceTo(end);
if(distance > max) {
result = raytraceresult;
max = distance;
}
}
}

return result;
return Util.closestResult(list, end);
}
}

0 comments on commit 276b59d

Please sign in to comment.