e1f9e01404
Also use a client-side method to update connected textures for crafting cubes if two previously distinct clusters are connected. Refactored MBCalculator to use generics for type checks and remove more casts.
234 lines
7.4 KiB
Java
234 lines
7.4 KiB
Java
/*
|
|
* This file is part of Applied Energistics 2.
|
|
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
|
*
|
|
* Applied Energistics 2 is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* Applied Energistics 2 is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
|
*/
|
|
|
|
package appeng.tile.spatial;
|
|
|
|
import java.io.IOException;
|
|
import java.util.EnumSet;
|
|
|
|
import javax.annotation.Nonnull;
|
|
|
|
import net.minecraft.network.PacketBuffer;
|
|
import net.minecraft.tileentity.TileEntityType;
|
|
import net.minecraft.util.Direction;
|
|
import net.minecraft.util.math.BlockPos;
|
|
import net.minecraftforge.client.model.data.IModelData;
|
|
import net.minecraftforge.client.model.data.ModelDataMap;
|
|
import net.minecraftforge.client.model.data.ModelProperty;
|
|
|
|
import appeng.api.networking.GridFlags;
|
|
import appeng.api.networking.events.MENetworkChannelsChanged;
|
|
import appeng.api.networking.events.MENetworkEventSubscribe;
|
|
import appeng.api.networking.events.MENetworkPowerStatusChange;
|
|
import appeng.me.GridAccessException;
|
|
import appeng.me.cluster.IAEMultiBlock;
|
|
import appeng.me.cluster.implementations.SpatialPylonCalculator;
|
|
import appeng.me.cluster.implementations.SpatialPylonCluster;
|
|
import appeng.me.helpers.AENetworkProxy;
|
|
import appeng.me.helpers.AENetworkProxyMultiblock;
|
|
import appeng.tile.grid.AENetworkTileEntity;
|
|
|
|
public class SpatialPylonTileEntity extends AENetworkTileEntity implements IAEMultiBlock<SpatialPylonCluster> {
|
|
|
|
public static final ModelProperty<Integer> STATE = new ModelProperty<>(value -> {
|
|
// The lower 6 bits are used
|
|
return (value & ~0x3F) == 0;
|
|
});
|
|
|
|
public static final int DISPLAY_END_MIN = 0x01;
|
|
public static final int DISPLAY_END_MAX = 0x02;
|
|
public static final int DISPLAY_MIDDLE = 0x01 + 0x02;
|
|
public static final int DISPLAY_X = 0x04;
|
|
public static final int DISPLAY_Y = 0x08;
|
|
public static final int DISPLAY_Z = 0x04 + 0x08;
|
|
public static final int MB_STATUS = 0x01 + 0x02 + 0x04 + 0x08;
|
|
|
|
public static final int DISPLAY_ENABLED = 0x10;
|
|
public static final int DISPLAY_POWERED_ENABLED = 0x20;
|
|
public static final int NET_STATUS = 0x10 + 0x20;
|
|
|
|
private final SpatialPylonCalculator calc = new SpatialPylonCalculator(this);
|
|
private int displayBits = 0;
|
|
private SpatialPylonCluster cluster;
|
|
private boolean didHaveLight = false;
|
|
|
|
public SpatialPylonTileEntity(TileEntityType<?> tileEntityTypeIn) {
|
|
super(tileEntityTypeIn);
|
|
this.getProxy().setFlags(GridFlags.REQUIRE_CHANNEL, GridFlags.MULTIBLOCK);
|
|
this.getProxy().setIdlePowerUsage(0.5);
|
|
this.getProxy().setValidSides(EnumSet.noneOf(Direction.class));
|
|
}
|
|
|
|
@Override
|
|
protected AENetworkProxy createProxy() {
|
|
return new AENetworkProxyMultiblock(this, "proxy", this.getItemFromTile(this), true);
|
|
}
|
|
|
|
@Override
|
|
public void onChunkUnloaded() {
|
|
this.disconnect(false);
|
|
super.onChunkUnloaded();
|
|
}
|
|
|
|
@Override
|
|
public void onReady() {
|
|
super.onReady();
|
|
this.calc.calculateMultiblock(world, pos);
|
|
}
|
|
|
|
@Override
|
|
public void remove() {
|
|
this.disconnect(false);
|
|
super.remove();
|
|
}
|
|
|
|
public void neighborChanged(BlockPos changedPos) {
|
|
this.calc.updateMultiblockAfterNeighborUpdate(this.world, pos, changedPos);
|
|
}
|
|
|
|
@Override
|
|
public void disconnect(final boolean b) {
|
|
if (this.cluster != null) {
|
|
this.cluster.destroy();
|
|
this.updateStatus(null);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public SpatialPylonCluster getCluster() {
|
|
return this.cluster;
|
|
}
|
|
|
|
@Override
|
|
public boolean isValid() {
|
|
return true;
|
|
}
|
|
|
|
public void updateStatus(final SpatialPylonCluster c) {
|
|
this.cluster = c;
|
|
this.getProxy().setValidSides(c == null ? EnumSet.noneOf(Direction.class) : EnumSet.allOf(Direction.class));
|
|
this.recalculateDisplay();
|
|
}
|
|
|
|
public void recalculateDisplay() {
|
|
final int oldBits = this.displayBits;
|
|
|
|
this.displayBits = 0;
|
|
|
|
if (this.cluster != null) {
|
|
if (this.cluster.getBoundsMin().equals(this.pos)) {
|
|
this.displayBits = DISPLAY_END_MIN;
|
|
} else if (this.cluster.getBoundsMax().equals(this.pos)) {
|
|
this.displayBits = DISPLAY_END_MAX;
|
|
} else {
|
|
this.displayBits = DISPLAY_MIDDLE;
|
|
}
|
|
|
|
switch (this.cluster.getCurrentAxis()) {
|
|
case X:
|
|
this.displayBits |= DISPLAY_X;
|
|
break;
|
|
case Y:
|
|
this.displayBits |= DISPLAY_Y;
|
|
break;
|
|
case Z:
|
|
this.displayBits |= DISPLAY_Z;
|
|
break;
|
|
default:
|
|
this.displayBits = 0;
|
|
break;
|
|
}
|
|
|
|
try {
|
|
if (this.getProxy().getEnergy().isNetworkPowered()) {
|
|
this.displayBits |= DISPLAY_POWERED_ENABLED;
|
|
}
|
|
|
|
if (this.cluster.isValid() && this.getProxy().isActive()) {
|
|
this.displayBits |= DISPLAY_ENABLED;
|
|
}
|
|
} catch (final GridAccessException e) {
|
|
// nothing?
|
|
}
|
|
}
|
|
|
|
if (oldBits != this.displayBits) {
|
|
this.markForUpdate();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void markForUpdate() {
|
|
super.markForUpdate();
|
|
final boolean hasLight = this.getLightValue() > 0;
|
|
if (hasLight != this.didHaveLight) {
|
|
this.didHaveLight = hasLight;
|
|
this.world.getLightManager().checkBlock(this.pos);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean canBeRotated() {
|
|
return false;
|
|
}
|
|
|
|
public int getLightValue() {
|
|
if ((this.displayBits & DISPLAY_POWERED_ENABLED) == DISPLAY_POWERED_ENABLED) {
|
|
return 8;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
@Override
|
|
protected boolean readFromStream(final PacketBuffer data) throws IOException {
|
|
final boolean c = super.readFromStream(data);
|
|
final int old = this.displayBits;
|
|
this.displayBits = data.readByte();
|
|
return old != this.displayBits || c;
|
|
}
|
|
|
|
@Override
|
|
protected void writeToStream(final PacketBuffer data) throws IOException {
|
|
super.writeToStream(data);
|
|
data.writeByte(this.displayBits);
|
|
}
|
|
|
|
@MENetworkEventSubscribe
|
|
public void powerRender(final MENetworkPowerStatusChange c) {
|
|
this.recalculateDisplay();
|
|
}
|
|
|
|
@MENetworkEventSubscribe
|
|
public void activeRender(final MENetworkChannelsChanged c) {
|
|
this.recalculateDisplay();
|
|
}
|
|
|
|
public int getDisplayBits() {
|
|
return this.displayBits;
|
|
}
|
|
|
|
@Nonnull
|
|
@Override
|
|
public IModelData getModelData() {
|
|
// FIXME: Must force model data update on changes, should potentially be moved
|
|
// to block state (?)
|
|
return new ModelDataMap.Builder().withInitial(STATE, getDisplayBits()).build();
|
|
}
|
|
|
|
}
|