diff --git a/src/main/java/com/hbm/blocks/ModBlocks.java b/src/main/java/com/hbm/blocks/ModBlocks.java index 99824c4d8..87269420e 100644 --- a/src/main/java/com/hbm/blocks/ModBlocks.java +++ b/src/main/java/com/hbm/blocks/ModBlocks.java @@ -1248,6 +1248,7 @@ public class ModBlocks { public static Block wand_loot; public static Block wand_jigsaw; public static Block wand_logic; + public static Block wand_tandem; public static Block logic_block; @@ -2411,6 +2412,7 @@ public class ModBlocks { wand_loot = new BlockWandLoot().setBlockName("wand_loot").setBlockTextureName(RefStrings.MODID + ":wand_loot"); wand_jigsaw = new BlockWandJigsaw().setBlockName("wand_jigsaw").setBlockTextureName(RefStrings.MODID + ":wand_jigsaw"); wand_logic = new BlockWandLogic().setBlockName("wand_logic").setBlockTextureName(RefStrings.MODID + ":wand_logic"); + wand_tandem = new BlockWandTandem().setBlockName("wand_tandem").setBlockTextureName(RefStrings.MODID + ":wand_tandem"); logic_block = new LogicBlock().setBlockName("logic_block").setBlockTextureName(RefStrings.MODID + ":logic_block"); @@ -3569,6 +3571,7 @@ public class ModBlocks { register(wand_loot); register(wand_jigsaw); register(wand_logic); + register(wand_tandem); register(logic_block); } diff --git a/src/main/java/com/hbm/blocks/generic/BlockWandTandem.java b/src/main/java/com/hbm/blocks/generic/BlockWandTandem.java new file mode 100644 index 000000000..1ad176e63 --- /dev/null +++ b/src/main/java/com/hbm/blocks/generic/BlockWandTandem.java @@ -0,0 +1,438 @@ +package com.hbm.blocks.generic; + +import java.util.ArrayList; +import java.util.List; + +import org.lwjgl.input.Keyboard; + +import com.hbm.blocks.IBlockSideRotation; +import com.hbm.blocks.ILookOverlay; +import com.hbm.blocks.ModBlocks; +import com.hbm.interfaces.IControlReceiver; +import com.hbm.items.ModItems; +import com.hbm.lib.RefStrings; +import com.hbm.main.MainRegistry; +import com.hbm.packet.PacketDispatcher; +import com.hbm.packet.toserver.NBTControlPacket; +import com.hbm.tileentity.IGUIProvider; +import com.hbm.tileentity.TileEntityLoadedBase; +import com.hbm.util.BufferUtil; +import com.hbm.util.i18n.I18nUtil; +import com.hbm.util.fauxpointtwelve.BlockPos; +import com.hbm.world.gen.nbt.INBTBlockTransformable; +import com.hbm.world.gen.nbt.NBTStructure; +import com.hbm.world.gen.nbt.NBTStructure.JigsawConnection; +import com.hbm.world.gen.nbt.SpawnCondition; +import com.hbm.world.gen.nbt.JigsawPiece; +import com.hbm.world.gen.nbt.JigsawPool; + +import cpw.mods.fml.common.network.internal.FMLNetworkHandler; +import cpw.mods.fml.common.registry.GameRegistry; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import io.netty.buffer.ByteBuf; +import net.minecraft.block.Block; +import net.minecraft.block.BlockContainer; +import net.minecraft.block.BlockPistonBase; +import net.minecraft.block.material.Material; +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.gui.GuiTextField; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.inventory.Container; +import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.IIcon; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; +import net.minecraftforge.client.event.RenderGameOverlayEvent.Pre; +import net.minecraftforge.common.util.ForgeDirection; + +/** + * You're familiar with Billy Mitchell, World Video Game Champion? He could probably do it. + * So I gotta find a way to harness his power. And I think I've found a way. + * + * THAT'S RIGHT, WE'RE GONNA CHEAT. + * + * NBTStructures have the inherent flaws of the vanilla structure system: Structures are composed + * before terrain gen even kicks in, placement order of components are arbitrary and certain + * connected parts will fall apart due to unexpected variance in the terrain. Not good. + * The solution: Simply delay generation of parts using a tile entity that checks if the chunks + * in front of it are loaded, and then places a random part from the chosen pool. When this happens, + * the player is usually still far far away so they'll be none the wiser. Chunk load checks help + * prevent forced chunk loading and all the lag that comes with that. + * + * The system is named after tandem shaped charges: Make a hole with the first charge, then deliver + * the actual payload. + * + * @author hbm, Mellow + */ +public class BlockWandTandem extends BlockContainer implements IBlockSideRotation, INBTBlockTransformable, IGUIProvider, ILookOverlay { + + private IIcon iconTop; + private IIcon iconSide; + private IIcon iconBack; + + public BlockWandTandem() { + super(Material.iron); + } + + @Override + public TileEntity createNewTileEntity(World world, int meta) { + return new TileEntityWandTandem(); + } + + @Override + public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase player, ItemStack stack) { + int l = BlockPistonBase.determineOrientation(world, x, y, z, player); + world.setBlockMetadataWithNotify(x, y, z, l, 2); + } + + @Override + @SideOnly(Side.CLIENT) + public void registerBlockIcons(IIconRegister iconRegister) { + this.blockIcon = iconRegister.registerIcon(RefStrings.MODID + ":wand_tandem"); + this.iconTop = iconRegister.registerIcon(RefStrings.MODID + ":wand_tandem_top"); + this.iconSide = iconRegister.registerIcon(RefStrings.MODID + ":wand_tandem_side"); + this.iconBack = iconRegister.registerIcon(RefStrings.MODID + ":wand_tandem_back"); + } + + @Override + public IIcon getIcon(int side, int meta) { + if(side == meta) return blockIcon; + if(IBlockSideRotation.isOpposite(side, meta)) return iconBack; + if(side <= 1) return iconTop; + if(side > 3 && meta <= 1) return iconTop; + return iconSide; + } + + @Override + public int getRotationFromSide(IBlockAccess world, int x, int y, int z, int side) { + if(side == 0) return IBlockSideRotation.topToBottom(getRotationFromSide(world, x, y, z, 1)); + + int meta = world.getBlockMetadata(x, y, z); + if(side == meta || IBlockSideRotation.isOpposite(side, meta)) return 0; + + // downwards facing has no changes, upwards flips anything not handled already + if(meta == 0) return 0; + if(meta == 1) return 3; + + // top (and bottom) is rotated fairly normally + if(side == 1) { + switch(meta) { + case 2: return 3; + case 3: return 0; + case 4: return 1; + case 5: return 2; + } + } + + // you know what I aint explaining further, it's a fucking mess here + if(meta == 2) return side == 4 ? 2 : 1; + if(meta == 3) return side == 4 ? 1 : 2; + if(meta == 4) return side == 2 ? 1 : 2; + if(meta == 5) return side == 2 ? 2 : 1; + + return 0; + } + + @Override + public int getRenderType() { + return IBlockSideRotation.getRenderType(); + } + + @Override + public int transformMeta(int meta, int coordBaseMode) { + return INBTBlockTransformable.transformMetaDeco(meta, coordBaseMode); + } + + @Override + public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ) { + TileEntity te = world.getTileEntity(x, y, z); + + if(!(te instanceof TileEntityWandTandem)) return false; + + TileEntityWandTandem jigsaw = (TileEntityWandTandem) te; + + if(player.getHeldItem() != null && player.getHeldItem().getItem() == Items.paper) { + TileEntityWandTandem.copyMode = true; + if(!player.getHeldItem().hasTagCompound()) { + player.getHeldItem().stackTagCompound = new NBTTagCompound(); + jigsaw.writeToNBT(player.getHeldItem().stackTagCompound); + } else { + jigsaw.readFromNBT(player.getHeldItem().stackTagCompound); + jigsaw.markDirty(); + } + TileEntityWandTandem.copyMode = false; + return true; + } + + if(!player.isSneaking()) { + Block block = getBlock(world, player.getHeldItem()); + if(block == ModBlocks.wand_air) block = Blocks.air; + + if(block != null && block != ModBlocks.wand_jigsaw && block != ModBlocks.wand_loot) { + jigsaw.replaceBlock = block; + jigsaw.replaceMeta = player.getHeldItem().getItemDamage(); + jigsaw.markDirty(); + + return true; + } + + if(player.getHeldItem() != null && player.getHeldItem().getItem() == ModItems.wand_s) return false; + + if(world.isRemote) FMLNetworkHandler.openGui(player, MainRegistry.instance, 0, world, x, y, z); + + return true; + } + + return false; + } + + private Block getBlock(World world, ItemStack stack) { + if(stack == null) return null; + if(!(stack.getItem() instanceof ItemBlock)) return null; + + return ((ItemBlock) stack.getItem()).field_150939_a; + } + + @Override + @SideOnly(Side.CLIENT) + public Object provideGUI(int ID, EntityPlayer player, World world, int x, int y, int z) { + return new GuiWandTandem((TileEntityWandTandem) world.getTileEntity(x, y, z)); + } + + @Override + public Container provideContainer(int ID, EntityPlayer player, World world, int x, int y, int z) { + return null; + } + + @Override + public void printHook(Pre event, World world, int x, int y, int z) { + TileEntity te = world.getTileEntity(x, y, z); + if(!(te instanceof TileEntityWandTandem)) return; + TileEntityWandTandem jigsaw = (TileEntityWandTandem) te; + + List text = new ArrayList(); + + text.add(EnumChatFormatting.GRAY + "Target pool: " + EnumChatFormatting.RESET + jigsaw.pool); + text.add(EnumChatFormatting.GRAY + "Target name: " + EnumChatFormatting.RESET + jigsaw.target); + text.add(EnumChatFormatting.GRAY + "Turns into: " + EnumChatFormatting.RESET + GameRegistry.findUniqueIdentifierFor(jigsaw.replaceBlock).toString()); + text.add(EnumChatFormatting.GRAY + " with meta: " + EnumChatFormatting.RESET + jigsaw.replaceMeta); + text.add(EnumChatFormatting.GRAY + "Joint type: " + EnumChatFormatting.RESET + (jigsaw.isRollable ? "Rollable" : "Aligned")); + + ILookOverlay.printGeneric(event, I18nUtil.resolveKey(getUnlocalizedName() + ".name"), 0xffff00, 0x404000, text); + } + + + public static class TileEntityWandTandem extends TileEntityLoadedBase implements IControlReceiver { + + public static boolean copyMode = false; + + private String pool = "default"; + private String target = "default"; + private Block replaceBlock = Blocks.air; + private int replaceMeta = 0; + private boolean isRollable = true; // sets joint type, rollable joints can be placed in any orientation for vertical jigsaw connections + + private boolean isArmed = false; + private SpawnCondition structure; + + @Override + public void updateEntity() { + if(!worldObj.isRemote) { + tryGenerate(); + networkPackNT(15); + } + } + + private void tryGenerate() { + if(!this.isArmed || target == null || target.isEmpty() || pool == null || pool.isEmpty()) return; + + JigsawPool pool = structure.getPool(this.pool); + if(pool == null) return; + + JigsawPiece nextPiece = pool.get(worldObj.rand); + if(nextPiece == null) return; + + ForgeDirection dir = ForgeDirection.getOrientation(this.getBlockMetadata()); + + List connectionPool = nextPiece.structure.getConnectionPool(dir, target); + if(connectionPool == null) return; + + JigsawConnection toConnection = connectionPool.get(worldObj.rand.nextInt(connectionPool.size())); + int nextCoordBase = directionOffsetToCoordBase(dir.getOpposite(), toConnection.dir); + + BlockPos pos = new BlockPos(xCoord + dir.offsetX, yCoord + dir.offsetY, zCoord + dir.offsetZ); + + // offset the starting point to the connecting point + int ox = nextPiece.structure.rotateX(toConnection.pos.x, toConnection.pos.z, nextCoordBase); + int oy = toConnection.pos.y; + int oz = nextPiece.structure.rotateZ(toConnection.pos.x, toConnection.pos.z, nextCoordBase); + + nextPiece.structure.build(worldObj, nextPiece, pos.getX() - ox, pos.getY() - oy, pos.getZ() - oz, nextCoordBase, structure.name); + + worldObj.setBlock(xCoord, yCoord, zCoord, replaceBlock, replaceMeta, 2); + } + + private int directionOffsetToCoordBase(ForgeDirection from, ForgeDirection to) { + for(int i = 0; i < 4; i++) { + if(from == to) return i % 4; + from = from.getRotation(ForgeDirection.DOWN); + } + return 0; + } + + @Override + public void serialize(ByteBuf buf) { + BufferUtil.writeString(buf, pool); + BufferUtil.writeString(buf, target); + buf.writeInt(Block.getIdFromBlock(replaceBlock)); + buf.writeInt(replaceMeta); + buf.writeBoolean(isRollable); + } + + @Override + public void deserialize(ByteBuf buf) { + pool = BufferUtil.readString(buf); + target = BufferUtil.readString(buf); + replaceBlock = Block.getBlockById(buf.readInt()); + replaceMeta = buf.readInt(); + isRollable = buf.readBoolean(); + } + + @Override + public void writeToNBT(NBTTagCompound nbt) { + if(!copyMode) { + super.writeToNBT(nbt); + nbt.setInteger("direction", this.getBlockMetadata()); + if(isArmed) { + nbt.setBoolean("isArmed", isArmed); + nbt.setString("structure", structure.name); + } + } + + nbt.setString("pool", pool); + nbt.setString("target", target); + nbt.setString("block", GameRegistry.findUniqueIdentifierFor(replaceBlock).toString()); + nbt.setInteger("meta", replaceMeta); + nbt.setBoolean("roll", isRollable); + } + + @Override + public void readFromNBT(NBTTagCompound nbt) { + if(!copyMode) { + super.readFromNBT(nbt); + isArmed = nbt.getBoolean("isArmed"); + structure = NBTStructure.getStructure(nbt.getString("structure")); + } + + pool = nbt.getString("pool"); + target = nbt.getString("target"); + replaceBlock = Block.getBlockFromName(nbt.getString("block")); + replaceMeta = nbt.getInteger("meta"); + isRollable = nbt.getBoolean("roll"); + } + + @Override + public boolean hasPermission(EntityPlayer player) { + return true; + } + + @Override + public void receiveControl(NBTTagCompound nbt) { + readFromNBT(nbt); + markDirty(); + } + + public void arm(SpawnCondition structure) { + isArmed = true; + this.structure = structure; + } + + } + + public static class GuiWandTandem extends GuiScreen { + + private final TileEntityWandTandem jigsaw; + + private GuiTextField textPool; + private GuiTextField textTarget; + + private GuiButton jointToggle; + + public GuiWandTandem(TileEntityWandTandem jigsaw) { + this.jigsaw = jigsaw; + } + + @Override + public void initGui() { + Keyboard.enableRepeatEvents(true); + + textPool = new GuiTextField(fontRendererObj, this.width / 2 - 150, 50, 300, 20); + textPool.setText(jigsaw.pool); + + textTarget = new GuiTextField(fontRendererObj, this.width / 2 + 10, 100, 140, 20); + textTarget.setText(jigsaw.target); + + jointToggle = new GuiButton(0, this.width / 2 + 60, 150, 90, 20, jigsaw.isRollable ? "Rollable" : "Aligned"); + } + + @Override + public void drawScreen(int mouseX, int mouseY, float partialTicks) { + drawDefaultBackground(); + + drawString(fontRendererObj, "Target pool:", this.width / 2 - 150, 37, 0xA0A0A0); + textPool.drawTextBox(); + + drawString(fontRendererObj, "Target name:", this.width / 2 + 10, 87, 0xA0A0A0); + textTarget.drawTextBox(); + + drawString(fontRendererObj, "Joint type:", this.width / 2 + 60, 137, 0xA0A0A0); + jointToggle.drawButton(mc, mouseX, mouseY); + + super.drawScreen(mouseX, mouseY, partialTicks); + } + + @Override + public void onGuiClosed() { + Keyboard.enableRepeatEvents(false); + + NBTTagCompound data = new NBTTagCompound(); + jigsaw.writeToNBT(data); + + data.setString("pool", textPool.getText()); + data.setString("target", textTarget.getText()); + data.setBoolean("roll", jointToggle.displayString == "Rollable"); + + PacketDispatcher.wrapper.sendToServer(new NBTControlPacket(data, jigsaw.xCoord, jigsaw.yCoord, jigsaw.zCoord)); + } + + @Override + protected void keyTyped(char typedChar, int keyCode) { + super.keyTyped(typedChar, keyCode); + textPool.textboxKeyTyped(typedChar, keyCode); + textTarget.textboxKeyTyped(typedChar, keyCode); + } + + @Override + protected void mouseClicked(int mouseX, int mouseY, int mouseButton) { + super.mouseClicked(mouseX, mouseY, mouseButton); + textPool.mouseClicked(mouseX, mouseY, mouseButton); + textTarget.mouseClicked(mouseX, mouseY, mouseButton); + + if(jointToggle.mousePressed(mc, mouseX, mouseY)) { + jointToggle.displayString = jointToggle.displayString == "Rollable" ? "Aligned" : "Rollable"; + } + } + + @Override public boolean doesGuiPauseGame() { return false; } + } +} \ No newline at end of file diff --git a/src/main/java/com/hbm/commands/CommandLocate.java b/src/main/java/com/hbm/commands/CommandLocate.java index b0a7f8948..ec646c817 100644 --- a/src/main/java/com/hbm/commands/CommandLocate.java +++ b/src/main/java/com/hbm/commands/CommandLocate.java @@ -21,7 +21,7 @@ import net.minecraft.world.World; public class CommandLocate extends CommandBase { - private static final int MAX_DISTANCE = 256; + private static final int MAX_DISTANCE = 256; @Override public String getCommandName() { diff --git a/src/main/java/com/hbm/main/StructureManager.java b/src/main/java/com/hbm/main/StructureManager.java index 077a3665f..e740331f3 100644 --- a/src/main/java/com/hbm/main/StructureManager.java +++ b/src/main/java/com/hbm/main/StructureManager.java @@ -68,5 +68,7 @@ public class StructureManager { // public static final NBTStructure test_jigsaw = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/test-jigsaw.nbt")); // public static final NBTStructure test_jigsaw_core = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/test-jigsaw-core.nbt")); // public static final NBTStructure test_jigsaw_hall = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/test-jigsaw-hall.nbt")); + // public static final NBTStructure test_tandem_core = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/test-tandem-core.nbt")); + // public static final NBTStructure test_tandem = new NBTStructure(new ResourceLocation(RefStrings.MODID, "structures/test-tandem.nbt")); } diff --git a/src/main/java/com/hbm/tileentity/TileMappings.java b/src/main/java/com/hbm/tileentity/TileMappings.java index bae45ddca..63bc3640e 100644 --- a/src/main/java/com/hbm/tileentity/TileMappings.java +++ b/src/main/java/com/hbm/tileentity/TileMappings.java @@ -20,6 +20,7 @@ import com.hbm.blocks.generic.BlockSnowglobe.TileEntitySnowglobe; import com.hbm.blocks.generic.BlockSupplyCrate.TileEntitySupplyCrate; import com.hbm.blocks.generic.BlockWandJigsaw.TileEntityWandJigsaw; import com.hbm.blocks.generic.BlockWandLoot.TileEntityWandLoot; +import com.hbm.blocks.generic.BlockWandTandem.TileEntityWandTandem; import com.hbm.blocks.generic.BlockWandLogic.TileEntityWandLogic; import com.hbm.blocks.generic.DungeonSpawner.TileEntityDungeonSpawner; import com.hbm.blocks.generic.LogicBlock; @@ -243,6 +244,7 @@ public class TileMappings { put(TileEntityWandLoot.class, "tileentity_wand_loot"); put(TileEntityWandJigsaw.class, "tileentity_wand_jigsaw"); put(TileEntityWandLogic.class, "tileentity_wand_spawner"); + put(TileEntityWandTandem.class, "tileentity_wand_tandem"); putNetwork(); putBombs(); diff --git a/src/main/java/com/hbm/world/gen/nbt/NBTStructure.java b/src/main/java/com/hbm/world/gen/nbt/NBTStructure.java index 385644257..2bf7de38c 100644 --- a/src/main/java/com/hbm/world/gen/nbt/NBTStructure.java +++ b/src/main/java/com/hbm/world/gen/nbt/NBTStructure.java @@ -9,6 +9,7 @@ import java.util.function.Predicate; import com.hbm.blocks.ModBlocks; import com.hbm.blocks.generic.BlockWand; +import com.hbm.blocks.generic.BlockWandTandem.TileEntityWandTandem; import com.hbm.config.GeneralConfig; import com.hbm.config.StructureConfig; import com.hbm.handler.ThreeInts; @@ -421,7 +422,7 @@ public class NBTStructure { return worldItemPalette; } - private TileEntity buildTileEntity(World world, Block block, HashMap worldItemPalette, NBTTagCompound nbt, int coordBaseMode) { + private TileEntity buildTileEntity(World world, Block block, HashMap worldItemPalette, NBTTagCompound nbt, int coordBaseMode, String structureName) { nbt = (NBTTagCompound)nbt.copy(); if(worldItemPalette != null) relinkItems(worldItemPalette, nbt); @@ -432,6 +433,10 @@ public class NBTStructure { ((INBTTileEntityTransformable) te).transformTE(world, coordBaseMode); } + if(te instanceof TileEntityWandTandem) { + ((TileEntityWandTandem) te).arm(getStructure(structureName)); + } + return te; } @@ -471,7 +476,7 @@ public class NBTStructure { world.setBlock(rx, ry, rz, block, meta, 2); if(state.nbt != null) { - TileEntity te = buildTileEntity(world, block, worldItemPalette, state.nbt, coordBaseMode); + TileEntity te = buildTileEntity(world, block, worldItemPalette, state.nbt, coordBaseMode, null); world.setTileEntity(rx, ry, rz, te); } } @@ -479,7 +484,23 @@ public class NBTStructure { } } - protected boolean build(World world, JigsawPiece piece, StructureBoundingBox totalBounds, StructureBoundingBox generatingBounds, int coordBaseMode) { + // Used to construct tandems + public void build(World world, JigsawPiece piece, int x, int y, int z, int coordBaseMode, String structureName) { + StructureBoundingBox bb; + switch(coordBaseMode) { + case 1: + case 3: + bb = new StructureBoundingBox(x, y, z, x + piece.structure.size.z - 1, y + piece.structure.size.y - 1, z + piece.structure.size.x - 1); + break; + default: + bb = new StructureBoundingBox(x, y, z, x + piece.structure.size.x - 1, y + piece.structure.size.y - 1, z + piece.structure.size.z - 1); + break; + } + + build(world, piece, bb, bb, coordBaseMode, structureName); + } + + protected boolean build(World world, JigsawPiece piece, StructureBoundingBox totalBounds, StructureBoundingBox generatingBounds, int coordBaseMode, String structureName) { if(!isLoaded) { MainRegistry.logger.info("NBTStructure is invalid"); return false; @@ -528,7 +549,7 @@ public class NBTStructure { world.setBlock(rx, ry, rz, block, meta, 2); if(state.nbt != null) { - TileEntity te = buildTileEntity(world, block, worldItemPalette, state.nbt, coordBaseMode); + TileEntity te = buildTileEntity(world, block, worldItemPalette, state.nbt, coordBaseMode, structureName); world.setTileEntity(rx, ry, rz, te); } } @@ -538,6 +559,16 @@ public class NBTStructure { return true; } + public List getConnectionPool(ForgeDirection dir, String target) { + if(dir == ForgeDirection.DOWN) { + return toTopConnections.get(target); + } else if(dir == ForgeDirection.UP) { + return toBottomConnections.get(target); + } + + return toHorizontalConnections.get(target); + } + // What a fucken mess, why even implement the IntArray NBT if ye aint gonna use it Moe Yang? private ThreeInts parsePos(NBTTagList pos) { NBTBase xb = (NBTBase)pos.tagList.get(0); @@ -605,7 +636,7 @@ public class NBTStructure { return definition.meta; } - private int rotateX(int x, int z, int coordBaseMode) { + public int rotateX(int x, int z, int coordBaseMode) { switch(coordBaseMode) { case 1: return size.z - 1 - z; case 2: return size.x - 1 - x; @@ -614,7 +645,7 @@ public class NBTStructure { } } - private int rotateZ(int x, int z, int coordBaseMode) { + public int rotateZ(int x, int z, int coordBaseMode) { switch(coordBaseMode) { case 1: return x; case 2: return size.z - 1 - z; @@ -673,10 +704,10 @@ public class NBTStructure { } // Each jigsaw block in a structure will instance one of these - private static class JigsawConnection { + public static class JigsawConnection { - private final ThreeInts pos; - private final ForgeDirection dir; + public final ThreeInts pos; + public final ForgeDirection dir; // what pool should we look through to find a connection private final String poolName; @@ -772,14 +803,14 @@ public class NBTStructure { if(!piece.conformToTerrain && !heightUpdated) { int y = MathHelper.clamp_int(getAverageHeight(world, box) + piece.heightOffset, minHeight, maxHeight); - if(!piece.alignToTerrain && parent != null) { + if(!piece.alignToTerrain) { parent.offsetYHeight(y); } else { offsetYHeight(y); } } - return piece.structure.build(world, piece, boundingBox, box, coordBaseMode); + return piece.structure.build(world, piece, boundingBox, box, coordBaseMode, parent.name); } public void offsetYHeight(int y) { @@ -876,12 +907,16 @@ public class NBTStructure { public static class Start extends StructureStart { + public String name; + public Start() {} @SuppressWarnings("unchecked") public Start(World world, Random rand, SpawnCondition spawn, int chunkX, int chunkZ) { super(chunkX, chunkZ); + name = spawn.name; + int x = chunkX << 4; int z = chunkZ << 4; @@ -966,7 +1001,7 @@ public class NBTStructure { } if(GeneralConfig.enableDebugMode) { - MainRegistry.logger.info("[Debug] Spawning NBT structure with " + components.size() + " piece(s) at: " + chunkX * 16 + ", " + chunkZ * 16); + MainRegistry.logger.info("[Debug] Spawning NBT structure " + name + " with " + components.size() + " piece(s) at: " + chunkX * 16 + ", " + chunkZ * 16); String componentList = "[Debug] Components: "; for(Object component : this.components) { componentList += ((Component) component).piece.structure.name + " "; @@ -1005,7 +1040,7 @@ public class NBTStructure { return null; } - List connectionPool = getConnectionPool(nextPiece, fromConnection); + List connectionPool = nextPiece.structure.getConnectionPool(fromConnection.dir, fromConnection.targetName); if(connectionPool == null || connectionPool.isEmpty()) { MainRegistry.logger.warn("[Jigsaw] No valid connections for: " + fromConnection.targetName + " - in piece: " + nextPiece.name); return null; @@ -1026,16 +1061,6 @@ public class NBTStructure { return new Component(spawn, nextPiece, rand, pos.getX() - ox, pos.getY() - oy, pos.getZ() - oz, nextCoordBase).connectedFrom(toConnection); } - private List getConnectionPool(JigsawPiece nextPiece, JigsawConnection fromConnection) { - if(fromConnection.dir == ForgeDirection.DOWN) { - return nextPiece.structure.toTopConnections.get(fromConnection.targetName); - } else if(fromConnection.dir == ForgeDirection.UP) { - return nextPiece.structure.toBottomConnections.get(fromConnection.targetName); - } - - return nextPiece.structure.toHorizontalConnections.get(fromConnection.targetName); - } - private int getDistanceTo(StructureBoundingBox box) { int x = box.getCenterX(); int z = box.getCenterZ(); @@ -1045,12 +1070,19 @@ public class NBTStructure { // post loading, update parent reference for loaded components @Override - public void func_143017_b(NBTTagCompound nbt) { + public void func_143017_b(NBTTagCompound nbt) { // readFromNBT + name = nbt.getString("name"); + for(Object o : components) { ((Component) o).parent = this; } } + @Override + public void func_143022_a(NBTTagCompound nbt) { // writeToNBT + nbt.setString("name", name); + } + public void offsetYHeight(int y) { for(Object o : components) { Component component = (Component) o; diff --git a/src/main/java/com/hbm/world/gen/nbt/SpawnCondition.java b/src/main/java/com/hbm/world/gen/nbt/SpawnCondition.java index b623ea864..f84d3aad8 100644 --- a/src/main/java/com/hbm/world/gen/nbt/SpawnCondition.java +++ b/src/main/java/com/hbm/world/gen/nbt/SpawnCondition.java @@ -64,7 +64,7 @@ public class SpawnCondition { return canSpawn.test(biome); } - protected JigsawPool getPool(String name) { + public JigsawPool getPool(String name) { JigsawPool pool = pools.get(name); return pool != null ? pool.clone() : null; } diff --git a/src/main/resources/assets/hbm/structures/test-tandem-core.nbt b/src/main/resources/assets/hbm/structures/test-tandem-core.nbt new file mode 100644 index 000000000..34a426eac Binary files /dev/null and b/src/main/resources/assets/hbm/structures/test-tandem-core.nbt differ diff --git a/src/main/resources/assets/hbm/structures/test-tandem.nbt b/src/main/resources/assets/hbm/structures/test-tandem.nbt new file mode 100644 index 000000000..ba23b9b0c Binary files /dev/null and b/src/main/resources/assets/hbm/structures/test-tandem.nbt differ diff --git a/src/main/resources/assets/hbm/textures/blocks/wand_tandem.png b/src/main/resources/assets/hbm/textures/blocks/wand_tandem.png new file mode 100644 index 000000000..ea5f193b7 Binary files /dev/null and b/src/main/resources/assets/hbm/textures/blocks/wand_tandem.png differ diff --git a/src/main/resources/assets/hbm/textures/blocks/wand_tandem_back.png b/src/main/resources/assets/hbm/textures/blocks/wand_tandem_back.png new file mode 100644 index 000000000..acd39e0e5 Binary files /dev/null and b/src/main/resources/assets/hbm/textures/blocks/wand_tandem_back.png differ diff --git a/src/main/resources/assets/hbm/textures/blocks/wand_tandem_side.png b/src/main/resources/assets/hbm/textures/blocks/wand_tandem_side.png new file mode 100644 index 000000000..7389799c1 Binary files /dev/null and b/src/main/resources/assets/hbm/textures/blocks/wand_tandem_side.png differ diff --git a/src/main/resources/assets/hbm/textures/blocks/wand_tandem_top.png b/src/main/resources/assets/hbm/textures/blocks/wand_tandem_top.png new file mode 100644 index 000000000..373951004 Binary files /dev/null and b/src/main/resources/assets/hbm/textures/blocks/wand_tandem_top.png differ