1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2024-07-01 09:33:20 +00:00

Use world-specific collider entity

This is equally an ugly hack, but means we're at least not constructing
entities with null worlds any more.

Ideally we could always use the turtle entity, but this will require a
bit more of a refactor.

Fixes #265
This commit is contained in:
SquidDev 2019-07-05 22:09:42 +01:00
parent 18068effec
commit 9d51c4c340

View File

@ -7,6 +7,7 @@
package dan200.computercraft.shared.util; package dan200.computercraft.shared.util;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.collect.MapMaker;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.entity.*; import net.minecraft.entity.*;
import net.minecraft.entity.item.ItemEntity; import net.minecraft.entity.item.ItemEntity;
@ -20,25 +21,35 @@
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.List; import java.util.List;
import java.util.Map;
public final class WorldUtil public final class WorldUtil
{ {
@SuppressWarnings( "Guava" ) @SuppressWarnings( "Guava" )
private static final Predicate<Entity> CAN_COLLIDE = x -> x != null && x.isAlive() && x.canBeCollidedWith(); private static final Predicate<Entity> CAN_COLLIDE = x -> x != null && x.isAlive() && x.canBeCollidedWith();
private static final Entity ENTITY = new ItemEntity( EntityType.ITEM, null ) private static final Map<World, Entity> entityCache = new MapMaker().weakKeys().weakValues().makeMap();
{
@Override
public EntitySize getSize( Pose pose )
{
return EntitySize.fixed( 0, 0 );
}
};
static private static synchronized Entity getEntity( World world )
{ {
ENTITY.noClip = true; // TODO: It'd be nice if we could avoid this. Maybe always use the turtle player (if it's available).
ENTITY.recalculateSize(); Entity entity = entityCache.get( world );
if( entity != null ) return entity;
entity = new ItemEntity( EntityType.ITEM, world )
{
@Nonnull
@Override
public EntitySize getSize( Pose pose )
{
return EntitySize.fixed( 0, 0 );
}
};
entity.noClip = true;
entity.recalculateSize();
entityCache.put( world, entity );
return entity;
} }
public static boolean isLiquidBlock( World world, BlockPos pos ) public static boolean isLiquidBlock( World world, BlockPos pos )
@ -61,8 +72,9 @@ public static Pair<Entity, Vec3d> rayTraceEntities( World world, Vec3d vecStart,
Vec3d vecEnd = vecStart.add( vecDir.x * distance, vecDir.y * distance, vecDir.z * distance ); Vec3d vecEnd = vecStart.add( vecDir.x * distance, vecDir.y * distance, vecDir.z * distance );
// Raycast for blocks // Raycast for blocks
ENTITY.setPosition( vecStart.x, vecStart.y, vecStart.z ); Entity collisionEntity = getEntity( world );
RayTraceContext context = new RayTraceContext( vecStart, vecEnd, RayTraceContext.BlockMode.COLLIDER, RayTraceContext.FluidMode.NONE, ENTITY ); collisionEntity.setPosition( vecStart.x, vecStart.y, vecStart.z );
RayTraceContext context = new RayTraceContext( vecStart, vecEnd, RayTraceContext.BlockMode.COLLIDER, RayTraceContext.FluidMode.NONE, collisionEntity );
RayTraceResult result = world.rayTraceBlocks( context ); RayTraceResult result = world.rayTraceBlocks( context );
if( result != null && result.getType() == RayTraceResult.Type.BLOCK ) if( result != null && result.getType() == RayTraceResult.Type.BLOCK )
{ {