mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-04-02 08:46:59 +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:
parent
7bc9745c7a
commit
34d43d8273
@ -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,40 +71,32 @@ public class TurtleMoveCommand implements ITurtleCommand
|
||||
newPosition.getY(),
|
||||
newPosition.getZ()
|
||||
);
|
||||
|
||||
if( !oldWorld.checkNoEntityCollision( aabb ) )
|
||||
{
|
||||
if( ComputerCraft.turtlesCanPush && m_direction != MoveDirection.Up && m_direction != MoveDirection.Down )
|
||||
{
|
||||
// Check there is space for all the pushable entities to be pushed
|
||||
List<Entity> list = oldWorld.getEntitiesWithinAABBExcludingEntity( null, aabb );
|
||||
for( Entity entity : list )
|
||||
{
|
||||
if( !entity.isDead && entity.preventEntitySpawning )
|
||||
{
|
||||
AxisAlignedBB entityBB = entity.getEntityBoundingBox();
|
||||
if( entityBB == null )
|
||||
{
|
||||
entityBB = entity.getCollisionBoundingBox();
|
||||
}
|
||||
if( entityBB != null )
|
||||
{
|
||||
AxisAlignedBB pushedBB = entityBB.offset(
|
||||
direction.getXOffset(),
|
||||
direction.getYOffset(),
|
||||
direction.getZOffset()
|
||||
);
|
||||
if( !oldWorld.getCollisionBoxes( null, pushedBB ).isEmpty() )
|
||||
{
|
||||
return TurtleCommandResult.failure( "Movement obstructed" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
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.getEntitiesWithinAABB( Entity.class, aabb, x -> x != null && !x.isDead && x.preventEntitySpawning );
|
||||
for( Entity entity : list )
|
||||
{
|
||||
AxisAlignedBB entityBB = entity.getEntityBoundingBox();
|
||||
if( entityBB == null ) entityBB = entity.getCollisionBoundingBox();
|
||||
if( entityBB == null ) continue;
|
||||
|
||||
AxisAlignedBB pushedBB = entityBB.offset(
|
||||
direction.getXOffset(),
|
||||
direction.getYOffset(),
|
||||
direction.getZOffset()
|
||||
);
|
||||
if( !oldWorld.getCollisionBoxes( null, pushedBB ).isEmpty() )
|
||||
{
|
||||
return TurtleCommandResult.failure( "Movement obstructed" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TurtleBlockEvent.Move moveEvent = new TurtleBlockEvent.Move( turtle, turtlePlayer, oldWorld, newPosition );
|
||||
@ -121,42 +112,29 @@ public class TurtleMoveCommand implements ITurtleCommand
|
||||
}
|
||||
|
||||
// Move
|
||||
if( turtle.teleportTo( oldWorld, newPosition ) )
|
||||
{
|
||||
// Consume fuel
|
||||
turtle.consumeFuel( 1 );
|
||||
if( !turtle.teleportTo( oldWorld, newPosition ) ) return TurtleCommandResult.failure( "Movement failed" );
|
||||
|
||||
// Animate
|
||||
switch( m_direction )
|
||||
{
|
||||
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
|
||||
// Consume fuel
|
||||
turtle.consumeFuel( 1 );
|
||||
|
||||
// Animate
|
||||
switch( m_direction )
|
||||
{
|
||||
return TurtleCommandResult.failure( "Movement failed" );
|
||||
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();
|
||||
}
|
||||
|
||||
private TurtleCommandResult canEnter( TurtlePlayer turtlePlayer, World world, BlockPos position )
|
||||
|
@ -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,103 +70,86 @@ public class TurtleSuckCommand implements ITurtleCommand
|
||||
{
|
||||
// Take from inventory of thing in front
|
||||
ItemStack stack = InventoryUtil.takeItems( m_quantity, inventory );
|
||||
if( !stack.isEmpty() )
|
||||
{
|
||||
// Try to place into the turtle
|
||||
ItemStack remainder = InventoryUtil.storeItems( stack, turtle.getItemHandler(), turtle.getSelectedSlot() );
|
||||
if( !remainder.isEmpty() )
|
||||
{
|
||||
// Put the remainder back in the inventory
|
||||
InventoryUtil.storeItems( remainder, inventory );
|
||||
}
|
||||
if( stack.isEmpty() ) return TurtleCommandResult.failure( "No items to take" );
|
||||
|
||||
// Return true if we consumed anything
|
||||
if( remainder != stack )
|
||||
{
|
||||
turtle.playAnimation( TurtleAnimation.Wait );
|
||||
return TurtleCommandResult.success();
|
||||
}
|
||||
else
|
||||
{
|
||||
return TurtleCommandResult.failure( "No space for items" );
|
||||
}
|
||||
// Try to place into the turtle
|
||||
ItemStack remainder = InventoryUtil.storeItems( stack, turtle.getItemHandler(), turtle.getSelectedSlot() );
|
||||
if( !remainder.isEmpty() )
|
||||
{
|
||||
// Put the remainder back in the inventory
|
||||
InventoryUtil.storeItems( remainder, inventory );
|
||||
}
|
||||
|
||||
// Return true if we consumed anything
|
||||
if( remainder != stack )
|
||||
{
|
||||
turtle.playAnimation( TurtleAnimation.Wait );
|
||||
return TurtleCommandResult.success();
|
||||
}
|
||||
else
|
||||
{
|
||||
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 )
|
||||
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 )
|
||||
{
|
||||
boolean foundItems = false;
|
||||
boolean storedItems = false;
|
||||
for( Entity entity : list )
|
||||
// Suck up the item
|
||||
ItemStack stack = entity.getItem().copy();
|
||||
|
||||
ItemStack storeStack;
|
||||
ItemStack leaveStack;
|
||||
if( stack.getCount() > m_quantity )
|
||||
{
|
||||
if( entity instanceof EntityItem && !entity.isDead )
|
||||
{
|
||||
// Suck up the item
|
||||
foundItems = true;
|
||||
EntityItem entityItem = (EntityItem) entity;
|
||||
ItemStack stack = entityItem.getItem().copy();
|
||||
ItemStack storeStack;
|
||||
ItemStack leaveStack;
|
||||
if( stack.getCount() > m_quantity )
|
||||
{
|
||||
storeStack = stack.splitStack( m_quantity );
|
||||
leaveStack = stack;
|
||||
}
|
||||
else
|
||||
{
|
||||
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();
|
||||
}
|
||||
else if( remainder.isEmpty() )
|
||||
{
|
||||
entityItem.setItem( leaveStack );
|
||||
}
|
||||
else if( leaveStack.isEmpty() )
|
||||
{
|
||||
entityItem.setItem( remainder );
|
||||
}
|
||||
else
|
||||
{
|
||||
leaveStack.grow( remainder.getCount() );
|
||||
entityItem.setItem( leaveStack );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
storeStack = stack.splitStack( m_quantity );
|
||||
leaveStack = stack;
|
||||
}
|
||||
else
|
||||
{
|
||||
storeStack = stack;
|
||||
leaveStack = ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
if( foundItems )
|
||||
ItemStack remainder = InventoryUtil.storeItems( storeStack, turtle.getItemHandler(), turtle.getSelectedSlot() );
|
||||
|
||||
if( remainder != storeStack )
|
||||
{
|
||||
if( storedItems )
|
||||
if( remainder.isEmpty() && leaveStack.isEmpty() )
|
||||
{
|
||||
// Play fx
|
||||
world.playBroadcastSound( 1000, oldPosition, 0 );
|
||||
turtle.playAnimation( TurtleAnimation.Wait );
|
||||
return TurtleCommandResult.success();
|
||||
entity.setDead();
|
||||
}
|
||||
else if( remainder.isEmpty() )
|
||||
{
|
||||
entity.setItem( leaveStack );
|
||||
}
|
||||
else if( leaveStack.isEmpty() )
|
||||
{
|
||||
entity.setItem( remainder );
|
||||
}
|
||||
else
|
||||
{
|
||||
return TurtleCommandResult.failure( "No space for items" );
|
||||
leaveStack.grow( remainder.getCount() );
|
||||
entity.setItem( leaveStack );
|
||||
}
|
||||
|
||||
// Play fx
|
||||
world.playBroadcastSound( 1000, turtlePosition, 0 ); // BLOCK_DISPENSER_DISPENSE
|
||||
turtle.playAnimation( TurtleAnimation.Wait );
|
||||
return TurtleCommandResult.success();
|
||||
}
|
||||
}
|
||||
return TurtleCommandResult.failure( "No items to take" );
|
||||
|
||||
|
||||
return TurtleCommandResult.failure( "No space for items" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 )
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user