/* * 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 . */ 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 getOriginalBlockPlacer() { return (w, p)->w.setBlockState(p, getOriginalBlock()); } @Nullable public 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 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; } }