pick 97420a31d The big reformat of 2020
This commit is contained in:
@@ -18,23 +18,17 @@
|
||||
|
||||
package appeng.tile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import appeng.api.implementations.tiles.ISegmentedInventory;
|
||||
import appeng.api.util.ICommonTile;
|
||||
import appeng.api.util.IConfigManager;
|
||||
import appeng.api.util.IConfigurableObject;
|
||||
import appeng.api.util.IOrientable;
|
||||
import appeng.block.AEBaseTileBlock;
|
||||
import appeng.client.render.model.AEModelData;
|
||||
import appeng.core.AELog;
|
||||
import appeng.core.features.IStackSrc;
|
||||
import appeng.helpers.ICustomNameObject;
|
||||
import appeng.helpers.IPriorityHost;
|
||||
import appeng.hooks.TickHandler;
|
||||
import appeng.tile.inventory.AppEngInternalAEInventory;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.SettingsFrom;
|
||||
import io.netty.buffer.Unpooled;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.item.ItemStack;
|
||||
@@ -53,476 +47,414 @@ import net.minecraftforge.client.model.data.IModelData;
|
||||
import net.minecraftforge.client.model.data.ModelDataMap;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class AEBaseTile extends TileEntity implements IOrientable, ICommonTile, ICustomNameObject
|
||||
{
|
||||
|
||||
private static final ThreadLocal<WeakReference<AEBaseTile>> DROP_NO_ITEMS = new ThreadLocal<>();
|
||||
private static final Map<Class<? extends TileEntity>, IStackSrc> ITEM_STACKS = new HashMap<>();
|
||||
private int renderFragment = 0;
|
||||
@Nullable
|
||||
private String customName;
|
||||
private Direction forward = Direction.NORTH;
|
||||
private Direction up = Direction.UP;
|
||||
private boolean markDirtyQueued = false;
|
||||
|
||||
public AEBaseTile(TileEntityType<?> tileEntityTypeIn) {
|
||||
super(tileEntityTypeIn);
|
||||
}
|
||||
|
||||
public static void registerTileItem( final Class<? extends TileEntity> c, final IStackSrc wat )
|
||||
{
|
||||
ITEM_STACKS.put( c, wat );
|
||||
}
|
||||
|
||||
public boolean dropItems()
|
||||
{
|
||||
final WeakReference<AEBaseTile> what = DROP_NO_ITEMS.get();
|
||||
return what == null || what.get() != this;
|
||||
}
|
||||
|
||||
public boolean notLoaded()
|
||||
{
|
||||
return !this.world.isBlockLoaded( this.pos );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public TileEntity getTile()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected ItemStack getItemFromTile( final Object obj )
|
||||
{
|
||||
final IStackSrc src = ITEM_STACKS.get( obj.getClass() );
|
||||
if( src == null )
|
||||
{
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
return src.stack( 1 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read( final CompoundNBT data )
|
||||
{
|
||||
super.read( data );
|
||||
|
||||
if( data.contains( "customName" ) )
|
||||
{
|
||||
this.customName = data.getString( "customName" );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.customName = null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if( this.canBeRotated() )
|
||||
{
|
||||
this.forward = Direction.valueOf( data.getString( "forward" ) );
|
||||
this.up = Direction.valueOf( data.getString( "up" ) );
|
||||
}
|
||||
}
|
||||
catch( final IllegalArgumentException ignored )
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundNBT write( final CompoundNBT data )
|
||||
{
|
||||
super.write( data );
|
||||
|
||||
if( this.canBeRotated() )
|
||||
{
|
||||
data.putString( "forward", this.getForward().name() );
|
||||
data.putString( "up", this.getUp().name() );
|
||||
}
|
||||
|
||||
if( this.customName != null )
|
||||
{
|
||||
data.putString( "customName", this.customName );
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SUpdateTileEntityPacket getUpdatePacket()
|
||||
{
|
||||
return new SUpdateTileEntityPacket( this.pos, 64, this.getUpdateTag() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataPacket( final NetworkManager net, final SUpdateTileEntityPacket pkt )
|
||||
{
|
||||
// / pkt.actionType
|
||||
if( pkt.getTileEntityType() == 64 )
|
||||
{
|
||||
this.handleUpdateTag( pkt.getNbtCompound() );
|
||||
}
|
||||
}
|
||||
|
||||
public void onReady()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This builds a tag with the actual data that should be sent to the client for update syncs.
|
||||
* If the tile entity doesn't need update syncs, it returns null.
|
||||
*/
|
||||
private CompoundNBT writeUpdateData()
|
||||
{
|
||||
final CompoundNBT data = new CompoundNBT();
|
||||
|
||||
final PacketBuffer stream = new PacketBuffer( Unpooled.buffer() );
|
||||
|
||||
try
|
||||
{
|
||||
this.writeToStream( stream );
|
||||
if( stream.readableBytes() == 0 )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch( final Throwable t )
|
||||
{
|
||||
AELog.debug( t );
|
||||
}
|
||||
|
||||
stream.capacity( stream.readableBytes() );
|
||||
data.putByteArray( "X", stream.array() );
|
||||
return data;
|
||||
}
|
||||
|
||||
private boolean readUpdateData( PacketBuffer stream )
|
||||
{
|
||||
boolean output = false;
|
||||
|
||||
try
|
||||
{
|
||||
this.renderFragment = 100;
|
||||
|
||||
output = this.readFromStream( stream );
|
||||
|
||||
if( ( this.renderFragment & 1 ) == 1 )
|
||||
{
|
||||
output = true;
|
||||
}
|
||||
this.renderFragment = 0;
|
||||
}
|
||||
catch( final Throwable t )
|
||||
{
|
||||
AELog.debug( t );
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles tile entites that are being sent to the client as part of a full chunk.
|
||||
*/
|
||||
@Override
|
||||
public CompoundNBT getUpdateTag()
|
||||
{
|
||||
final CompoundNBT data = this.writeUpdateData();
|
||||
|
||||
if( data == null )
|
||||
{
|
||||
return new CompoundNBT();
|
||||
}
|
||||
|
||||
data.putInt( "x", this.pos.getX() );
|
||||
data.putInt( "y", this.pos.getY() );
|
||||
data.putInt( "z", this.pos.getZ() );
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles tile entites that are being received by the client as part of a full chunk.
|
||||
*/
|
||||
@Override
|
||||
public void handleUpdateTag( CompoundNBT tag )
|
||||
{
|
||||
final PacketBuffer stream = new PacketBuffer( Unpooled.copiedBuffer( tag.getByteArray( "X" ) ) );
|
||||
|
||||
if( this.readUpdateData( stream ) )
|
||||
{
|
||||
this.markForUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean readFromStream( final PacketBuffer data ) throws IOException
|
||||
{
|
||||
if( this.canBeRotated() )
|
||||
{
|
||||
final Direction old_Forward = this.forward;
|
||||
final Direction old_Up = this.up;
|
||||
|
||||
final byte orientation = data.readByte();
|
||||
this.forward = Direction.values()[orientation & 0x7];
|
||||
this.up = Direction.values()[orientation >> 3];
|
||||
|
||||
return this.forward != old_Forward || this.up != old_Up;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void writeToStream( final PacketBuffer data ) throws IOException
|
||||
{
|
||||
if( this.canBeRotated() )
|
||||
{
|
||||
final byte orientation = (byte) ( ( this.up.ordinal() << 3 ) | this.forward.ordinal() );
|
||||
data.writeByte( orientation );
|
||||
}
|
||||
}
|
||||
|
||||
public void markForUpdate()
|
||||
{
|
||||
if( this.renderFragment > 0 )
|
||||
{
|
||||
this.renderFragment |= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Optimize Network Load
|
||||
if( this.world != null )
|
||||
{
|
||||
this.requestModelDataUpdate();
|
||||
|
||||
boolean alreadyUpdated = false;
|
||||
// Let the block update it's own state with our internal state changes
|
||||
BlockState currentState = getBlockState();
|
||||
if (currentState.getBlock() instanceof AEBaseTileBlock) {
|
||||
AEBaseTileBlock<?> tileBlock = (AEBaseTileBlock<?>) currentState.getBlock();
|
||||
BlockState newState = tileBlock.getTileEntityBlockState(currentState, this);
|
||||
if (currentState != newState) {
|
||||
AELog.blockUpdate(this.pos, currentState, newState, this);
|
||||
this.world.setBlockState(pos, newState);
|
||||
alreadyUpdated = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!alreadyUpdated) {
|
||||
this.world.notifyBlockUpdate(this.pos, currentState, currentState, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* By default all blocks can have orientation, this handles saving, and loading, as well as synchronization.
|
||||
*
|
||||
* @return true if tile can be rotated
|
||||
*/
|
||||
@Override
|
||||
public boolean canBeRotated()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Direction getForward()
|
||||
{
|
||||
return this.forward;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Direction getUp()
|
||||
{
|
||||
return this.up;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOrientation( final Direction inForward, final Direction inUp )
|
||||
{
|
||||
this.forward = inForward;
|
||||
this.up = inUp;
|
||||
this.markForUpdate();
|
||||
Platform.notifyBlocksOfNeighbors( this.world, this.pos );
|
||||
}
|
||||
|
||||
public void onPlacement(BlockItemUseContext context)
|
||||
{
|
||||
ItemStack stack = context.getItem();
|
||||
if( stack.hasTag() )
|
||||
{
|
||||
this.uploadSettings( SettingsFrom.DISMANTLE_ITEM, stack.getTag() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* depending on the from, different settings will be accepted, don't call this with null
|
||||
*
|
||||
* @param from source of settings
|
||||
* @param compound compound of source
|
||||
*/
|
||||
public void uploadSettings( final SettingsFrom from, final CompoundNBT compound )
|
||||
{
|
||||
if( this instanceof IConfigurableObject )
|
||||
{
|
||||
final IConfigManager cm = ( (IConfigurableObject) this ).getConfigManager();
|
||||
if( cm != null )
|
||||
{
|
||||
cm.readFromNBT( compound );
|
||||
}
|
||||
}
|
||||
|
||||
if( this instanceof IPriorityHost )
|
||||
{
|
||||
final IPriorityHost pHost = (IPriorityHost) this;
|
||||
pHost.setPriority( compound.getInt( "priority" ) );
|
||||
}
|
||||
|
||||
if( this instanceof ISegmentedInventory )
|
||||
{
|
||||
final IItemHandler inv = ( (ISegmentedInventory) this ).getInventoryByName( "config" );
|
||||
if( inv instanceof AppEngInternalAEInventory )
|
||||
{
|
||||
final AppEngInternalAEInventory target = (AppEngInternalAEInventory) inv;
|
||||
final AppEngInternalAEInventory tmp = new AppEngInternalAEInventory( null, target.getSlots() );
|
||||
tmp.readFromNBT( compound, "config" );
|
||||
for( int x = 0; x < tmp.getSlots(); x++ )
|
||||
{
|
||||
target.setStackInSlot( x, tmp.getStackInSlot( x ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the contents of the tile entity, into the world, defaults to dropping everything in the inventory.
|
||||
*
|
||||
* @param w world
|
||||
* @param pos block position
|
||||
* @param drops drops of tile entity
|
||||
*/
|
||||
@Override
|
||||
public void getDrops( final World w, final BlockPos pos, final List<ItemStack> drops )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void getNoDrops( final World w, final BlockPos pos, final List<ItemStack> drops )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* null means nothing to store...
|
||||
*
|
||||
* @param from source of settings
|
||||
*
|
||||
* @return compound of source
|
||||
*/
|
||||
public CompoundNBT downloadSettings( final SettingsFrom from )
|
||||
{
|
||||
final CompoundNBT output = new CompoundNBT();
|
||||
|
||||
if( this.hasCustomInventoryName() )
|
||||
{
|
||||
final CompoundNBT dsp = new CompoundNBT();
|
||||
dsp.putString( "Name", this.customName );
|
||||
output.put( "display", dsp );
|
||||
}
|
||||
|
||||
if( this instanceof IConfigurableObject )
|
||||
{
|
||||
final IConfigManager cm = ( (IConfigurableObject) this ).getConfigManager();
|
||||
if( cm != null )
|
||||
{
|
||||
cm.writeToNBT( output );
|
||||
}
|
||||
}
|
||||
|
||||
if( this instanceof IPriorityHost)
|
||||
{
|
||||
final IPriorityHost pHost = (IPriorityHost) this;
|
||||
output.putInt( "priority", pHost.getPriority() );
|
||||
}
|
||||
|
||||
if( this instanceof ISegmentedInventory)
|
||||
{
|
||||
final IItemHandler inv = ( (ISegmentedInventory) this ).getInventoryByName( "config" );
|
||||
if( inv instanceof AppEngInternalAEInventory)
|
||||
{
|
||||
( (AppEngInternalAEInventory) inv ).writeToNBT( output, "config" );
|
||||
}
|
||||
}
|
||||
|
||||
return output.isEmpty() ? null : output;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITextComponent getCustomInventoryName()
|
||||
{
|
||||
return new StringTextComponent(this.hasCustomInventoryName() ? this.customName : this.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasCustomInventoryName()
|
||||
{
|
||||
return this.customName != null && !this.customName.isEmpty();
|
||||
}
|
||||
|
||||
public void securityBreak()
|
||||
{
|
||||
this.world.destroyBlock( this.pos, true );
|
||||
this.disableDrops();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this tile entity is remote (we are running on the logical client side).
|
||||
*/
|
||||
public boolean isRemote() {
|
||||
World world = getWorld();
|
||||
return world == null || world.isRemote();
|
||||
}
|
||||
|
||||
public void disableDrops()
|
||||
{
|
||||
DROP_NO_ITEMS.set( new WeakReference<>( this ) );
|
||||
}
|
||||
|
||||
public void saveChanges()
|
||||
{
|
||||
if( this.world != null )
|
||||
{
|
||||
this.world.markChunkDirty( this.pos, this );
|
||||
if( !this.markDirtyQueued )
|
||||
{
|
||||
TickHandler.INSTANCE.addCallable( null, this::markDirtyAtEndOfTick );
|
||||
this.markDirtyQueued = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Object markDirtyAtEndOfTick( final World w )
|
||||
{
|
||||
this.markDirty();
|
||||
this.markDirtyQueued = false;
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setName( final String name )
|
||||
{
|
||||
this.customName = name;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public IModelData getModelData() {
|
||||
return new AEModelData(up, forward);
|
||||
}
|
||||
import appeng.api.implementations.tiles.ISegmentedInventory;
|
||||
import appeng.api.util.ICommonTile;
|
||||
import appeng.api.util.IConfigManager;
|
||||
import appeng.api.util.IConfigurableObject;
|
||||
import appeng.api.util.IOrientable;
|
||||
import appeng.block.AEBaseTileBlock;
|
||||
import appeng.client.render.model.AEModelData;
|
||||
import appeng.core.AELog;
|
||||
import appeng.core.features.IStackSrc;
|
||||
import appeng.helpers.ICustomNameObject;
|
||||
import appeng.helpers.IPriorityHost;
|
||||
import appeng.hooks.TickHandler;
|
||||
import appeng.tile.inventory.AppEngInternalAEInventory;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.SettingsFrom;
|
||||
|
||||
public class AEBaseTile extends TileEntity implements IOrientable, ICommonTile, ICustomNameObject {
|
||||
|
||||
private static final ThreadLocal<WeakReference<AEBaseTile>> DROP_NO_ITEMS = new ThreadLocal<>();
|
||||
private static final Map<Class<? extends TileEntity>, IStackSrc> ITEM_STACKS = new HashMap<>();
|
||||
private int renderFragment = 0;
|
||||
@Nullable
|
||||
private String customName;
|
||||
private Direction forward = Direction.NORTH;
|
||||
private Direction up = Direction.UP;
|
||||
private boolean markDirtyQueued = false;
|
||||
|
||||
public AEBaseTile(TileEntityType<?> tileEntityTypeIn) {
|
||||
super(tileEntityTypeIn);
|
||||
}
|
||||
|
||||
public static void registerTileItem(final Class<? extends TileEntity> c, final IStackSrc wat) {
|
||||
ITEM_STACKS.put(c, wat);
|
||||
}
|
||||
|
||||
public boolean dropItems() {
|
||||
final WeakReference<AEBaseTile> what = DROP_NO_ITEMS.get();
|
||||
return what == null || what.get() != this;
|
||||
}
|
||||
|
||||
public boolean notLoaded() {
|
||||
return !this.world.isBlockLoaded(this.pos);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public TileEntity getTile() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected ItemStack getItemFromTile(final Object obj) {
|
||||
final IStackSrc src = ITEM_STACKS.get(obj.getClass());
|
||||
if (src == null) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
return src.stack(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(final CompoundNBT data) {
|
||||
super.read(data);
|
||||
|
||||
if (data.contains("customName")) {
|
||||
this.customName = data.getString("customName");
|
||||
} else {
|
||||
this.customName = null;
|
||||
}
|
||||
|
||||
try {
|
||||
if (this.canBeRotated()) {
|
||||
this.forward = Direction.valueOf(data.getString("forward"));
|
||||
this.up = Direction.valueOf(data.getString("up"));
|
||||
}
|
||||
} catch (final IllegalArgumentException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundNBT write(final CompoundNBT data) {
|
||||
super.write(data);
|
||||
|
||||
if (this.canBeRotated()) {
|
||||
data.putString("forward", this.getForward().name());
|
||||
data.putString("up", this.getUp().name());
|
||||
}
|
||||
|
||||
if (this.customName != null) {
|
||||
data.putString("customName", this.customName);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SUpdateTileEntityPacket getUpdatePacket() {
|
||||
return new SUpdateTileEntityPacket(this.pos, 64, this.getUpdateTag());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataPacket(final NetworkManager net, final SUpdateTileEntityPacket pkt) {
|
||||
// / pkt.actionType
|
||||
if (pkt.getTileEntityType() == 64) {
|
||||
this.handleUpdateTag(pkt.getNbtCompound());
|
||||
}
|
||||
}
|
||||
|
||||
public void onReady() {
|
||||
}
|
||||
|
||||
/**
|
||||
* This builds a tag with the actual data that should be sent to the client for
|
||||
* update syncs. If the tile entity doesn't need update syncs, it returns null.
|
||||
*/
|
||||
private CompoundNBT writeUpdateData() {
|
||||
final CompoundNBT data = new CompoundNBT();
|
||||
|
||||
final PacketBuffer stream = new PacketBuffer(Unpooled.buffer());
|
||||
|
||||
try {
|
||||
this.writeToStream(stream);
|
||||
if (stream.readableBytes() == 0) {
|
||||
return null;
|
||||
}
|
||||
} catch (final Throwable t) {
|
||||
AELog.debug(t);
|
||||
}
|
||||
|
||||
stream.capacity(stream.readableBytes());
|
||||
data.putByteArray("X", stream.array());
|
||||
return data;
|
||||
}
|
||||
|
||||
private boolean readUpdateData(PacketBuffer stream) {
|
||||
boolean output = false;
|
||||
|
||||
try {
|
||||
this.renderFragment = 100;
|
||||
|
||||
output = this.readFromStream(stream);
|
||||
|
||||
if ((this.renderFragment & 1) == 1) {
|
||||
output = true;
|
||||
}
|
||||
this.renderFragment = 0;
|
||||
} catch (final Throwable t) {
|
||||
AELog.debug(t);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles tile entites that are being sent to the client as part of a full
|
||||
* chunk.
|
||||
*/
|
||||
@Override
|
||||
public CompoundNBT getUpdateTag() {
|
||||
final CompoundNBT data = this.writeUpdateData();
|
||||
|
||||
if (data == null) {
|
||||
return new CompoundNBT();
|
||||
}
|
||||
|
||||
data.putInt("x", this.pos.getX());
|
||||
data.putInt("y", this.pos.getY());
|
||||
data.putInt("z", this.pos.getZ());
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles tile entites that are being received by the client as part of a full
|
||||
* chunk.
|
||||
*/
|
||||
@Override
|
||||
public void handleUpdateTag(CompoundNBT tag) {
|
||||
final PacketBuffer stream = new PacketBuffer(Unpooled.copiedBuffer(tag.getByteArray("X")));
|
||||
|
||||
if (this.readUpdateData(stream)) {
|
||||
this.markForUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean readFromStream(final PacketBuffer data) throws IOException {
|
||||
if (this.canBeRotated()) {
|
||||
final Direction old_Forward = this.forward;
|
||||
final Direction old_Up = this.up;
|
||||
|
||||
final byte orientation = data.readByte();
|
||||
this.forward = Direction.values()[orientation & 0x7];
|
||||
this.up = Direction.values()[orientation >> 3];
|
||||
|
||||
return this.forward != old_Forward || this.up != old_Up;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void writeToStream(final PacketBuffer data) throws IOException {
|
||||
if (this.canBeRotated()) {
|
||||
final byte orientation = (byte) ((this.up.ordinal() << 3) | this.forward.ordinal());
|
||||
data.writeByte(orientation);
|
||||
}
|
||||
}
|
||||
|
||||
public void markForUpdate() {
|
||||
if (this.renderFragment > 0) {
|
||||
this.renderFragment |= 1;
|
||||
} else {
|
||||
// TODO: Optimize Network Load
|
||||
if (this.world != null) {
|
||||
this.requestModelDataUpdate();
|
||||
|
||||
boolean alreadyUpdated = false;
|
||||
// Let the block update it's own state with our internal state changes
|
||||
BlockState currentState = getBlockState();
|
||||
if (currentState.getBlock() instanceof AEBaseTileBlock) {
|
||||
AEBaseTileBlock<?> tileBlock = (AEBaseTileBlock<?>) currentState.getBlock();
|
||||
BlockState newState = tileBlock.getTileEntityBlockState(currentState, this);
|
||||
if (currentState != newState) {
|
||||
AELog.blockUpdate(this.pos, currentState, newState, this);
|
||||
this.world.setBlockState(pos, newState);
|
||||
alreadyUpdated = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!alreadyUpdated) {
|
||||
this.world.notifyBlockUpdate(this.pos, currentState, currentState, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* By default all blocks can have orientation, this handles saving, and loading,
|
||||
* as well as synchronization.
|
||||
*
|
||||
* @return true if tile can be rotated
|
||||
*/
|
||||
@Override
|
||||
public boolean canBeRotated() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Direction getForward() {
|
||||
return this.forward;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Direction getUp() {
|
||||
return this.up;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOrientation(final Direction inForward, final Direction inUp) {
|
||||
this.forward = inForward;
|
||||
this.up = inUp;
|
||||
this.markForUpdate();
|
||||
Platform.notifyBlocksOfNeighbors(this.world, this.pos);
|
||||
}
|
||||
|
||||
public void onPlacement(BlockItemUseContext context) {
|
||||
ItemStack stack = context.getItem();
|
||||
if (stack.hasTag()) {
|
||||
this.uploadSettings(SettingsFrom.DISMANTLE_ITEM, stack.getTag());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* depending on the from, different settings will be accepted, don't call this
|
||||
* with null
|
||||
*
|
||||
* @param from source of settings
|
||||
* @param compound compound of source
|
||||
*/
|
||||
public void uploadSettings(final SettingsFrom from, final CompoundNBT compound) {
|
||||
if (this instanceof IConfigurableObject) {
|
||||
final IConfigManager cm = ((IConfigurableObject) this).getConfigManager();
|
||||
if (cm != null) {
|
||||
cm.readFromNBT(compound);
|
||||
}
|
||||
}
|
||||
|
||||
if (this instanceof IPriorityHost) {
|
||||
final IPriorityHost pHost = (IPriorityHost) this;
|
||||
pHost.setPriority(compound.getInt("priority"));
|
||||
}
|
||||
|
||||
if (this instanceof ISegmentedInventory) {
|
||||
final IItemHandler inv = ((ISegmentedInventory) this).getInventoryByName("config");
|
||||
if (inv instanceof AppEngInternalAEInventory) {
|
||||
final AppEngInternalAEInventory target = (AppEngInternalAEInventory) inv;
|
||||
final AppEngInternalAEInventory tmp = new AppEngInternalAEInventory(null, target.getSlots());
|
||||
tmp.readFromNBT(compound, "config");
|
||||
for (int x = 0; x < tmp.getSlots(); x++) {
|
||||
target.setStackInSlot(x, tmp.getStackInSlot(x));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the contents of the tile entity, into the world, defaults to dropping
|
||||
* everything in the inventory.
|
||||
*
|
||||
* @param w world
|
||||
* @param pos block position
|
||||
* @param drops drops of tile entity
|
||||
*/
|
||||
@Override
|
||||
public void getDrops(final World w, final BlockPos pos, final List<ItemStack> drops) {
|
||||
|
||||
}
|
||||
|
||||
public void getNoDrops(final World w, final BlockPos pos, final List<ItemStack> drops) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* null means nothing to store...
|
||||
*
|
||||
* @param from source of settings
|
||||
*
|
||||
* @return compound of source
|
||||
*/
|
||||
public CompoundNBT downloadSettings(final SettingsFrom from) {
|
||||
final CompoundNBT output = new CompoundNBT();
|
||||
|
||||
if (this.hasCustomInventoryName()) {
|
||||
final CompoundNBT dsp = new CompoundNBT();
|
||||
dsp.putString("Name", this.customName);
|
||||
output.put("display", dsp);
|
||||
}
|
||||
|
||||
if (this instanceof IConfigurableObject) {
|
||||
final IConfigManager cm = ((IConfigurableObject) this).getConfigManager();
|
||||
if (cm != null) {
|
||||
cm.writeToNBT(output);
|
||||
}
|
||||
}
|
||||
|
||||
if (this instanceof IPriorityHost) {
|
||||
final IPriorityHost pHost = (IPriorityHost) this;
|
||||
output.putInt("priority", pHost.getPriority());
|
||||
}
|
||||
|
||||
if (this instanceof ISegmentedInventory) {
|
||||
final IItemHandler inv = ((ISegmentedInventory) this).getInventoryByName("config");
|
||||
if (inv instanceof AppEngInternalAEInventory) {
|
||||
((AppEngInternalAEInventory) inv).writeToNBT(output, "config");
|
||||
}
|
||||
}
|
||||
|
||||
return output.isEmpty() ? null : output;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITextComponent getCustomInventoryName() {
|
||||
return new StringTextComponent(
|
||||
this.hasCustomInventoryName() ? this.customName : this.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasCustomInventoryName() {
|
||||
return this.customName != null && !this.customName.isEmpty();
|
||||
}
|
||||
|
||||
public void securityBreak() {
|
||||
this.world.destroyBlock(this.pos, true);
|
||||
this.disableDrops();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this tile entity is remote (we are running on the logical client
|
||||
* side).
|
||||
*/
|
||||
public boolean isRemote() {
|
||||
World world = getWorld();
|
||||
return world == null || world.isRemote();
|
||||
}
|
||||
|
||||
public void disableDrops() {
|
||||
DROP_NO_ITEMS.set(new WeakReference<>(this));
|
||||
}
|
||||
|
||||
public void saveChanges() {
|
||||
if (this.world != null) {
|
||||
this.world.markChunkDirty(this.pos, this);
|
||||
if (!this.markDirtyQueued) {
|
||||
TickHandler.INSTANCE.addCallable(null, this::markDirtyAtEndOfTick);
|
||||
this.markDirtyQueued = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Object markDirtyAtEndOfTick(final World w) {
|
||||
this.markDirty();
|
||||
this.markDirtyQueued = false;
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setName(final String name) {
|
||||
this.customName = name;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public IModelData getModelData() {
|
||||
return new AEModelData(up, forward);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user