Merge pull request #2012 from MellowArpeggiation/master

More NBTStructure improvements from OUTER SPACE
This commit is contained in:
HbmMods 2025-03-26 09:28:00 +01:00 committed by GitHub
commit 4e08e107a8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 255 additions and 115 deletions

View File

@ -4,6 +4,7 @@ import java.util.Random;
import com.hbm.blocks.ModBlocks;
import com.hbm.items.ModItems;
import com.hbm.world.gen.INBTTransformable;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@ -20,7 +21,7 @@ import net.minecraft.util.Vec3;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
public class BlockModDoor extends Block {
public class BlockModDoor extends Block implements INBTTransformable {
@SideOnly(Side.CLIENT)
private IIcon[] field_150017_a;
@SideOnly(Side.CLIENT)
@ -234,7 +235,7 @@ public class BlockModDoor extends Block {
}
p_149727_1_.playSoundEffect(p_149727_2_, p_149727_3_, p_149727_4_, "hbm:block.openDoor", 1.0F, p_149727_1_.rand.nextFloat() * 0.1F + 0.9F);
return true;
}
@ -311,10 +312,10 @@ public class BlockModDoor extends Block {
}
public Item getItemDropped(int p_149650_1_, Random p_149650_2_, int p_149650_3_) {
if((p_149650_1_ & 8) != 0)
return null;
if (this == ModBlocks.door_metal)
return ModItems.door_metal;
else if (this == ModBlocks.door_office)
@ -396,4 +397,9 @@ public class BlockModDoor extends Block {
p_149681_1_.setBlockToAir(p_149681_2_, p_149681_3_ - 1, p_149681_4_);
}
}
}
@Override
public int transformMeta(int meta, int coordBaseMode) {
return INBTTransformable.transformMetaDoor(meta, coordBaseMode);
}
}

View File

@ -5,6 +5,8 @@ import java.util.Random;
import com.hbm.blocks.IBlockMulti;
import com.hbm.blocks.ITooltipProvider;
import com.hbm.world.gen.INBTTileEntityTransformable;
import com.hbm.world.gen.INBTTransformable;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@ -27,7 +29,7 @@ import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.StatCollector;
import net.minecraft.world.World;
public class BlockPlushie extends BlockContainer implements IBlockMulti, ITooltipProvider {
public class BlockPlushie extends BlockContainer implements IBlockMulti, ITooltipProvider, INBTTransformable {
public BlockPlushie() {
super(Material.cloth);
@ -37,7 +39,7 @@ public class BlockPlushie extends BlockContainer implements IBlockMulti, IToolti
@Override public boolean isOpaqueCube() { return false; }
@Override public boolean renderAsNormalBlock() { return false; }
@Override public Item getItemDropped(int i, Random rand, int j) { return null; }
@Override
public ItemStack getPickBlock(MovingObjectPosition target, World world, int x, int y, int z, EntityPlayer player) {
TileEntityPlushie entity = (TileEntityPlushie) world.getTileEntity(x, y, z);
@ -47,7 +49,7 @@ public class BlockPlushie extends BlockContainer implements IBlockMulti, IToolti
@Override
public void onBlockHarvested(World world, int x, int y, int z, int meta, EntityPlayer player) {
if(!player.capabilities.isCreativeMode) {
harvesters.set(player);
if(!world.isRemote) {
@ -63,7 +65,7 @@ public class BlockPlushie extends BlockContainer implements IBlockMulti, IToolti
harvesters.set(null);
}
}
@Override
public void harvestBlock(World world, EntityPlayer player, int x, int y, int z, int meta) {
player.addStat(StatList.mineBlockStatArray[getIdFromBlock(this)], 1);
@ -80,7 +82,7 @@ public class BlockPlushie extends BlockContainer implements IBlockMulti, IToolti
public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase player, ItemStack stack) {
int meta = MathHelper.floor_double((double)((player.rotationYaw + 180.0F) * 16.0F / 360.0F) + 0.5D) & 15;
world.setBlockMetadataWithNotify(x, y, z, meta, 2);
TileEntityPlushie plushie = (TileEntityPlushie) world.getTileEntity(x, y, z);
plushie.type = PlushieType.values()[Math.abs(stack.getItemDamage()) % PlushieType.values().length];
plushie.markDirty();
@ -93,7 +95,7 @@ public class BlockPlushie extends BlockContainer implements IBlockMulti, IToolti
@Override
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ) {
if(world.isRemote) {
TileEntityPlushie plushie = (TileEntityPlushie) world.getTileEntity(x, y, z);
plushie.squishTimer = 11;
@ -104,8 +106,13 @@ public class BlockPlushie extends BlockContainer implements IBlockMulti, IToolti
}
}
public static class TileEntityPlushie extends TileEntity {
@Override
public int transformMeta(int meta, int coordBaseMode) {
return (meta + coordBaseMode * 4) % 16;
}
public static class TileEntityPlushie extends TileEntity implements INBTTileEntityTransformable {
public PlushieType type = PlushieType.NONE;
public int squishTimer;
@ -120,7 +127,7 @@ public class BlockPlushie extends BlockContainer implements IBlockMulti, IToolti
this.writeToNBT(nbt);
return new S35PacketUpdateTileEntity(this.xCoord, this.yCoord, this.zCoord, 0, nbt);
}
@Override
public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) {
this.readFromNBT(pkt.func_148857_g());
@ -137,8 +144,13 @@ public class BlockPlushie extends BlockContainer implements IBlockMulti, IToolti
super.writeToNBT(nbt);
nbt.setByte("type", (byte) type.ordinal());
}
@Override
public void transformTE(World world, int coordBaseMode) {
type = PlushieType.values()[world.rand.nextInt(PlushieType.values().length - 1) + 1];
}
}
public static enum PlushieType {
NONE( "NONE", null),
YOMI( "Yomi", "Hi! Can I be your rabbit friend?"),
@ -147,7 +159,7 @@ public class BlockPlushie extends BlockContainer implements IBlockMulti, IToolti
public String label;
public String inscription;
private PlushieType(String label, String inscription) {
this.label = label;
this.inscription = inscription;

View File

@ -9,6 +9,7 @@ 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;
@ -144,6 +145,8 @@ public class BlockWandJigsaw extends BlockContainer implements IBlockSideRotatio
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;

View File

@ -12,6 +12,7 @@ import com.hbm.blocks.ModBlocks;
import com.hbm.config.StructureConfig;
import com.hbm.itempool.ItemPool;
import com.hbm.lib.RefStrings;
import com.hbm.main.MainRegistry;
import com.hbm.tileentity.TileEntityLoadedBase;
import com.hbm.util.BufferUtil;
import com.hbm.util.I18nUtil;
@ -248,6 +249,11 @@ public class BlockWandLoot extends BlockContainer implements ILookOverlay, ITool
}
private void replace() {
if(!(worldObj.getBlock(xCoord, yCoord, zCoord) instanceof BlockWandLoot)) {
MainRegistry.logger.warn("Somehow the block at: " + xCoord + ", " + yCoord + ", " + zCoord + " isn't a loot block but we're doing a TE update as if it is, cancelling!");
return;
}
WeightedRandomChestContent[] pool = ItemPool.getPool(poolName);
worldObj.setBlock(xCoord, yCoord, zCoord, replaceBlock, replaceMeta, 2);

View File

@ -1,6 +1,7 @@
package com.hbm.blocks.machine;
import com.hbm.main.MainRegistry;
import com.hbm.world.gen.INBTTransformable;
import cpw.mods.fml.common.network.internal.FMLNetworkHandler;
import net.minecraft.block.Block;
@ -16,8 +17,8 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
public abstract class BlockMachineBase extends BlockContainer {
public abstract class BlockMachineBase extends BlockContainer implements INBTTransformable {
int guiID = -1;
protected boolean rotatable = false;
@ -25,13 +26,13 @@ public abstract class BlockMachineBase extends BlockContainer {
super(mat);
this.guiID = guiID;
}
@Override
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ) {
if(guiID == -1)
return false;
if(world.isRemote) {
return true;
} else if(!player.isSneaking()) {
@ -41,9 +42,9 @@ public abstract class BlockMachineBase extends BlockContainer {
return false;
}
}
private static boolean keepInventory;
@Override
public void breakBlock(World world, int x, int y, int z, Block block, int meta) {
@ -96,18 +97,24 @@ public abstract class BlockMachineBase extends BlockContainer {
super.breakBlock(world, x, y, z, block, meta);
}
@Override
public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase player, ItemStack itemStack) {
if(!rotatable)
return;
int i = MathHelper.floor_double(player.rotationYaw * 4.0F / 360.0F + 0.5D) & 3;
if(i == 0) world.setBlockMetadataWithNotify(x, y, z, 2, 2);
if(i == 1) world.setBlockMetadataWithNotify(x, y, z, 5, 2);
if(i == 2) world.setBlockMetadataWithNotify(x, y, z, 3, 2);
if(i == 3) world.setBlockMetadataWithNotify(x, y, z, 4, 2);
}
}
@Override
public int transformMeta(int meta, int coordBaseMode) {
if(!rotatable) return meta;
return INBTTransformable.transformMetaDeco(meta, coordBaseMode);
}
}

View File

@ -4,6 +4,7 @@ import java.util.Random;
import com.hbm.main.MainRegistry;
import com.hbm.tileentity.machine.TileEntityMachineEPress;
import com.hbm.world.gen.INBTTransformable;
import cpw.mods.fml.common.network.internal.FMLNetworkHandler;
import net.minecraft.block.Block;
@ -19,7 +20,7 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
public class MachineEPress extends BlockContainer {
public class MachineEPress extends BlockContainer implements INBTTransformable {
private final Random field_149933_a = new Random();
private static boolean keepInventory;
@ -120,4 +121,9 @@ public class MachineEPress extends BlockContainer {
return false;
}
}
}
@Override
public int transformMeta(int meta, int coordBaseMode) {
return INBTTransformable.transformMetaDeco(meta, coordBaseMode);
}
}

View File

@ -15,6 +15,7 @@ import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.Block;
import net.minecraft.block.BlockSlab;
import net.minecraft.block.material.Material;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
@ -26,6 +27,8 @@ import net.minecraftforge.common.util.ForgeDirection;
public class Spotlight extends Block implements ISpotlight, INBTTransformable {
public static boolean disableOnGeneration = true;
// I'd be extending the ReinforcedLamp class if it wasn't for the inverted behaviour of these specific lights
// I want these blocks to be eminently useful, so removing the need for redstone by default is desired,
// these act more like redstone torches, in that applying a signal turns them off
@ -220,6 +223,31 @@ public class Spotlight extends Block implements ISpotlight, INBTTransformable {
return ForgeDirection.getOrientation(metadata >> 1);
}
// Replace bulbs on broken lights with a click
@Override
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ) {
int meta = world.getBlockMetadata(x, y, z);
if(!isBroken(meta)) return false;
repair(world, x, y, z);
return true;
}
private void repair(World world, int x, int y, int z) {
int meta = world.getBlockMetadata(x, y, z);
if(!isBroken(meta)) return;
world.setBlock(x, y, z, getOn(), meta - 1, 2);
for(ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
int ox = x + dir.offsetX;
int oy = y + dir.offsetY;
int oz = z + dir.offsetZ;
Block block = world.getBlock(ox, oy, oz);
if(block == this) repair(world, ox, oy, oz);
}
}
public boolean isBroken(int metadata) {
return (metadata & 1) == 1;
}
@ -326,11 +354,13 @@ public class Spotlight extends Block implements ISpotlight, INBTTransformable {
@Override
public int transformMeta(int meta, int coordBaseMode) {
// +1 to set as broken, won't turn on until broken and replaced
return (INBTTransformable.transformMetaDeco(meta >> 1, coordBaseMode) << 1) + 1;
int disabled = disableOnGeneration ? 1 : 0;
return (INBTTransformable.transformMetaDeco(meta >> 1, coordBaseMode) << 1) + disabled;
}
@Override
public Block transformBlock(Block block) {
if(!disableOnGeneration) return block;
if(block == ModBlocks.spotlight_incandescent) return ModBlocks.spotlight_incandescent_off;
if(block == ModBlocks.spotlight_fluoro) return ModBlocks.spotlight_fluoro_off;
if(block == ModBlocks.spotlight_halogen) return ModBlocks.spotlight_halogen_off;

View File

@ -206,4 +206,9 @@ public abstract class RBMKBase extends BlockDummyable implements IToolable, ILoo
public static int renderIDRods = RenderingRegistry.getNextAvailableRenderId();
public static int renderIDPassive = RenderingRegistry.getNextAvailableRenderId();
public static int renderIDControl = RenderingRegistry.getNextAvailableRenderId();
}
@Override
public int transformMeta(int meta, int coordBaseMode) {
return meta;
}
}

View File

@ -2,8 +2,11 @@ package com.hbm.items.tool;
import java.util.List;
import com.hbm.blocks.ModBlocks;
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
@ -11,98 +14,87 @@ import net.minecraft.util.ChatComponentText;
import net.minecraft.world.World;
public class ItemWand extends Item {
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public void addInformation(ItemStack itemstack, EntityPlayer player, List list, boolean bool)
{
public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean bool) {
list.add("Creative-only item");
list.add("\"Destruction brings creation\"");
list.add("(Set positions with right click,");
list.add("set block with shift-right click!)");
if(itemstack.stackTagCompound != null &&
!(itemstack.stackTagCompound.getInteger("x") == 0 &&
itemstack.stackTagCompound.getInteger("y") == 0 &&
itemstack.stackTagCompound.getInteger("z") == 0))
{
list.add("Pos: " + itemstack.stackTagCompound.getInteger("x") + ", " + itemstack.stackTagCompound.getInteger("y") + ", " + itemstack.stackTagCompound.getInteger("z"));
if(stack.stackTagCompound != null && !(stack.stackTagCompound.getInteger("x") == 0 && stack.stackTagCompound.getInteger("y") == 0 && stack.stackTagCompound.getInteger("z") == 0)) {
list.add("Pos: " + stack.stackTagCompound.getInteger("x") + ", " + stack.stackTagCompound.getInteger("y") + ", " + stack.stackTagCompound.getInteger("z"));
} else {
list.add("Positions not set!");
}
if(itemstack.stackTagCompound != null)
list.add("Block saved: " + Block.getBlockById(itemstack.stackTagCompound.getInteger("block")).getUnlocalizedName());
if(stack.stackTagCompound != null)
list.add("Block saved: " + Block.getBlockById(stack.stackTagCompound.getInteger("block")).getUnlocalizedName());
}
@Override
public boolean onItemUse(ItemStack p_77648_1_, EntityPlayer p_77648_2_, World p_77648_3_, int p_77648_4_, int p_77648_5_, int p_77648_6_, int p_77648_7_, float p_77648_8_, float p_77648_9_, float p_77648_10_)
{
if(p_77648_1_.stackTagCompound == null)
{
p_77648_1_.stackTagCompound = new NBTTagCompound();
public boolean onItemUse(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, float fx, float fy, float fz) {
if(stack.stackTagCompound == null) {
stack.stackTagCompound = new NBTTagCompound();
}
if(p_77648_2_.isSneaking())
{
p_77648_1_.stackTagCompound.setInteger("block", Block.getIdFromBlock(p_77648_3_.getBlock(p_77648_4_, p_77648_5_, p_77648_6_)));
p_77648_1_.stackTagCompound.setInteger("meta", p_77648_3_.getBlockMetadata(p_77648_4_, p_77648_5_, p_77648_6_));
if(p_77648_3_.isRemote)
p_77648_2_.addChatMessage(new ChatComponentText("Set block " + Block.getBlockById(p_77648_1_.stackTagCompound.getInteger("block")).getUnlocalizedName()));
if(player.isSneaking()) {
stack.stackTagCompound.setInteger("block", Block.getIdFromBlock(world.getBlock(x, y, z)));
stack.stackTagCompound.setInteger("meta", world.getBlockMetadata(x, y, z));
if(world.isRemote)
player.addChatMessage(new ChatComponentText("Set block " + Block.getBlockById(stack.stackTagCompound.getInteger("block")).getUnlocalizedName()));
} else {
if(p_77648_1_.stackTagCompound.getInteger("x") == 0 &&
p_77648_1_.stackTagCompound.getInteger("y") == 0 &&
p_77648_1_.stackTagCompound.getInteger("z") == 0)
{
p_77648_1_.stackTagCompound.setInteger("x", p_77648_4_);
p_77648_1_.stackTagCompound.setInteger("y", p_77648_5_);
p_77648_1_.stackTagCompound.setInteger("z", p_77648_6_);
if(p_77648_3_.isRemote)
p_77648_2_.addChatMessage(new ChatComponentText("Position set!"));
if(stack.stackTagCompound.getInteger("x") == 0 && stack.stackTagCompound.getInteger("y") == 0 && stack.stackTagCompound.getInteger("z") == 0) {
stack.stackTagCompound.setInteger("x", x);
stack.stackTagCompound.setInteger("y", y);
stack.stackTagCompound.setInteger("z", z);
if(world.isRemote)
player.addChatMessage(new ChatComponentText("Position set!"));
} else {
int x = p_77648_1_.stackTagCompound.getInteger("x");
int y = p_77648_1_.stackTagCompound.getInteger("y");
int z = p_77648_1_.stackTagCompound.getInteger("z");
p_77648_1_.stackTagCompound.setInteger("x", 0);
p_77648_1_.stackTagCompound.setInteger("y", 0);
p_77648_1_.stackTagCompound.setInteger("z", 0);
if(!p_77648_3_.isRemote)
{
for(int i = Math.min(x, p_77648_4_); i <= Math.max(x, p_77648_4_); i++)
{
for(int j = Math.min(y, p_77648_5_); j <= Math.max(y, p_77648_5_); j++)
{
for(int k = Math.min(z, p_77648_6_); k <= Math.max(z, p_77648_6_); k++)
{
p_77648_3_.setBlock(i, j, k, Block.getBlockById(p_77648_1_.stackTagCompound.getInteger("block")), p_77648_1_.stackTagCompound.getInteger("meta"), 3);
int ox = stack.stackTagCompound.getInteger("x");
int oy = stack.stackTagCompound.getInteger("y");
int oz = stack.stackTagCompound.getInteger("z");
stack.stackTagCompound.setInteger("x", 0);
stack.stackTagCompound.setInteger("y", 0);
stack.stackTagCompound.setInteger("z", 0);
if(!world.isRemote) {
Block block = Block.getBlockById(stack.stackTagCompound.getInteger("block"));
int meta = stack.stackTagCompound.getInteger("meta");
boolean replaceAir = block == ModBlocks.wand_air;
for(int i = Math.min(ox, x); i <= Math.max(ox, x); i++) {
for(int j = Math.min(oy, y); j <= Math.max(oy, y); j++) {
for(int k = Math.min(oz, z); k <= Math.max(oz, z); k++) {
if(replaceAir && world.getBlock(i, j, k) != Blocks.air) continue;
world.setBlock(i, j, k, block, meta, 3);
}
}
}
}
if(p_77648_3_.isRemote)
p_77648_2_.addChatMessage(new ChatComponentText("Selection filled!"));
if(world.isRemote)
player.addChatMessage(new ChatComponentText("Selection filled!"));
}
}
return true;
}
return true;
}
@Override
public ItemStack onItemRightClick(ItemStack stack, World world, EntityPlayer player) {
if(stack.stackTagCompound == null)
{
if(stack.stackTagCompound == null) {
stack.stackTagCompound = new NBTTagCompound();
}
if(player.isSneaking())
{
if(player.isSneaking()) {
stack.stackTagCompound.setInteger("block", 0);
stack.stackTagCompound.setInteger("meta", 0);
if(world.isRemote)
player.addChatMessage(new ChatComponentText("Set block " + Block.getBlockById(stack.stackTagCompound.getInteger("block")).getUnlocalizedName()));
}
return stack;
}
}
}

View File

@ -16,6 +16,7 @@ import com.hbm.handler.ThreeInts;
import com.hbm.main.MainRegistry;
import com.hbm.util.Tuple.Pair;
import com.hbm.util.Tuple.Quartet;
import com.hbm.util.fauxpointtwelve.BlockPos;
import cpw.mods.fml.common.registry.GameRegistry;
import net.minecraft.block.*;
@ -94,7 +95,7 @@ public class NBTStructure {
}
}
public static void registerStructure(SpawnCondition spawn, int... dimensionIds) {
public static void registerStructure(SpawnCondition spawn, int[] dimensionIds) {
for(int dimensionId : dimensionIds) {
registerStructure(dimensionId, spawn);
}
@ -265,6 +266,10 @@ public class NBTStructure {
}
palette[i] = new BlockDefinition(blockName, meta);
if(StructureConfig.debugStructures && palette[i].block == Blocks.air) {
palette[i] = new BlockDefinition(ModBlocks.wand_air, meta);
}
}
@ -349,7 +354,7 @@ public class NBTStructure {
if(connections.size() > 0) {
fromConnections = new ArrayList<>();
connections.sort((a, b) -> a.selectionPriority - b.selectionPriority); // sort by descending priority, highest first
connections.sort((a, b) -> b.selectionPriority - a.selectionPriority); // sort by descending priority, highest first
// Sort out our from connections, splitting into individual lists for each priority level
List<JigsawConnection> innerList = null;
@ -439,7 +444,7 @@ public class NBTStructure {
int ry = by + y;
Block block = transformBlock(state.definition, null, world.rand);
int meta = coordBaseMode != 0 ? transformMeta(state.definition, coordBaseMode) : state.definition.meta;
int meta = transformMeta(state.definition, null, coordBaseMode);
world.setBlock(rx, ry, rz, block, meta, 2);
@ -496,7 +501,7 @@ public class NBTStructure {
int ry = by + oy;
Block block = transformBlock(state.definition, piece.blockTable, world.rand);
int meta = coordBaseMode != 0 ? transformMeta(state.definition, coordBaseMode) : state.definition.meta;
int meta = transformMeta(state.definition, piece.blockTable, coordBaseMode);
world.setBlock(rx, ry, rz, block, meta, 2);
@ -552,10 +557,16 @@ public class NBTStructure {
return definition.block;
}
private int transformMeta(BlockDefinition definition, int coordBaseMode) {
private int transformMeta(BlockDefinition definition, Map<Block, BlockSelector> blockTable, int coordBaseMode) {
if(blockTable != null && blockTable.containsKey(definition.block)) {
return blockTable.get(definition.block).getSelectedBlockMetaData();
}
// Our shit
if(definition.block instanceof INBTTransformable) return ((INBTTransformable) definition.block).transformMeta(definition.meta, coordBaseMode);
if(coordBaseMode == 0) return definition.meta;
// Vanilla shit
if(definition.block instanceof BlockStairs) return INBTTransformable.transformMetaStairs(definition.meta, coordBaseMode);
if(definition.block instanceof BlockRotatedPillar) return INBTTransformable.transformMetaPillar(definition.meta, coordBaseMode);
@ -566,6 +577,7 @@ public class NBTStructure {
if(definition.block instanceof BlockLever) return INBTTransformable.transformMetaLever(definition.meta, coordBaseMode);
if(definition.block instanceof BlockSign) return INBTTransformable.transformMetaDeco(definition.meta, coordBaseMode);
if(definition.block instanceof BlockLadder) return INBTTransformable.transformMetaDeco(definition.meta, coordBaseMode);
if(definition.block instanceof BlockTripWireHook) return INBTTransformable.transformMetaDirectional(definition.meta, coordBaseMode);
return definition.meta;
}
@ -630,6 +642,11 @@ public class NBTStructure {
this.meta = meta;
}
BlockDefinition(Block block, int meta) {
this.block = block;
this.meta = meta;
}
}
public static class SpawnCondition {
@ -670,6 +687,31 @@ public class NBTStructure {
return pools.get(name).clone();
}
// Builds all of the pools into neat rows and columns, for editing and debugging!
// Make sure structure debug is enabled, or it will no-op
// Do not use in generation
public void buildAll(World world, int x, int y, int z) {
if(!StructureConfig.debugStructures) return;
int padding = 5;
int oz = 0;
for(JigsawPool pool : pools.values()) {
int highestWidth = 0;
int ox = 0;
for(Pair<JigsawPiece, Integer> entry : pool.pieces) {
NBTStructure structure = entry.key.structure;
structure.build(world, x + ox + (structure.size.x / 2), y, z + oz + (structure.size.z / 2));
ox += structure.size.x + padding;
highestWidth = Math.max(highestWidth, structure.size.z);
}
oz += highestWidth + padding;
}
}
}
// A set of pieces with weights
@ -790,7 +832,7 @@ public class NBTStructure {
boolean heightUpdated = false;
int priority; // placement priority not yet implemented because selection priority is far more useful whatever
int priority;
// this is fucking hacky but we need a way to update ALL component bounds once a Y-level is determined
private Start parent;
@ -941,6 +983,17 @@ public class NBTStructure {
return false;
}
protected boolean isInsideIgnoringSelf(LinkedList<StructureComponent> components, int x, int y, int z) {
for(StructureComponent component : components) {
if(component == this) continue;
if(component.getBoundingBox() == null) continue;
if(component.getBoundingBox().isVecInside(x, y, z)) return true;
}
return false;
}
}
public static class Start extends StructureStart {
@ -966,7 +1019,15 @@ public class NBTStructure {
// Iterate through and build out all the components we intend to spawn
while(!queuedComponents.isEmpty()) {
final int i = rand.nextInt(queuedComponents.size());
queuedComponents.sort((a, b) -> b.priority - a.priority); // sort by placement priority descending
int matchPriority = queuedComponents.get(0).priority;
int max = 1;
while(max < queuedComponents.size()) {
if(queuedComponents.get(max).priority != matchPriority) break;
max++;
}
final int i = rand.nextInt(max);
Component fromComponent = queuedComponents.remove(i);
if(fromComponent.piece.structure.fromConnections == null) continue;
@ -1008,9 +1069,14 @@ public class NBTStructure {
queuedComponents.add(nextComponent);
} else {
// If we failed to fit anything in, grab something from the fallback pool, ignoring bounds check
// unless we are perfectly abutting another piece, so grid layouts can work!
if(nextPool.fallback != null) {
nextComponent = buildNextComponent(rand, spawn, spawn.pools.get(nextPool.fallback), fromComponent, fromConnection);
addComponent(nextComponent, fromConnection.placementPriority); // don't add to queued list, we don't want to try continue from fallback
BlockPos checkPos = getConnectionTargetPosition(fromComponent, fromConnection);
if(!fromComponent.isInsideIgnoringSelf(components, checkPos.getX(), checkPos.getY(), checkPos.getZ())) {
nextComponent = buildNextComponent(rand, spawn, spawn.pools.get(nextPool.fallback), fromComponent, fromConnection);
addComponent(nextComponent, fromConnection.placementPriority); // don't add to queued list, we don't want to try continue from fallback
}
}
}
}
@ -1031,12 +1097,25 @@ public class NBTStructure {
@SuppressWarnings("unchecked")
private void addComponent(Component component, int placementPriority) {
if(component == null) return;
components.add(component);
component.parent = this;
component.priority = placementPriority;
}
private BlockPos getConnectionTargetPosition(Component component, JigsawConnection connection) {
// The direction this component is extending towards in ABSOLUTE direction
ForgeDirection extendDir = component.rotateDir(connection.dir);
// Set the starting point for the next structure to the location of the connector block
int x = component.getXWithOffset(connection.pos.x, connection.pos.z) + extendDir.offsetX;
int y = component.getYWithOffset(connection.pos.y) + extendDir.offsetY;
int z = component.getZWithOffset(connection.pos.x, connection.pos.z) + extendDir.offsetZ;
return new BlockPos(x, y, z);
}
private Component buildNextComponent(Random rand, SpawnCondition spawn, JigsawPool pool, Component fromComponent, JigsawConnection fromConnection) {
JigsawPiece nextPiece = pool.get(rand);
if(nextPiece == null) return null;
@ -1046,23 +1125,17 @@ public class NBTStructure {
JigsawConnection toConnection = connectionPool.get(rand.nextInt(connectionPool.size()));
// The direction this component is extending towards in ABSOLUTE direction
ForgeDirection extendDir = fromComponent.rotateDir(fromConnection.dir);
// Rotate our incoming piece to plug it in
int nextCoordBase = fromComponent.getNextCoordBase(fromConnection, toConnection, rand);
// Set the starting point for the next structure to the location of the connector block
int nextX = fromComponent.getXWithOffset(fromConnection.pos.x, fromConnection.pos.z) + extendDir.offsetX;
int nextY = fromComponent.getYWithOffset(fromConnection.pos.y) + extendDir.offsetY;
int nextZ = fromComponent.getZWithOffset(fromConnection.pos.x, fromConnection.pos.z) + extendDir.offsetZ;
BlockPos pos = getConnectionTargetPosition(fromComponent, fromConnection);
// offset the starting point to the connecting point
nextX -= nextPiece.structure.rotateX(toConnection.pos.x, toConnection.pos.z, nextCoordBase);
nextY -= toConnection.pos.y;
nextZ -= nextPiece.structure.rotateZ(toConnection.pos.x, toConnection.pos.z, nextCoordBase);
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);
return new Component(spawn, nextPiece, rand, nextX, nextY, nextZ, nextCoordBase).connectedFrom(toConnection);
return new Component(spawn, nextPiece, rand, pos.getX() - ox, pos.getY() - oy, pos.getZ() - oz, nextCoordBase).connectedFrom(toConnection);
}
private List<JigsawConnection> getConnectionPool(JigsawPiece nextPiece, JigsawConnection fromConnection) {