a756de6ace
Fix crashes without IC2
175 lines
5.5 KiB
Java
175 lines
5.5 KiB
Java
/*
|
|
* This file is part of Industrial Wires.
|
|
* Copyright (C) 2016-2018 malte0811
|
|
* Industrial Wires is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
* Industrial Wires 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 General Public License for more details.
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with Industrial Wires. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
package malte0811.industrialWires.blocks;
|
|
|
|
import blusunrize.immersiveengineering.common.blocks.IEBlockInterfaces.IDirectionalTile;
|
|
import blusunrize.immersiveengineering.common.blocks.IEBlockInterfaces.IGeneralMultiblock;
|
|
import malte0811.industrialWires.util.MiscUtils;
|
|
import net.minecraft.block.state.IBlockState;
|
|
import net.minecraft.entity.EntityLivingBase;
|
|
import net.minecraft.entity.item.EntityItem;
|
|
import net.minecraft.item.ItemStack;
|
|
import net.minecraft.nbt.NBTTagCompound;
|
|
import net.minecraft.tileentity.TileEntity;
|
|
import net.minecraft.util.EnumFacing;
|
|
import net.minecraft.util.math.BlockPos;
|
|
import net.minecraft.util.math.Vec3i;
|
|
import net.minecraft.world.World;
|
|
|
|
import javax.annotation.Nonnull;
|
|
import javax.annotation.Nullable;
|
|
import java.util.function.BiConsumer;
|
|
|
|
public abstract class TileEntityIWMultiblock extends TileEntityIWBase implements IGeneralMultiblock,
|
|
IDirectionalTile {
|
|
protected final static String OFFSET = "offset";
|
|
protected final static String FORMED = "formed";
|
|
protected final static String MIRRORED = "mirrored";
|
|
protected final static String FACING = "facing";
|
|
//HFR
|
|
protected Vec3i size;
|
|
public Vec3i offset = new Vec3i(0, 1, 0);
|
|
public boolean formed;
|
|
public boolean mirrored;
|
|
public long onlyLocalDissassembly;
|
|
public EnumFacing facing = EnumFacing.NORTH;
|
|
@Nonnull
|
|
protected abstract BlockPos getOrigin();
|
|
public abstract IBlockState getOriginalBlock();
|
|
public ItemStack getOriginalItem() {
|
|
IBlockState state = getOriginalBlock();
|
|
return new ItemStack(state.getBlock(), 1, state.getBlock().getMetaFromState(state));
|
|
}
|
|
public BiConsumer<World, BlockPos> getOriginalBlockPlacer() {
|
|
return (w, p)->w.setBlockState(p, getOriginalBlock());
|
|
}
|
|
@Nullable
|
|
public <T extends TileEntityIWMultiblock> T master(T here) {
|
|
if (!isLogicDummy()) {
|
|
return here;
|
|
}
|
|
TileEntity m = world.getTileEntity(pos.subtract(offset));
|
|
if (m!=null&&m.getClass().equals(this.getClass())) {
|
|
return (T) m;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public boolean isLogicDummy() {
|
|
return offset.getX()!=0||offset.getY()!=0||offset.getZ()!=0;
|
|
}
|
|
|
|
@Nonnull
|
|
public <T extends TileEntityIWMultiblock> T masterOr(T here, @Nonnull T def) {
|
|
T master = master(here);
|
|
return master!=null?master:def;
|
|
}
|
|
public void disassemble() {
|
|
if (formed && !world.isRemote) {
|
|
BlockPos startPos = getOrigin();
|
|
BlockPos masterPos = getPos().subtract(offset);
|
|
long time = world.getTotalWorldTime();
|
|
Vec3i size = getSize();
|
|
for (int up = 0; up < size.getX(); up++) {
|
|
for (int forward = 0; forward < size.getY(); forward++) {
|
|
for (int right = 0; right < size.getZ(); right++) {
|
|
BlockPos pos = MiscUtils.offset(startPos, facing, mirrored, right, forward, up);
|
|
TileEntity te = world.getTileEntity(pos);
|
|
if (te instanceof TileEntityIWMultiblock) {
|
|
TileEntityIWMultiblock part = (TileEntityIWMultiblock) te;
|
|
Vec3i diff = pos.subtract(masterPos);
|
|
if (part.offset.equals(diff) && time != part.onlyLocalDissassembly) {
|
|
part.formed = false;
|
|
if (!pos.equals(this.pos)) {
|
|
part.getOriginalBlockPlacer().accept(world, pos);
|
|
} else if (part.getOriginalBlock()!=null) {
|
|
ItemStack drop = getOriginalItem();
|
|
world.spawnEntity(new EntityItem(world, pos.getX()+.5,pos.getY()+.5,pos.getZ()+.5, drop));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void writeNBT(NBTTagCompound out, boolean updatePacket) {
|
|
out.setInteger(FACING, facing.getHorizontalIndex());
|
|
out.setIntArray(OFFSET, new int[]{offset.getX(), offset.getY(), offset.getZ()});
|
|
out.setBoolean(MIRRORED, mirrored);
|
|
out.setBoolean(FORMED, formed);
|
|
}
|
|
|
|
@Override
|
|
public void readNBT(NBTTagCompound in, boolean updatePacket) {
|
|
formed = in.getBoolean(FORMED);
|
|
mirrored = in.getBoolean(MIRRORED);
|
|
int[] offset = in.getIntArray(OFFSET);
|
|
this.offset = new Vec3i(offset[0], offset[1], offset[2]);
|
|
facing = EnumFacing.getHorizontal(in.getInteger(FACING));
|
|
}
|
|
|
|
public Vec3i getSize() {
|
|
return size;
|
|
}
|
|
|
|
public int getRight() {
|
|
return dot(offset, facing.rotateY().getDirectionVec())*(mirrored?-1:1);
|
|
}
|
|
|
|
public int getForward() {
|
|
return dot(offset, facing.getDirectionVec());
|
|
}
|
|
|
|
protected int dot(Vec3i a, Vec3i b) {
|
|
return a.getX()*b.getX()+a.getY()*b.getY()+a.getZ()*b.getZ();
|
|
}
|
|
|
|
|
|
@Nonnull
|
|
@Override
|
|
public EnumFacing getFacing() {
|
|
return facing;
|
|
}
|
|
|
|
@Override
|
|
public void setFacing(@Nonnull EnumFacing facing) {
|
|
this.facing = facing;
|
|
}
|
|
|
|
@Override
|
|
public int getFacingLimitation() {
|
|
return 2;
|
|
}
|
|
|
|
@Override
|
|
public boolean mirrorFacingOnPlacement(@Nonnull EntityLivingBase placer) {
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public boolean canHammerRotate(@Nonnull EnumFacing side, float hitX, float hitY, float hitZ, @Nonnull EntityLivingBase entity) {
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public boolean canRotate(@Nonnull EnumFacing axis) {
|
|
return false;
|
|
}
|
|
}
|