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

Cache a turtle's fake player

Player construction can get a little expensive, and this is exacerbated
by Sponge. We now cache a turtle's fake player (updating the position
every time it is requested) in order to reduce this overhead.
This commit is contained in:
SquidDev 2018-07-08 15:21:42 +01:00
parent 0ce6f34a09
commit 45a189e834
5 changed files with 44 additions and 23 deletions

View File

@ -127,6 +127,8 @@ public static void cleanupBrains()
private TurtleAnimation m_animation;
private int m_animationProgress;
private int m_lastAnimationProgress;
TurtlePlayer m_cachedPlayer;
public TurtleBrain( TileTurtle turtle )
{

View File

@ -180,12 +180,12 @@ public static ItemStack deploy( @Nonnull ItemStack stack, ITurtleAccess turtle,
public static TurtlePlayer createPlayer( ITurtleAccess turtle, BlockPos position, EnumFacing direction )
{
TurtlePlayer turtlePlayer = new TurtlePlayer( turtle );
TurtlePlayer turtlePlayer = TurtlePlayer.get( turtle );
orientPlayer( turtle, turtlePlayer, position, direction );
return turtlePlayer;
}
public static void orientPlayer( ITurtleAccess turtle, TurtlePlayer turtlePlayer, BlockPos position, EnumFacing direction )
private static void orientPlayer( ITurtleAccess turtle, TurtlePlayer turtlePlayer, BlockPos position, EnumFacing direction )
{
turtlePlayer.posX = position.getX() + 0.5;
turtlePlayer.posY = position.getY() + 0.5;

View File

@ -36,16 +36,31 @@ public class TurtlePlayer extends FakePlayer
"[ComputerCraft]"
);
/**
* Construct a TurtlePlayer which exists in the world
*
* @param world The world the player exists in
* @deprecated This is required by {@link Entity}.
*/
@Deprecated
public TurtlePlayer( World world )
{
super( (WorldServer) world, DEFAULT_PROFILE );
}
public TurtlePlayer( ITurtleAccess turtle )
{
super( (WorldServer) turtle.getWorld(), getProfile( turtle.getOwningPlayer() ));
private TurtlePlayer( ITurtleAccess turtle )
{
super( (WorldServer) turtle.getWorld(), getProfile( turtle.getOwningPlayer() ) );
setState( turtle );
}
private static GameProfile getProfile( @Nullable GameProfile profile )
{
return profile != null && profile.isComplete() ? profile : DEFAULT_PROFILE;
}
private void setState( ITurtleAccess turtle )
{
BlockPos position = turtle.getPosition();
posX = position.getX() + 0.5;
posY = position.getY() + 0.5;
@ -55,9 +70,23 @@ public TurtlePlayer( ITurtleAccess turtle )
rotationPitch = 0.0f;
}
private static GameProfile getProfile( @Nullable GameProfile profile )
public static TurtlePlayer get( ITurtleAccess access )
{
return profile != null && profile.isComplete() ? profile : DEFAULT_PROFILE;
if( !(access instanceof TurtleBrain) ) return new TurtlePlayer( access );
TurtleBrain brain = (TurtleBrain) access;
TurtlePlayer player = brain.m_cachedPlayer;
if( player == null || player.getGameProfile() != getProfile( access.getOwningPlayer() )
|| player.getEntityWorld() != access.getWorld() )
{
player = brain.m_cachedPlayer = new TurtlePlayer( brain );
}
else
{
player.setState( access );
}
return player;
}
public void loadInventory( @Nonnull ItemStack currentStack )
@ -76,7 +105,7 @@ public ItemStack unloadInventory( ITurtleAccess turtle )
// Store (or drop) anything else we found
BlockPos dropPosition = turtle.getPosition();
EnumFacing dropDirection = turtle.getDirection().getOpposite();
for( int i=0; i<inventory.getSizeInventory(); ++i )
for( int i = 0; i < inventory.getSizeInventory(); ++i )
{
ItemStack stack = inventory.getStackInSlot( i );
if( !stack.isEmpty() )

View File

@ -118,7 +118,7 @@ public ArrayList<ItemStack> doCrafting( World world, int maxCount )
}
// Do post-pickup stuff
TurtlePlayer turtlePlayer = new TurtlePlayer( m_turtle );
TurtlePlayer turtlePlayer = TurtlePlayer.get( m_turtle );
result.onCrafting( world, turtlePlayer, numToCraft );
results.add( result );

View File

@ -29,12 +29,10 @@
import net.minecraft.item.ItemStack;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.NonNullList;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeHooks;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.ForgeEventFactory;
import net.minecraftforge.event.entity.player.AttackEntityEvent;
@ -149,15 +147,6 @@ protected boolean canBreakBlock( World world, BlockPos pos )
return !block.isAir( state, world, pos ) && block != Blocks.BEDROCK && state.getBlockHardness( world, pos ) > -1.0F;
}
protected boolean canHarvestBlock( ITurtleAccess turtleAccess, BlockPos pos )
{
World world = turtleAccess.getWorld();
Block block = world.getBlockState( pos ).getBlock();
TurtlePlayer turtlePlayer = new TurtlePlayer( turtleAccess );
turtlePlayer.loadInventory( m_item.copy() );
return ForgeHooks.canHarvestBlock( block, turtlePlayer, world, pos );
}
protected float getDamageMultiplier()
{
return 3.0f;
@ -286,9 +275,11 @@ private TurtleCommandResult dig( ITurtleAccess turtle, EnumFacing direction, Tur
{
return TurtleCommandResult.failure( digEvent.getFailureMessage() );
}
IBlockState previousState = world.getBlockState( newPosition );
// Consume the items the block drops
if( canHarvestBlock( turtle, newPosition ) )
if( previousState.getBlock().canHarvestBlock( world, newPosition, turtlePlayer ) )
{
List<ItemStack> items = getBlockDropped( world, newPosition, turtlePlayer );
if( items != null && items.size() > 0 )
@ -306,7 +297,6 @@ private TurtleCommandResult dig( ITurtleAccess turtle, EnumFacing direction, Tur
}
// Destroy the block
IBlockState previousState = world.getBlockState( newPosition );
world.playEvent(2001, newPosition, Block.getStateId(previousState));
world.setBlockToAir( newPosition );