/* * 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.mech_mb; import blusunrize.immersiveengineering.api.MultiblockHandler; import blusunrize.immersiveengineering.api.crafting.IngredientStack; import malte0811.industrialWires.IndustrialWires; import malte0811.industrialWires.blocks.converter.MechanicalMBBlockType; import malte0811.industrialWires.blocks.converter.TileEntityMechMB; import malte0811.industrialWires.util.LocalSidedWorld; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import java.util.ArrayList; import java.util.List; import java.util.function.BiConsumer; import java.util.function.Consumer; import static malte0811.industrialWires.blocks.converter.MechanicalMBBlockType.*; public class MultiblockMechMB implements MultiblockHandler.IMultiblock { public static MultiblockMechMB INSTANCE; @Override public String getUniqueName() { return IndustrialWires.MODID+":mech_mb"; } @Override public boolean isBlockTrigger(IBlockState state) { return MechMBPart.isValidDefaultCenter(state); } private boolean checkEnd(LocalSidedWorld w, BlockPos.PooledMutableBlockPos p) { p.setPos(0, 0, 0); if (!MechMBPart.isValidDefaultCenter(w.getBlockState(p))) { return false; } p.setPos(0, -1, 0); return MechMBPart.isValidDefaultCenter(w.getBlockState(p)); } private void formEnd(LocalSidedWorld w, BlockPos.PooledMutableBlockPos p, MechanicalMBBlockType type, BiConsumer init) { p.setPos(0, 0, 0); w.setBlockState(p, IndustrialWires.mechanicalMB.getStateFromMeta(type.ordinal())); TileEntity te = w.getTileEntity(p); if (te instanceof TileEntityMechMB) { init.accept((TileEntityMechMB) te, true); } p.setPos(0, -1, 0); w.setBlockState(p, IndustrialWires.mechanicalMB.getStateFromMeta(NO_MODEL.ordinal())); te = w.getTileEntity(p); if (te instanceof TileEntityMechMB) { init.accept((TileEntityMechMB) te, false); } } @Override public boolean createStructure(World world, BlockPos pos, EnumFacing side, EntityPlayer player) { if (side.getAxis().isVertical()) return false; BlockPos.PooledMutableBlockPos mutPos = BlockPos.PooledMutableBlockPos.retain(); try { LocalSidedWorld w = new LocalSidedWorld(world, pos, side.getOpposite(), false); if (!checkEnd(w, mutPos)) { return false; } boolean foundAll = false; List parts = new ArrayList<>(); int lastLength = 1; double weight = 0; while (!foundAll) { mutPos.setPos(0, 0, lastLength); w.setOrigin(w.getRealPos(mutPos)); MechMBPart next = null; List instances = new ArrayList<>(MechMBPart.INSTANCES.values()); instances.sort(MechMBPart.SORT_BY_COUNT.reversed()); MechMBPart last = instances.get(0); for (MechMBPart part:instances) { if (MechMBPart.SORT_BY_COUNT.compare(last, part)!=0&& checkEnd(w, mutPos)) { foundAll = true; break; } last = part; if (part.canForm(w)) { next = part; String key = MechMBPart.REGISTRY.inverse().get(part.getClass()); MechMBPart.cacheNewInstance(key); break; } } if (next != null) { parts.add(next); lastLength = next.getLength(); weight += next.getInertia(); } else if (!foundAll) { return false; } } double finalWeight = weight; w.setOrigin(pos); formEnd(w, mutPos, END, (te, master) -> { if (master) { te.offset = BlockPos.ORIGIN; te.setMechanical(parts.toArray(new MechMBPart[0]), 0); te.energyState = new MechEnergy(finalWeight, 0); } else { te.offset = new BlockPos(0, -1, 0); } te.facing = side; te.formed = true; }); lastLength = 1; Consumer init = (te) -> { te.offset = te.getPos().subtract(pos); te.facing = side; te.formed = true; }; for (MechMBPart part : parts) { mutPos.setPos(0, 0, lastLength); w = new LocalSidedWorld(world, w.getRealPos(mutPos), w.getFacing(), w.isMirrored()); part.form(w, init); lastLength = part.getLength(); } mutPos.setPos(0, 0, lastLength); w = new LocalSidedWorld(w.getWorld(), w.getRealPos(mutPos), w.getFacing(), w.isMirrored()); formEnd(w, mutPos, OTHER_END, (te, __) -> init.accept(te)); return true; } finally { mutPos.release(); } } ItemStack[][][] fakeStructure = {{{new ItemStack(Blocks.COMMAND_BLOCK)}}}; IngredientStack[] fakeMats = {new IngredientStack(fakeStructure[0][0][0])}; @Override public ItemStack[][][] getStructureManual() { return fakeStructure; } @Override public IngredientStack[] getTotalMaterials() { return fakeMats; } @Override public boolean overwriteBlockRender(ItemStack stack, int iterator) { return false; } @Override public float getManualScale() { return 1; } @Override public boolean canRenderFormedStructure() { return false; } @Override public void renderFormedStructure() { } }