1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-06-03 23:24:11 +00:00

Make entity in bounds selectors more restrictive

This means we can remove some additional predicates we have in place,
and hopefully make things faster as less entities are added to the list.
This commit is contained in:
SquidDev 2019-01-03 22:20:50 +00:00
parent 7bc9745c7a
commit 34d43d8273
3 changed files with 112 additions and 153 deletions

View File

@ -57,8 +57,7 @@ public class TurtleMoveCommand implements ITurtleCommand
// Check existing block is air or replaceable
IBlockState state = oldWorld.getBlockState( newPosition );
Block block = state.getBlock();
if( block != null &&
!oldWorld.isAirBlock( newPosition ) &&
if( !oldWorld.isAirBlock( newPosition ) &&
!WorldUtil.isLiquidBlock( oldWorld, newPosition ) &&
!block.isReplaceable( oldWorld, newPosition ) )
{
@ -72,23 +71,22 @@ public class TurtleMoveCommand implements ITurtleCommand
newPosition.getY(),
newPosition.getZ()
);
if( !oldWorld.checkNoEntityCollision( aabb ) )
{
if( ComputerCraft.turtlesCanPush && m_direction != MoveDirection.Up && m_direction != MoveDirection.Down )
if( !ComputerCraft.turtlesCanPush || m_direction == MoveDirection.Up || m_direction == MoveDirection.Down )
{
return TurtleCommandResult.failure( "Movement obstructed" );
}
// Check there is space for all the pushable entities to be pushed
List<Entity> list = oldWorld.getEntitiesWithinAABBExcludingEntity( null, aabb );
List<Entity> list = oldWorld.getEntitiesWithinAABB( Entity.class, aabb, x -> x != null && !x.isDead && x.preventEntitySpawning );
for( Entity entity : list )
{
if( !entity.isDead && entity.preventEntitySpawning )
{
AxisAlignedBB entityBB = entity.getEntityBoundingBox();
if( entityBB == null )
{
entityBB = entity.getCollisionBoundingBox();
}
if( entityBB != null )
{
if( entityBB == null ) entityBB = entity.getCollisionBoundingBox();
if( entityBB == null ) continue;
AxisAlignedBB pushedBB = entityBB.offset(
direction.getXOffset(),
direction.getYOffset(),
@ -100,13 +98,6 @@ public class TurtleMoveCommand implements ITurtleCommand
}
}
}
}
}
else
{
return TurtleCommandResult.failure( "Movement obstructed" );
}
}
TurtleBlockEvent.Move moveEvent = new TurtleBlockEvent.Move( turtle, turtlePlayer, oldWorld, newPosition );
if( MinecraftForge.EVENT_BUS.post( moveEvent ) )
@ -121,8 +112,8 @@ public class TurtleMoveCommand implements ITurtleCommand
}
// Move
if( turtle.teleportTo( oldWorld, newPosition ) )
{
if( !turtle.teleportTo( oldWorld, newPosition ) ) return TurtleCommandResult.failure( "Movement failed" );
// Consume fuel
turtle.consumeFuel( 1 );
@ -131,33 +122,20 @@ public class TurtleMoveCommand implements ITurtleCommand
{
case Forward:
default:
{
turtle.playAnimation( TurtleAnimation.MoveForward );
break;
}
case Back:
{
turtle.playAnimation( TurtleAnimation.MoveBack );
break;
}
case Up:
{
turtle.playAnimation( TurtleAnimation.MoveUp );
break;
}
case Down:
{
turtle.playAnimation( TurtleAnimation.MoveDown );
break;
}
}
return TurtleCommandResult.success();
}
else
{
return TurtleCommandResult.failure( "Movement failed" );
}
}
private TurtleCommandResult canEnter( TurtlePlayer turtlePlayer, World world, BlockPos position )
{

View File

@ -12,9 +12,9 @@ import dan200.computercraft.api.turtle.TurtleAnimation;
import dan200.computercraft.api.turtle.TurtleCommandResult;
import dan200.computercraft.api.turtle.event.TurtleInventoryEvent;
import dan200.computercraft.shared.util.InventoryUtil;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EntitySelectors;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
@ -52,15 +52,15 @@ public class TurtleSuckCommand implements ITurtleCommand
// Get inventory for thing in front
World world = turtle.getWorld();
BlockPos oldPosition = turtle.getPosition();
BlockPos newPosition = oldPosition.offset( direction );
BlockPos turtlePosition = turtle.getPosition();
BlockPos blockPosition = turtlePosition.offset( direction );
EnumFacing side = direction.getOpposite();
IItemHandler inventory = InventoryUtil.getInventory( world, newPosition, side );
IItemHandler inventory = InventoryUtil.getInventory( world, blockPosition, side );
// Fire the event, exiting if it is cancelled.
TurtlePlayer player = TurtlePlaceCommand.createPlayer( turtle, oldPosition, direction );
TurtleInventoryEvent.Suck event = new TurtleInventoryEvent.Suck( turtle, player, world, newPosition, inventory );
TurtlePlayer player = TurtlePlaceCommand.createPlayer( turtle, turtlePosition, direction );
TurtleInventoryEvent.Suck event = new TurtleInventoryEvent.Suck( turtle, player, world, blockPosition, inventory );
if( MinecraftForge.EVENT_BUS.post( event ) )
{
return TurtleCommandResult.failure( event.getFailureMessage() );
@ -70,8 +70,8 @@ public class TurtleSuckCommand implements ITurtleCommand
{
// Take from inventory of thing in front
ItemStack stack = InventoryUtil.takeItems( m_quantity, inventory );
if( !stack.isEmpty() )
{
if( stack.isEmpty() ) return TurtleCommandResult.failure( "No items to take" );
// Try to place into the turtle
ItemStack remainder = InventoryUtil.storeItems( stack, turtle.getItemHandler(), turtle.getSelectedSlot() );
if( !remainder.isEmpty() )
@ -91,28 +91,21 @@ public class TurtleSuckCommand implements ITurtleCommand
return TurtleCommandResult.failure( "No space for items" );
}
}
return TurtleCommandResult.failure( "No items to take" );
}
else
{
// Suck up loose items off the ground
AxisAlignedBB aabb = new AxisAlignedBB(
newPosition.getX(), newPosition.getY(), newPosition.getZ(),
newPosition.getX() + 1.0, newPosition.getY() + 1.0, newPosition.getZ() + 1.0
blockPosition.getX(), blockPosition.getY(), blockPosition.getZ(),
blockPosition.getX() + 1.0, blockPosition.getY() + 1.0, blockPosition.getZ() + 1.0
);
List<Entity> list = world.getEntitiesWithinAABBExcludingEntity( null, aabb );
if( list.size() > 0 )
{
boolean foundItems = false;
boolean storedItems = false;
for( Entity entity : list )
{
if( entity instanceof EntityItem && !entity.isDead )
List<EntityItem> list = world.getEntitiesWithinAABB( EntityItem.class, aabb, EntitySelectors.IS_ALIVE );
if( list.isEmpty() ) return TurtleCommandResult.failure( "No items to take" );
for( EntityItem entity : list )
{
// Suck up the item
foundItems = true;
EntityItem entityItem = (EntityItem) entity;
ItemStack stack = entityItem.getItem().copy();
ItemStack stack = entity.getItem().copy();
ItemStack storeStack;
ItemStack leaveStack;
if( stack.getCount() > m_quantity )
@ -125,48 +118,38 @@ public class TurtleSuckCommand implements ITurtleCommand
storeStack = stack;
leaveStack = ItemStack.EMPTY;
}
ItemStack remainder = InventoryUtil.storeItems( storeStack, turtle.getItemHandler(), turtle.getSelectedSlot() );
if( remainder != storeStack )
{
storedItems = true;
if( remainder.isEmpty() && leaveStack.isEmpty() )
{
entityItem.setDead();
entity.setDead();
}
else if( remainder.isEmpty() )
{
entityItem.setItem( leaveStack );
entity.setItem( leaveStack );
}
else if( leaveStack.isEmpty() )
{
entityItem.setItem( remainder );
entity.setItem( remainder );
}
else
{
leaveStack.grow( remainder.getCount() );
entityItem.setItem( leaveStack );
}
break;
}
}
entity.setItem( leaveStack );
}
if( foundItems )
{
if( storedItems )
{
// Play fx
world.playBroadcastSound( 1000, oldPosition, 0 );
world.playBroadcastSound( 1000, turtlePosition, 0 ); // BLOCK_DISPENSER_DISPENSE
turtle.playAnimation( TurtleAnimation.Wait );
return TurtleCommandResult.success();
}
else
{
}
return TurtleCommandResult.failure( "No space for items" );
}
}
}
return TurtleCommandResult.failure( "No items to take" );
}
}
}

View File

@ -6,6 +6,7 @@
package dan200.computercraft.shared.util;
import com.google.common.base.Predicate;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.item.EntityItem;
@ -24,6 +25,8 @@ import java.util.List;
public class WorldUtil
{
private static final Predicate<Entity> CAN_COLLIDE = x -> x != null && !x.isDead && x.canBeCollidedWith();
public static boolean isLiquidBlock( World world, BlockPos pos )
{
return world.getBlockState( pos ).getMaterial().isLiquid();
@ -56,14 +59,9 @@ public class WorldUtil
Entity closest = null;
double closestDist = 99.0;
List<Entity> list = world.getEntitiesWithinAABBExcludingEntity( null, bigBox );
List<Entity> list = world.getEntitiesWithinAABB( Entity.class, bigBox, CAN_COLLIDE );
for( Entity entity : list )
{
if( entity.isDead || !entity.canBeCollidedWith() )
{
continue;
}
AxisAlignedBB littleBox = entity.getEntityBoundingBox();
if( littleBox == null )
{