mirror of
https://github.com/HbmMods/Hbm-s-Nuclear-Tech-GIT.git
synced 2026-01-25 10:32:49 +00:00
Merge pull request #2563 from MellowArpeggiation/structure-port
Structure Block!
This commit is contained in:
commit
03e7db5d92
@ -1261,6 +1261,7 @@ public class ModBlocks {
|
||||
public static Block wand_jigsaw;
|
||||
public static Block wand_logic;
|
||||
public static Block wand_tandem;
|
||||
public static Block wand_structure;
|
||||
|
||||
public static Block logic_block;
|
||||
|
||||
@ -2066,7 +2067,7 @@ public class ModBlocks {
|
||||
fusion_boiler = new MachineFusionBoiler().setBlockName("fusion_boiler").setHardness(5.0F).setResistance(60.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":block_steel");
|
||||
fusion_mhdt = new MachineFusionMHDT().setBlockName("fusion_mhdt").setHardness(5.0F).setResistance(60.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":block_steel");
|
||||
fusion_coupler = new MachineFusionCoupler().setBlockName("fusion_coupler").setHardness(5.0F).setResistance(60.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":block_steel");
|
||||
|
||||
|
||||
machine_icf_press = new MachineICFPress().setBlockName("machine_icf_press").setHardness(5.0F).setResistance(60.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":block_steel");
|
||||
icf = new MachineICF().setBlockName("icf").setHardness(5.0F).setResistance(60.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":block_steel");
|
||||
icf_component = new BlockICFComponent().setBlockName("icf_component").setHardness(5.0F).setResistance(60.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":icf_component");
|
||||
@ -2430,6 +2431,7 @@ public class ModBlocks {
|
||||
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");
|
||||
wand_structure = new BlockWandStructure().setBlockName("wand_structure");
|
||||
|
||||
logic_block = new LogicBlock().setBlockName("logic_block").setBlockTextureName(RefStrings.MODID + ":logic_block");
|
||||
|
||||
@ -3448,7 +3450,7 @@ public class ModBlocks {
|
||||
GameRegistry.registerBlock(plasma, ItemBlockLore.class, plasma.getUnlocalizedName());
|
||||
GameRegistry.registerBlock(iter, iter.getUnlocalizedName());
|
||||
GameRegistry.registerBlock(plasma_heater, plasma_heater.getUnlocalizedName());
|
||||
|
||||
|
||||
register(fusion_component);
|
||||
register(fusion_torus);
|
||||
register(fusion_klystron);
|
||||
@ -3603,6 +3605,7 @@ public class ModBlocks {
|
||||
register(wand_jigsaw);
|
||||
register(wand_logic);
|
||||
register(wand_tandem);
|
||||
register(wand_structure);
|
||||
|
||||
register(logic_block);
|
||||
}
|
||||
@ -3635,4 +3638,24 @@ public class ModBlocks {
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static Block getBlockFromStack(ItemStack stack) {
|
||||
if(stack == null) return null;
|
||||
if(!(stack.getItem() instanceof ItemBlock)) return null;
|
||||
|
||||
return ((ItemBlock) stack.getItem()).field_150939_a;
|
||||
}
|
||||
|
||||
// Is this block a special structure handling block, so we can ignore it for blacklist selection, etc.
|
||||
public static boolean isStructureBlock(Block block, boolean includeAir) {
|
||||
if(block == null) return false;
|
||||
if(block == wand_air) return includeAir;
|
||||
if(block == wand_structure) return true;
|
||||
if(block == wand_jigsaw) return true;
|
||||
if(block == wand_logic) return true;
|
||||
if(block == wand_tandem) return true;
|
||||
if(block == wand_loot) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -37,7 +37,6 @@ import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.init.Blocks;
|
||||
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;
|
||||
@ -135,10 +134,10 @@ public class BlockWandJigsaw extends BlockContainer implements IBlockSideRotatio
|
||||
TileEntityWandJigsaw jigsaw = (TileEntityWandJigsaw) te;
|
||||
|
||||
if(!player.isSneaking()) {
|
||||
Block block = getBlock(world, player.getHeldItem());
|
||||
Block block = ModBlocks.getBlockFromStack(player.getHeldItem());
|
||||
if(block == ModBlocks.wand_air) block = Blocks.air;
|
||||
|
||||
if(block != null && block != ModBlocks.wand_jigsaw && block != ModBlocks.wand_loot) {
|
||||
if(block != null && !ModBlocks.isStructureBlock(block, false)) {
|
||||
jigsaw.replaceBlock = block;
|
||||
jigsaw.replaceMeta = player.getHeldItem().getItemDamage();
|
||||
|
||||
@ -155,13 +154,6 @@ public class BlockWandJigsaw extends BlockContainer implements IBlockSideRotatio
|
||||
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) {
|
||||
|
||||
@ -33,7 +33,6 @@ import net.minecraft.client.renderer.texture.IIconRegister;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.item.ItemBlock;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
@ -82,7 +81,7 @@ public class BlockWandLoot extends BlockContainer implements ILookOverlay, ITool
|
||||
|
||||
@Override
|
||||
public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase player, ItemStack itemStack) {
|
||||
int i = MathHelper.floor_double(player.rotationYaw * 4.0F / 360.0F + 0.5D) & 3;
|
||||
int i = MathHelper.floor_double(player.rotationYaw * 4.0F / 360.0F + 0.5D) & 3;
|
||||
|
||||
if(i == 0) world.setBlockMetadataWithNotify(x, y, z, 3, 2);
|
||||
if(i == 1) world.setBlockMetadataWithNotify(x, y, z, 2, 2);
|
||||
@ -153,17 +152,14 @@ public class BlockWandLoot extends BlockContainer implements ILookOverlay, ITool
|
||||
}
|
||||
|
||||
private Block getLootableBlock(World world, ItemStack stack) {
|
||||
if(stack == null) return null;
|
||||
Block block = ModBlocks.getBlockFromStack(stack);
|
||||
if(block == null) return null;
|
||||
|
||||
if(stack.getItem() instanceof ItemBlock) {
|
||||
Block block = ((ItemBlock) stack.getItem()).field_150939_a;
|
||||
if(block == ModBlocks.deco_loot) return block;
|
||||
|
||||
if(block == ModBlocks.deco_loot) return block;
|
||||
|
||||
if(block instanceof ITileEntityProvider) {
|
||||
TileEntity te = ((ITileEntityProvider) block).createNewTileEntity(world, 12);
|
||||
if(te instanceof IInventory) return block;
|
||||
}
|
||||
if(block instanceof ITileEntityProvider) {
|
||||
TileEntity te = ((ITileEntityProvider) block).createNewTileEntity(world, 12);
|
||||
if(te instanceof IInventory) return block;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
573
src/main/java/com/hbm/blocks/generic/BlockWandStructure.java
Normal file
573
src/main/java/com/hbm/blocks/generic/BlockWandStructure.java
Normal file
@ -0,0 +1,573 @@
|
||||
package com.hbm.blocks.generic;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
|
||||
import com.hbm.blocks.IBlockMulti;
|
||||
import com.hbm.blocks.ILookOverlay;
|
||||
import com.hbm.blocks.ModBlocks;
|
||||
import com.hbm.config.StructureConfig;
|
||||
import com.hbm.interfaces.IControlReceiver;
|
||||
import com.hbm.inventory.gui.element.GuiFileList;
|
||||
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.Tuple.Pair;
|
||||
import com.hbm.util.i18n.I18nUtil;
|
||||
import com.hbm.world.gen.nbt.NBTStructure;
|
||||
|
||||
import cpw.mods.fml.common.network.internal.FMLNetworkHandler;
|
||||
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.material.Material;
|
||||
import net.minecraft.client.Minecraft;
|
||||
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.creativetab.CreativeTabs;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.event.ClickEvent;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.inventory.Container;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.AxisAlignedBB;
|
||||
import net.minecraft.util.ChatComponentText;
|
||||
import net.minecraft.util.EnumChatFormatting;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.client.event.RenderGameOverlayEvent.Pre;
|
||||
|
||||
public class BlockWandStructure extends BlockContainer implements IBlockMulti, IGUIProvider, ILookOverlay {
|
||||
|
||||
private IIcon saveIcon;
|
||||
private IIcon loadIcon;
|
||||
|
||||
public BlockWandStructure() {
|
||||
super(Material.iron);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileEntity createNewTileEntity(World worldIn, int meta) {
|
||||
return new TileEntityWandStructure();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void registerBlockIcons(IIconRegister iconRegister) {
|
||||
saveIcon = iconRegister.registerIcon(RefStrings.MODID + ":wand_structure_save");
|
||||
loadIcon = iconRegister.registerIcon(RefStrings.MODID + ":wand_structure_load");
|
||||
}
|
||||
|
||||
@Override
|
||||
public IIcon getIcon(int side, int meta) {
|
||||
if(meta == 1) return loadIcon;
|
||||
return saveIcon;
|
||||
}
|
||||
|
||||
@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 TileEntityWandStructure)) return false;
|
||||
|
||||
TileEntityWandStructure structure = (TileEntityWandStructure) te;
|
||||
|
||||
if(!player.isSneaking()) {
|
||||
Block block = ModBlocks.getBlockFromStack(player.getHeldItem());
|
||||
if(block != null && !ModBlocks.isStructureBlock(block, true)) {
|
||||
Pair<Block, Integer> bm = new Pair<Block, Integer>(block, player.getHeldItem().getItemDamage());
|
||||
|
||||
if(structure.blacklist.contains(bm)) {
|
||||
structure.blacklist.remove(bm);
|
||||
} else {
|
||||
structure.blacklist.add(bm);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if(world.isRemote) FMLNetworkHandler.openGui(player, MainRegistry.instance, 0, world, x, y, z);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void getSubBlocks(Item itemIn, CreativeTabs tab, List list) {
|
||||
list.add(new ItemStack(itemIn, 1, 0));
|
||||
list.add(new ItemStack(itemIn, 1, 1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSubCount() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUnlocalizedName(ItemStack stack) {
|
||||
int meta = stack.getItemDamage();
|
||||
if(meta == 1) return getUnlocalizedName() + ".load";
|
||||
return getUnlocalizedName() + ".save";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int damageDropped(int meta) {
|
||||
return meta;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Container provideContainer(int ID, EntityPlayer player, World world, int x, int y, int z) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object provideGUI(int ID, EntityPlayer player, World world, int x, int y, int z) {
|
||||
int meta = world.getBlockMetadata(x, y, z);
|
||||
TileEntityWandStructure structure = (TileEntityWandStructure) world.getTileEntity(x, y, z);
|
||||
if(meta == 1) return new GuiStructureLoad(structure);
|
||||
return new GuiStructureSave(structure);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printHook(Pre event, World world, int x, int y, int z) {
|
||||
if(world.getBlockMetadata(x, y, z) != 0) return;
|
||||
|
||||
TileEntity te = world.getTileEntity(x, y, z);
|
||||
if(!(te instanceof TileEntityWandStructure)) return;
|
||||
TileEntityWandStructure structure = (TileEntityWandStructure) te;
|
||||
|
||||
List<String> text = new ArrayList<String>();
|
||||
|
||||
text.add(EnumChatFormatting.GRAY + "Name: " + EnumChatFormatting.RESET + structure.name);
|
||||
|
||||
text.add(EnumChatFormatting.GRAY + "Blacklist:");
|
||||
for (Pair<Block, Integer> bm : structure.blacklist) {
|
||||
text.add(EnumChatFormatting.RED + "- " + bm.getKey().getUnlocalizedName() + " : " + bm.getValue());
|
||||
}
|
||||
|
||||
ILookOverlay.printGeneric(event, I18nUtil.resolveKey(getUnlocalizedName() + ".save.name"), 0xffff00, 0x404000, text);
|
||||
}
|
||||
|
||||
public static class TileEntityWandStructure extends TileEntityLoadedBase implements IControlReceiver {
|
||||
|
||||
public String name = "";
|
||||
|
||||
public int sizeX = 1;
|
||||
public int sizeY = 1;
|
||||
public int sizeZ = 1;
|
||||
|
||||
public Set<Pair<Block, Integer>> blacklist = new HashSet<>();
|
||||
|
||||
@Override
|
||||
public void updateEntity() {
|
||||
if(!worldObj.isRemote) {
|
||||
networkPackNT(256);
|
||||
}
|
||||
}
|
||||
|
||||
public void saveStructure(EntityPlayer player) {
|
||||
if(name.isEmpty()) {
|
||||
player.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "Could not save: invalid name"));
|
||||
return;
|
||||
}
|
||||
|
||||
if(sizeX <= 0 || sizeY <= 0 || sizeZ <= 0) {
|
||||
player.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "Could not save: invalid dimensions"));
|
||||
return;
|
||||
}
|
||||
|
||||
Pair<Block, Integer> air = new Pair<Block, Integer>(Blocks.air, 0);
|
||||
blacklist.add(air);
|
||||
|
||||
File file = NBTStructure.quickSaveArea(name + ".nbt", worldObj, xCoord, yCoord + 1, zCoord, xCoord + sizeX - 1, yCoord + sizeY, zCoord + sizeZ - 1, blacklist);
|
||||
|
||||
blacklist.remove(air);
|
||||
|
||||
if(file == null) {
|
||||
player.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "Failed to save structure"));
|
||||
return;
|
||||
}
|
||||
|
||||
ChatComponentText fileText = new ChatComponentText(file.getName());
|
||||
fileText.getChatStyle().setChatClickEvent(new ClickEvent(ClickEvent.Action.OPEN_FILE, file.getParentFile().getAbsolutePath()));
|
||||
fileText.getChatStyle().setUnderlined(true);
|
||||
|
||||
player.addChatMessage(new ChatComponentText("Saved structure as ").appendSibling(fileText));
|
||||
}
|
||||
|
||||
public void loadStructure(EntityPlayer player) {
|
||||
if(name.isEmpty()) {
|
||||
player.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "Could not load: no filename specified"));
|
||||
return;
|
||||
}
|
||||
|
||||
File structureDirectory = new File(Minecraft.getMinecraft().mcDataDir, "structures");
|
||||
structureDirectory.mkdir();
|
||||
|
||||
File structureFile = new File(structureDirectory, name + ".nbt");
|
||||
|
||||
boolean previousDebug = StructureConfig.debugStructures;
|
||||
StructureConfig.debugStructures = true;
|
||||
|
||||
try {
|
||||
NBTStructure structure = new NBTStructure(structureFile);
|
||||
|
||||
sizeX = structure.getSizeX();
|
||||
sizeY = structure.getSizeY();
|
||||
sizeZ = structure.getSizeZ();
|
||||
|
||||
structure.build(worldObj, xCoord, yCoord + 1, zCoord, 0, false, true);
|
||||
|
||||
worldObj.setBlockMetadataWithNotify(xCoord, yCoord, zCoord, 0, 3);
|
||||
|
||||
player.addChatMessage(new ChatComponentText("Structure loaded"));
|
||||
|
||||
} catch (FileNotFoundException ex) {
|
||||
player.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "Could not load: file not found"));
|
||||
} finally {
|
||||
StructureConfig.debugStructures = previousDebug;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(ByteBuf buf) {
|
||||
BufferUtil.writeString(buf, name);
|
||||
|
||||
buf.writeInt(sizeX);
|
||||
buf.writeInt(sizeY);
|
||||
buf.writeInt(sizeZ);
|
||||
|
||||
buf.writeInt(blacklist.size());
|
||||
for(Pair<Block, Integer> bm : blacklist) {
|
||||
buf.writeInt(Block.getIdFromBlock(bm.getKey()));
|
||||
buf.writeInt(bm.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deserialize(ByteBuf buf) {
|
||||
name = BufferUtil.readString(buf);
|
||||
|
||||
sizeX = buf.readInt();
|
||||
sizeY = buf.readInt();
|
||||
sizeZ = buf.readInt();
|
||||
|
||||
int count = buf.readInt();
|
||||
blacklist = new HashSet<>();
|
||||
for(int i = 0; i < count; i++) {
|
||||
Block block = Block.getBlockById(buf.readInt());
|
||||
int meta = buf.readInt();
|
||||
blacklist.add(new Pair<Block, Integer>(block, meta));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromNBT(NBTTagCompound nbt) {
|
||||
super.readFromNBT(nbt);
|
||||
|
||||
name = nbt.getString("name");
|
||||
|
||||
sizeX = nbt.getInteger("sizeX");
|
||||
sizeY = nbt.getInteger("sizeY");
|
||||
sizeZ = nbt.getInteger("sizeZ");
|
||||
|
||||
int[] blocks = nbt.getIntArray("blocks");
|
||||
int[] metas = nbt.getIntArray("metas");
|
||||
|
||||
blacklist = new HashSet<>();
|
||||
for (int i = 0; i < blocks.length; i++) {
|
||||
blacklist.add(new Pair<Block, Integer>(Block.getBlockById(blocks[i]), metas[i]));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToNBT(NBTTagCompound nbt) {
|
||||
super.writeToNBT(nbt);
|
||||
|
||||
nbt.setString("name", name);
|
||||
|
||||
nbt.setInteger("sizeX", sizeX);
|
||||
nbt.setInteger("sizeY", sizeY);
|
||||
nbt.setInteger("sizeZ", sizeZ);
|
||||
|
||||
nbt.setIntArray("blocks", blacklist.stream().mapToInt(b -> Block.getIdFromBlock(b.getKey())).toArray());
|
||||
nbt.setIntArray("metas", blacklist.stream().mapToInt(b -> b.getValue()).toArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(EntityPlayer player) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void receiveControl(NBTTagCompound data) {}
|
||||
|
||||
@Override
|
||||
public void receiveControl(EntityPlayer player, NBTTagCompound nbt) {
|
||||
readFromNBT(nbt);
|
||||
markDirty();
|
||||
|
||||
if(nbt.getBoolean("save")) {
|
||||
saveStructure(player);
|
||||
}
|
||||
|
||||
if(nbt.getBoolean("load")) {
|
||||
loadStructure(player);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public AxisAlignedBB getRenderBoundingBox() {
|
||||
return INFINITE_EXTENT_AABB;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public double getMaxRenderDistanceSquared() {
|
||||
return 65536.0D;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public static class GuiStructureSave extends GuiScreen {
|
||||
|
||||
private final TileEntityWandStructure tile;
|
||||
|
||||
private GuiTextField textName;
|
||||
|
||||
private GuiTextField textSizeX;
|
||||
private GuiTextField textSizeY;
|
||||
private GuiTextField textSizeZ;
|
||||
|
||||
private GuiButton performAction;
|
||||
|
||||
private boolean saveOnClose = false;
|
||||
|
||||
public GuiStructureSave(TileEntityWandStructure tile) {
|
||||
this.tile = tile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initGui() {
|
||||
Keyboard.enableRepeatEvents(true);
|
||||
|
||||
textName = new GuiTextField(fontRendererObj, width / 2 - 150, 50, 300, 20);
|
||||
textName.setText(tile.name);
|
||||
|
||||
textSizeX = new GuiTextField(fontRendererObj, width / 2 - 150, 100, 50, 20);
|
||||
textSizeX.setText("" + tile.sizeX);
|
||||
textSizeY = new GuiTextField(fontRendererObj, width / 2 - 100, 100, 50, 20);
|
||||
textSizeY.setText("" + tile.sizeY);
|
||||
textSizeZ = new GuiTextField(fontRendererObj, width / 2 - 50, 100, 50, 20);
|
||||
textSizeZ.setText("" + tile.sizeZ);
|
||||
|
||||
performAction = new GuiButton(0, width / 2 - 150, 150, 300, 20, "SAVE");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawScreen(int mouseX, int mouseY, float partialTicks) {
|
||||
drawDefaultBackground();
|
||||
|
||||
textName.drawTextBox();
|
||||
|
||||
textSizeX.drawTextBox();
|
||||
textSizeY.drawTextBox();
|
||||
textSizeZ.drawTextBox();
|
||||
|
||||
performAction.drawButton(mc, mouseX, mouseY);
|
||||
|
||||
super.drawScreen(mouseX, mouseY, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGuiClosed() {
|
||||
Keyboard.enableRepeatEvents(false);
|
||||
|
||||
NBTTagCompound data = new NBTTagCompound();
|
||||
tile.writeToNBT(data);
|
||||
|
||||
data.setString("name", textName.getText());
|
||||
|
||||
try { data.setInteger("sizeX", Integer.parseInt(textSizeX.getText())); } catch (Exception ex) {}
|
||||
try { data.setInteger("sizeY", Integer.parseInt(textSizeY.getText())); } catch (Exception ex) {}
|
||||
try { data.setInteger("sizeZ", Integer.parseInt(textSizeZ.getText())); } catch (Exception ex) {}
|
||||
|
||||
if(saveOnClose) data.setBoolean("save", true);
|
||||
|
||||
PacketDispatcher.wrapper.sendToServer(new NBTControlPacket(data, tile.xCoord, tile.yCoord, tile.zCoord));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void keyTyped(char typedChar, int keyCode) {
|
||||
super.keyTyped(typedChar, keyCode);
|
||||
|
||||
textName.textboxKeyTyped(typedChar, keyCode);
|
||||
|
||||
textSizeX.textboxKeyTyped(typedChar, keyCode);
|
||||
textSizeY.textboxKeyTyped(typedChar, keyCode);
|
||||
textSizeZ.textboxKeyTyped(typedChar, keyCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void mouseClicked(int mouseX, int mouseY, int mouseButton) {
|
||||
super.mouseClicked(mouseX, mouseY, mouseButton);
|
||||
textName.mouseClicked(mouseX, mouseY, mouseButton);
|
||||
|
||||
textSizeX.mouseClicked(mouseX, mouseY, mouseButton);
|
||||
textSizeY.mouseClicked(mouseX, mouseY, mouseButton);
|
||||
textSizeZ.mouseClicked(mouseX, mouseY, mouseButton);
|
||||
|
||||
if(performAction.mousePressed(mc, mouseX, mouseY)) {
|
||||
saveOnClose = true;
|
||||
|
||||
mc.displayGuiScreen(null);
|
||||
mc.setIngameFocus();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesGuiPauseGame() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public static class GuiStructureLoad extends GuiScreen {
|
||||
|
||||
private final TileEntityWandStructure tile;
|
||||
|
||||
private GuiTextField textName;
|
||||
|
||||
private GuiFileList fileList;
|
||||
|
||||
private GuiButton performAction;
|
||||
|
||||
private boolean loadOnClose = false;
|
||||
|
||||
private static File structureDirectory = new File(Minecraft.getMinecraft().mcDataDir, "structures");
|
||||
private static String nameFilter = "";
|
||||
private static final FileFilter structureFilter = new FileFilter() {
|
||||
|
||||
public boolean accept(File file) {
|
||||
if(!file.isFile() || !file.getName().endsWith(".nbt")) return false;
|
||||
return nameFilter.isEmpty() || file.getName().contains(nameFilter);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
public GuiStructureLoad(TileEntityWandStructure tile) {
|
||||
this.tile = tile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initGui() {
|
||||
Keyboard.enableRepeatEvents(true);
|
||||
|
||||
textName = new GuiTextField(fontRendererObj, width / 2 - 150, 50, 300, 20);
|
||||
textName.setText(tile.name);
|
||||
nameFilter = tile.name;
|
||||
|
||||
structureDirectory.mkdir();
|
||||
|
||||
fileList = new GuiFileList(mc, structureDirectory.listFiles(structureFilter), this::selectFile, nameFilter, width, height, 70, height - 90, 16);
|
||||
|
||||
performAction = new GuiButton(0, width / 2 - 150, height - 70, 300, 20, "LOAD");
|
||||
}
|
||||
|
||||
public void selectFile(File file) {
|
||||
String fileName = file.getName();
|
||||
textName.setText(fileName.substring(0, fileName.length() - 4));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawScreen(int mouseX, int mouseY, float partialTicks) {
|
||||
fileList.drawScreen(mouseX, mouseY, partialTicks);
|
||||
|
||||
textName.drawTextBox();
|
||||
|
||||
performAction.drawButton(mc, mouseX, mouseY);
|
||||
|
||||
super.drawScreen(mouseX, mouseY, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGuiClosed() {
|
||||
Keyboard.enableRepeatEvents(false);
|
||||
|
||||
NBTTagCompound data = new NBTTagCompound();
|
||||
tile.writeToNBT(data);
|
||||
|
||||
data.setString("name", textName.getText());
|
||||
|
||||
if(loadOnClose) data.setBoolean("load", true);
|
||||
|
||||
PacketDispatcher.wrapper.sendToServer(new NBTControlPacket(data, tile.xCoord, tile.yCoord, tile.zCoord));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void keyTyped(char typedChar, int keyCode) {
|
||||
super.keyTyped(typedChar, keyCode);
|
||||
|
||||
textName.textboxKeyTyped(typedChar, keyCode);
|
||||
|
||||
if(!nameFilter.equals(textName.getText())) {
|
||||
nameFilter = textName.getText();
|
||||
fileList = new GuiFileList(mc, structureDirectory.listFiles(structureFilter), this::selectFile, nameFilter, width, height, 70, height - 90, 16);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void mouseClicked(int mouseX, int mouseY, int mouseButton) {
|
||||
super.mouseClicked(mouseX, mouseY, mouseButton);
|
||||
textName.mouseClicked(mouseX, mouseY, mouseButton);
|
||||
|
||||
fileList.func_148179_a(mouseX, mouseY, mouseButton);
|
||||
|
||||
fileList.select(textName.getText());
|
||||
|
||||
if(performAction.mousePressed(mc, mouseX, mouseY)) {
|
||||
loadOnClose = true;
|
||||
|
||||
mc.displayGuiScreen(null);
|
||||
mc.setIngameFocus();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void mouseMovedOrUp(int mouseX, int mouseY, int state) {
|
||||
super.mouseMovedOrUp(mouseX, mouseY, state);
|
||||
fileList.func_148181_b(mouseX, mouseY, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesGuiPauseGame() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -44,7 +44,6 @@ 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;
|
||||
@ -175,10 +174,10 @@ public class BlockWandTandem extends BlockContainer implements IBlockSideRotatio
|
||||
}
|
||||
|
||||
if(!player.isSneaking()) {
|
||||
Block block = getBlock(world, player.getHeldItem());
|
||||
Block block = ModBlocks.getBlockFromStack(player.getHeldItem());
|
||||
if(block == ModBlocks.wand_air) block = Blocks.air;
|
||||
|
||||
if(block != null && block != ModBlocks.wand_jigsaw && block != ModBlocks.wand_loot) {
|
||||
if(block != null && !ModBlocks.isStructureBlock(block, false)) {
|
||||
jigsaw.replaceBlock = block;
|
||||
jigsaw.replaceMeta = player.getHeldItem().getItemDamage();
|
||||
jigsaw.markDirty();
|
||||
@ -196,13 +195,6 @@ public class BlockWandTandem extends BlockContainer implements IBlockSideRotatio
|
||||
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) {
|
||||
|
||||
@ -13,6 +13,7 @@ import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.command.PlayerNotFoundException;
|
||||
import net.minecraft.command.WrongUsageException;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.util.ChatComponentText;
|
||||
import net.minecraft.util.ChatComponentTranslation;
|
||||
import net.minecraft.util.EnumChatFormatting;
|
||||
import net.minecraft.util.MathHelper;
|
||||
@ -71,6 +72,8 @@ public class CommandLocate extends CommandBase {
|
||||
ChatComponentTranslation message = new ChatComponentTranslation("commands.locate.success.coordinates", structure.name, pos.chunkXPos * 16, pos.chunkZPos * 16);
|
||||
message.getChatStyle().setColor(EnumChatFormatting.GREEN);
|
||||
sender.addChatMessage(message);
|
||||
} else if (args[0].equals("list")) {
|
||||
sender.addChatMessage(new ChatComponentText(String.join(", ", NBTStructure.listStructures())));
|
||||
} else {
|
||||
throw new WrongUsageException(getCommandUsage(sender), new Object[0]);
|
||||
}
|
||||
@ -105,9 +108,9 @@ public class CommandLocate extends CommandBase {
|
||||
return Collections.emptyList();
|
||||
|
||||
if(args.length == 1)
|
||||
return getListOfStringsMatchingLastWord(args, "structure");
|
||||
return getListOfStringsMatchingLastWord(args, "structure", "list");
|
||||
|
||||
if(args.length == 2) {
|
||||
if(args.length == 2 && args[0].equals("structure")) {
|
||||
List<String> structures = NBTStructure.listStructures();
|
||||
return getListOfStringsMatchingLastWord(args, structures.toArray(new String[structures.size()]));
|
||||
}
|
||||
|
||||
99
src/main/java/com/hbm/inventory/gui/element/GuiFileList.java
Normal file
99
src/main/java/com/hbm/inventory/gui/element/GuiFileList.java
Normal file
@ -0,0 +1,99 @@
|
||||
package com.hbm.inventory.gui.element;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiListExtended;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class GuiFileList extends GuiListExtended {
|
||||
|
||||
private List<Row> rows = new ArrayList<>();
|
||||
private int selectedId = -1;
|
||||
|
||||
public GuiFileList(Minecraft mc, File[] files, Consumer<File> onSelect, String nameFilter, int width, int height, int top, int bottom, int slotHeight) {
|
||||
super(mc, width, height, top, bottom, slotHeight);
|
||||
|
||||
for(File file : files) {
|
||||
if(file.getName().equals(nameFilter + ".nbt")) {
|
||||
selectedId = rows.size();
|
||||
}
|
||||
rows.add(new Row(file, onSelect, width, slotHeight));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IGuiListEntry getListEntry(int id) {
|
||||
return rows.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSize() {
|
||||
return rows.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isSelected(int id) {
|
||||
return id == selectedId;
|
||||
}
|
||||
|
||||
public void select(String nameFilter) {
|
||||
for(int i = 0; i < rows.size(); i++) {
|
||||
Row row = rows.get(i);
|
||||
if(row.file.getName().equals(nameFilter + ".nbt")) {
|
||||
selectedId = i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public static class Row implements IGuiListEntry {
|
||||
|
||||
private final Minecraft mc;
|
||||
private final File file;
|
||||
|
||||
private final int width;
|
||||
private final int height;
|
||||
|
||||
private final Consumer<File> onSelect;
|
||||
|
||||
public Row(File file, Consumer<File> onSelect, int width, int height) {
|
||||
this.mc = Minecraft.getMinecraft();
|
||||
this.file = file;
|
||||
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
this.onSelect = onSelect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawEntry(int id, int x, int y, int width, int height, Tessellator tess, int mouseX, int mouseY, boolean isVisible) {
|
||||
mc.fontRenderer.drawString(file.getName(), x + 20, y + 1, 0xFFFFFF);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mousePressed(int id, int mouseX, int mouseY, int button, int hoverX, int hoverY) {
|
||||
if(hoverX < 0 || hoverX > width) return false;
|
||||
if(hoverY < 0 || hoverY > height) return false;
|
||||
|
||||
onSelect.accept(file);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(int id, int mouseX, int mouseY, int button, int hoverX, int hoverY) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,6 +1,5 @@
|
||||
package com.hbm.items.tool;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@ -8,23 +7,23 @@ import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
import com.hbm.blocks.ModBlocks;
|
||||
import com.hbm.blocks.generic.BlockWandStructure.TileEntityWandStructure;
|
||||
import com.hbm.util.BobMathUtil;
|
||||
import com.hbm.util.Tuple.Pair;
|
||||
import com.hbm.world.gen.nbt.NBTStructure;
|
||||
|
||||
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;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.ChatComponentText;
|
||||
import net.minecraft.util.EnumChatFormatting;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class ItemWandS extends Item {
|
||||
|
||||
private static final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss");
|
||||
private static final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss");
|
||||
|
||||
@Override
|
||||
public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean bool) {
|
||||
@ -34,106 +33,124 @@ public class ItemWandS extends Item {
|
||||
list.add("adds a block to the blacklist by crouch right-clicking!)");
|
||||
|
||||
if(stack.stackTagCompound != null) {
|
||||
int px = stack.stackTagCompound.getInteger("x");
|
||||
int py = stack.stackTagCompound.getInteger("y");
|
||||
int pz = stack.stackTagCompound.getInteger("z");
|
||||
int px = stack.stackTagCompound.getInteger("x");
|
||||
int py = stack.stackTagCompound.getInteger("y");
|
||||
int pz = stack.stackTagCompound.getInteger("z");
|
||||
|
||||
if(px != 0 || py != 0 || pz != 0) {
|
||||
list.add(EnumChatFormatting.AQUA + "From: " + px + ", " + py + ", " + pz);
|
||||
} else {
|
||||
list.add(EnumChatFormatting.AQUA + "No start position set");
|
||||
}
|
||||
list.add(EnumChatFormatting.AQUA + "From: " + px + ", " + py + ", " + pz);
|
||||
} else {
|
||||
list.add(EnumChatFormatting.AQUA + "No start position set");
|
||||
}
|
||||
|
||||
Set<Pair<Block, Integer>> blocks = getBlocks(stack);
|
||||
Set<Pair<Block, Integer>> blocks = getBlocks(stack);
|
||||
|
||||
if(blocks.size() > 0) {
|
||||
list.add("Blacklist:");
|
||||
for(Pair<Block, Integer> block : blocks) {
|
||||
list.add(EnumChatFormatting.RED + "- " + block.key.getUnlocalizedName());
|
||||
}
|
||||
}
|
||||
}
|
||||
if(blocks.size() > 0) {
|
||||
list.add("Blacklist:");
|
||||
for(Pair<Block, Integer> block : blocks) {
|
||||
list.add(EnumChatFormatting.RED + "- " + block.key.getUnlocalizedName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// why the fuck ye'd leave this whole thing obfuscated is beyond me
|
||||
@Override
|
||||
public boolean onItemUse(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, float fx, float fy, float fz) {
|
||||
// why the fuck ye'd leave this whole thing obfuscated is beyond me
|
||||
@Override
|
||||
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(player.isSneaking()) {
|
||||
Pair<Block, Integer> target = new Pair<Block, Integer>(world.getBlock(x, y, z), world.getBlockMetadata(x, y, z));
|
||||
Set<Pair<Block, Integer>> blocks = getBlocks(stack);
|
||||
Pair<Block, Integer> target = new Pair<Block, Integer>(world.getBlock(x, y, z), world.getBlockMetadata(x, y, z));
|
||||
Set<Pair<Block, Integer>> blocks = getBlocks(stack);
|
||||
|
||||
if(blocks.contains(target)) {
|
||||
blocks.remove(target);
|
||||
if(world.isRemote) player.addChatMessage(new ChatComponentText("Removed from blacklist " + target.key.getUnlocalizedName()));
|
||||
} else {
|
||||
blocks.add(target);
|
||||
if(world.isRemote) player.addChatMessage(new ChatComponentText("Added to blacklist " + target.key.getUnlocalizedName()));
|
||||
}
|
||||
if(blocks.contains(target)) {
|
||||
blocks.remove(target);
|
||||
if(world.isRemote) player.addChatMessage(new ChatComponentText("Removed from blacklist " + target.key.getUnlocalizedName()));
|
||||
} else {
|
||||
blocks.add(target);
|
||||
if(world.isRemote) player.addChatMessage(new ChatComponentText("Added to blacklist " + target.key.getUnlocalizedName()));
|
||||
}
|
||||
|
||||
setBlocks(stack, blocks);
|
||||
setBlocks(stack, blocks);
|
||||
|
||||
} else {
|
||||
int px = stack.stackTagCompound.getInteger("x");
|
||||
int py = stack.stackTagCompound.getInteger("y");
|
||||
int pz = stack.stackTagCompound.getInteger("z");
|
||||
int px = stack.stackTagCompound.getInteger("x");
|
||||
int py = stack.stackTagCompound.getInteger("y");
|
||||
int pz = stack.stackTagCompound.getInteger("z");
|
||||
|
||||
if(px == 0 && py == 0 && pz == 0) {
|
||||
setPosition(stack, x, y, z);
|
||||
setPosition(stack, x, y, z);
|
||||
|
||||
if(world.isRemote) player.addChatMessage(new ChatComponentText("First position set!"));
|
||||
} else {
|
||||
setPosition(stack, 0, 0, 0);
|
||||
setPosition(stack, 0, 0, 0);
|
||||
|
||||
Set<Pair<Block, Integer>> blocks = getBlocks(stack);
|
||||
blocks.add(new Pair<Block, Integer>(Blocks.air, 0));
|
||||
blocks.add(new Pair<Block, Integer>(ModBlocks.spotlight_beam, 0));
|
||||
int minX = Math.min(x, px);
|
||||
int minY = Math.min(y, py) - 1;
|
||||
int minZ = Math.min(z, pz);
|
||||
|
||||
String filename = "structure_" + dateFormat.format(new Date()).toString() + ".nbt";
|
||||
int sizeX = Math.abs(x - px) + 1;
|
||||
int sizeY = Math.abs(y - py) + 1;
|
||||
int sizeZ = Math.abs(z - pz) + 1;
|
||||
|
||||
NBTStructure.saveArea(filename, world, x, y, z, px, py, pz, blocks);
|
||||
world.setBlock(minX, minY, minZ, ModBlocks.wand_structure);
|
||||
|
||||
if(world.isRemote) player.addChatMessage(new ChatComponentText("Structure saved to: .minecraft/structures/" + filename));
|
||||
TileEntity te = world.getTileEntity(minX, minY, minZ);
|
||||
if (te instanceof TileEntityWandStructure) {
|
||||
TileEntityWandStructure structure = (TileEntityWandStructure) te;
|
||||
|
||||
structure.sizeX = sizeX;
|
||||
structure.sizeY = sizeY;
|
||||
structure.sizeZ = sizeZ;
|
||||
|
||||
structure.blacklist = getBlocks(stack);
|
||||
} else {
|
||||
if (world.isRemote)
|
||||
player.addChatMessage(new ChatComponentText("Could not add a structure block!"));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (world.isRemote)
|
||||
player.addChatMessage(new ChatComponentText("Structure block configured and added at: " + minX + ", " + minY + ", " + minZ));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void setPosition(ItemStack stack, int x, int y, int z) {
|
||||
stack.stackTagCompound.setInteger("x", x);
|
||||
stack.stackTagCompound.setInteger("y", y);
|
||||
stack.stackTagCompound.setInteger("z", z);
|
||||
}
|
||||
private void setPosition(ItemStack stack, int x, int y, int z) {
|
||||
stack.stackTagCompound.setInteger("x", x);
|
||||
stack.stackTagCompound.setInteger("y", y);
|
||||
stack.stackTagCompound.setInteger("z", z);
|
||||
}
|
||||
|
||||
private Set<Pair<Block, Integer>> getBlocks(ItemStack stack) {
|
||||
if(stack.stackTagCompound == null) {
|
||||
return new HashSet<>();
|
||||
}
|
||||
private Set<Pair<Block, Integer>> getBlocks(ItemStack stack) {
|
||||
if(stack.stackTagCompound == null) {
|
||||
return new HashSet<>();
|
||||
}
|
||||
|
||||
int[] blockIds = stack.stackTagCompound.getIntArray("blocks");
|
||||
int[] metas = stack.stackTagCompound.getIntArray("metas");
|
||||
Set<Pair<Block, Integer>> blocks = new HashSet<>(blockIds.length);
|
||||
int[] blockIds = stack.stackTagCompound.getIntArray("blocks");
|
||||
int[] metas = stack.stackTagCompound.getIntArray("metas");
|
||||
Set<Pair<Block, Integer>> blocks = new HashSet<>(blockIds.length);
|
||||
|
||||
for(int i = 0; i < blockIds.length; i++) {
|
||||
blocks.add(new Pair<Block, Integer>(Block.getBlockById(blockIds[i]), metas[i]));
|
||||
}
|
||||
for(int i = 0; i < blockIds.length; i++) {
|
||||
blocks.add(new Pair<Block, Integer>(Block.getBlockById(blockIds[i]), metas[i]));
|
||||
}
|
||||
|
||||
return blocks;
|
||||
}
|
||||
return blocks;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void setBlocks(ItemStack stack, Set<Pair<Block, Integer>> blocks) {
|
||||
if(stack.stackTagCompound == null) {
|
||||
stack.stackTagCompound = new NBTTagCompound();
|
||||
}
|
||||
private void setBlocks(ItemStack stack, Set<Pair<Block, Integer>> blocks) {
|
||||
if(stack.stackTagCompound == null) {
|
||||
stack.stackTagCompound = new NBTTagCompound();
|
||||
}
|
||||
|
||||
stack.stackTagCompound.setIntArray("blocks", BobMathUtil.collectionToIntArray(blocks, i -> Block.getIdFromBlock(((Pair<Block, Integer>)i).getKey())));
|
||||
stack.stackTagCompound.setIntArray("metas", BobMathUtil.collectionToIntArray(blocks, i -> ((Pair<Block, Integer>)i).getValue()));
|
||||
}
|
||||
stack.stackTagCompound.setIntArray("blocks", BobMathUtil.collectionToIntArray(blocks, i -> Block.getIdFromBlock(((Pair<Block, Integer>)i).getKey())));
|
||||
stack.stackTagCompound.setIntArray("metas", BobMathUtil.collectionToIntArray(blocks, i -> ((Pair<Block, Integer>)i).getValue()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack onItemRightClick(ItemStack stack, World world, EntityPlayer player) {
|
||||
@ -147,7 +164,7 @@ public class ItemWandS extends Item {
|
||||
|
||||
if(world.isRemote) {
|
||||
player.addChatMessage(new ChatComponentText("Cleared blacklist"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return stack;
|
||||
|
||||
@ -8,6 +8,7 @@ import com.hbm.blocks.generic.BlockPedestal.TileEntityPedestal;
|
||||
import com.hbm.blocks.generic.BlockPlushie.TileEntityPlushie;
|
||||
import com.hbm.blocks.generic.BlockSkeletonHolder.TileEntitySkeletonHolder;
|
||||
import com.hbm.blocks.generic.BlockSnowglobe.TileEntitySnowglobe;
|
||||
import com.hbm.blocks.generic.BlockWandStructure.TileEntityWandStructure;
|
||||
import com.hbm.blocks.machine.Floodlight.TileEntityFloodlight;
|
||||
import com.hbm.blocks.machine.MachineFan.TileEntityFan;
|
||||
import com.hbm.blocks.machine.PistonInserter.TileEntityPistonInserter;
|
||||
@ -130,18 +131,18 @@ import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public class ClientProxy extends ServerProxy {
|
||||
|
||||
|
||||
private static final I18nClient I18N = new I18nClient();
|
||||
|
||||
public RenderInfoSystem theInfoSystem = new RenderInfoSystem();
|
||||
|
||||
|
||||
public ITranslate getI18n() { return I18N; }
|
||||
|
||||
/** Runs just before item an block init */
|
||||
@Override
|
||||
public void registerPreRenderInfo() {
|
||||
AdvancedModelLoader.registerModelHandler(new HmfModelLoader());
|
||||
|
||||
|
||||
QMAWLoader.registerModFileURL(FMLCommonHandler.instance().findContainerFor(RefStrings.MODID).getSource());
|
||||
}
|
||||
|
||||
@ -438,6 +439,8 @@ public class ClientProxy extends ServerProxy {
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityVaultDoor.class, new RenderVaultDoor());
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityBlastDoor.class, new RenderBlastDoor());
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityDoorGeneric.class, new RenderDoorGeneric());
|
||||
//NBTStructure
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityWandStructure.class, new RenderWandStructure());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -459,7 +462,7 @@ public class ClientProxy extends ServerProxy {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// same crap but for items directly because why invent a new solution when this shit works just fine
|
||||
Iterator itItems = Item.itemRegistry.iterator();
|
||||
while(itItems.hasNext()) {
|
||||
@ -787,7 +790,7 @@ public class ClientProxy extends ServerProxy {
|
||||
public void registerBlockRenderer() {
|
||||
|
||||
RenderingRegistry.registerBlockHandler(new RenderISBRHUniversal());
|
||||
|
||||
|
||||
/// STOP DOING THIS ///
|
||||
RenderingRegistry.registerBlockHandler(new RenderScaffoldBlock());
|
||||
RenderingRegistry.registerBlockHandler(new RenderTapeBlock());
|
||||
|
||||
@ -0,0 +1,92 @@
|
||||
package com.hbm.render.tileentity;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import com.hbm.blocks.generic.BlockWandStructure.TileEntityWandStructure;
|
||||
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
|
||||
public class RenderWandStructure extends TileEntitySpecialRenderer {
|
||||
|
||||
@Override
|
||||
public void renderTileEntityAt(TileEntity tile, double x, double y, double z, float interp) {
|
||||
if(!(tile instanceof TileEntityWandStructure)) return;
|
||||
TileEntityWandStructure structure = (TileEntityWandStructure) tile;
|
||||
|
||||
if(tile.getBlockMetadata() != 0) return;
|
||||
|
||||
GL11.glPushMatrix();
|
||||
{
|
||||
|
||||
double x1 = x;
|
||||
double y1 = y + 1;
|
||||
double z1 = z;
|
||||
|
||||
double x2 = x + structure.sizeX;
|
||||
double y2 = y + structure.sizeY + 1;
|
||||
double z2 = z + structure.sizeZ;
|
||||
|
||||
|
||||
GL11.glDisable(GL11.GL_LIGHTING);
|
||||
GL11.glDisable(GL11.GL_TEXTURE_2D);
|
||||
GL11.glColor3f(1F, 1F, 1F);
|
||||
|
||||
|
||||
|
||||
Tessellator tess = Tessellator.instance;
|
||||
tess.startDrawing(GL11.GL_LINES);
|
||||
tess.setBrightness(240);
|
||||
tess.setColorRGBA_F(1F, 1F, 1F, 1F);
|
||||
|
||||
// top
|
||||
tess.addVertex(x1, y2, z1);
|
||||
tess.addVertex(x1, y2, z2);
|
||||
|
||||
tess.addVertex(x1, y2, z2);
|
||||
tess.addVertex(x2, y2, z2);
|
||||
|
||||
tess.addVertex(x2, y2, z2);
|
||||
tess.addVertex(x2, y2, z1);
|
||||
|
||||
tess.addVertex(x2, y2, z1);
|
||||
tess.addVertex(x1, y2, z1);
|
||||
|
||||
// bottom
|
||||
tess.addVertex(x1, y1, z1);
|
||||
tess.addVertex(x1, y1, z2);
|
||||
|
||||
tess.addVertex(x1, y1, z2);
|
||||
tess.addVertex(x2, y1, z2);
|
||||
|
||||
tess.addVertex(x2, y1, z2);
|
||||
tess.addVertex(x2, y1, z1);
|
||||
|
||||
tess.addVertex(x2, y1, z1);
|
||||
tess.addVertex(x1, y1, z1);
|
||||
|
||||
// sides
|
||||
tess.addVertex(x1, y1, z1);
|
||||
tess.addVertex(x1, y2, z1);
|
||||
|
||||
tess.addVertex(x2, y1, z1);
|
||||
tess.addVertex(x2, y2, z1);
|
||||
|
||||
tess.addVertex(x2, y1, z2);
|
||||
tess.addVertex(x2, y2, z2);
|
||||
|
||||
tess.addVertex(x1, y1, z2);
|
||||
tess.addVertex(x1, y2, z2);
|
||||
|
||||
tess.draw();
|
||||
|
||||
|
||||
GL11.glEnable(GL11.GL_TEXTURE_2D);
|
||||
GL11.glDisable(GL11.GL_LIGHTING);
|
||||
|
||||
}
|
||||
GL11.glPopMatrix();
|
||||
}
|
||||
|
||||
}
|
||||
@ -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.BlockWandStructure.TileEntityWandStructure;
|
||||
import com.hbm.blocks.generic.BlockWandTandem.TileEntityWandTandem;
|
||||
import com.hbm.blocks.generic.BlockWandLogic.TileEntityWandLogic;
|
||||
import com.hbm.blocks.generic.DungeonSpawner.TileEntityDungeonSpawner;
|
||||
@ -245,6 +246,7 @@ public class TileMappings {
|
||||
put(TileEntityWandJigsaw.class, "tileentity_wand_jigsaw");
|
||||
put(TileEntityWandLogic.class, "tileentity_wand_spawner");
|
||||
put(TileEntityWandTandem.class, "tileentity_wand_tandem");
|
||||
put(TileEntityWandStructure.class, "tileentity_wand_structure");
|
||||
|
||||
putNetwork();
|
||||
putBombs();
|
||||
@ -442,7 +444,7 @@ public class TileMappings {
|
||||
put(TileEntityPipeExhaustPaintable.class, "tileentity_pipe_exhaust_paintable");
|
||||
put(TileEntityFluidValve.class, "tileentity_pipe_valve");
|
||||
put(TileEntityFluidPump.class, "tileentity_pipe_pump");
|
||||
|
||||
|
||||
put(TileEntityPipeAnchor.class, "tileentity_pioe_anchor");
|
||||
|
||||
put(TileEntityCraneInserter.class, "tileentity_inserter");
|
||||
@ -496,7 +498,7 @@ public class TileMappings {
|
||||
if(IConfigurableMachine.class.isAssignableFrom(clazz)) {
|
||||
configurables.add((Class<? extends IConfigurableMachine>) clazz);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Causes problems with most machines where two independently acting tiles work together (TU machines, RBMKs, fluid transfer)
|
||||
* Also breaks due to some sort of buffer leak in the threaded packets, if a boiler is involved (which uses a ByteBuf instead of the usual serializing) it crashes
|
||||
|
||||
@ -9,17 +9,47 @@ import net.minecraft.world.gen.structure.StructureComponent.BlockSelector;
|
||||
// Assigned to a Component to build
|
||||
public class JigsawPiece {
|
||||
|
||||
// Translates a given name into a jigsaw piece, for serialization
|
||||
protected static Map<String, JigsawPiece> jigsawMap = new HashMap<>();
|
||||
// Translates a given name into a jigsaw piece, for serialization
|
||||
protected static Map<String, JigsawPiece> jigsawMap = new HashMap<>();
|
||||
|
||||
public final String name;
|
||||
public final NBTStructure structure;
|
||||
|
||||
// Block modifiers, for randomization and terrain matching
|
||||
/**
|
||||
* Replaces matching blocks using the result of a BlockSelector
|
||||
*/
|
||||
public Map<Block, BlockSelector> blockTable;
|
||||
public boolean conformToTerrain = false; // moves every single column to the terrain (digging out trenches, natural formations)
|
||||
public boolean alignToTerrain = false; // aligns this component y-level individually, without moving individual columns (village houses)
|
||||
public int heightOffset = 0; // individual offset for the structure
|
||||
|
||||
/**
|
||||
* Moves every single column to the terrain (for digging out trenches, natural formations, etc)
|
||||
*/
|
||||
public boolean conformToTerrain = false;
|
||||
|
||||
/**
|
||||
* Aligns this component y-level individually, without moving individual columns (like village houses)
|
||||
*/
|
||||
public boolean alignToTerrain = false;
|
||||
|
||||
/**
|
||||
* Height offset for this structure piece, -1 will sink the floor flush into the ground
|
||||
*/
|
||||
public int heightOffset = 0;
|
||||
|
||||
/**
|
||||
* Will fill any air gap beneath the jigsaw piece using the given selector
|
||||
*/
|
||||
public BlockSelector platform;
|
||||
|
||||
/**
|
||||
* If greater than 0, will limit the number of times this piece can spawn in a structure
|
||||
*/
|
||||
public int instanceLimit = 0;
|
||||
|
||||
/**
|
||||
* If set, will continue generation beyond the defined limits until this piece exists at least once
|
||||
*/
|
||||
public boolean required = false;
|
||||
|
||||
public JigsawPiece(String name, NBTStructure structure) {
|
||||
this(name, structure, 0);
|
||||
|
||||
@ -23,6 +23,11 @@ public class JigsawPool {
|
||||
totalWeight += weight;
|
||||
}
|
||||
|
||||
public int getAverageWeight() {
|
||||
if(pieces.size() == 0) return 1;
|
||||
return totalWeight / pieces.size();
|
||||
}
|
||||
|
||||
protected JigsawPool clone() {
|
||||
JigsawPool clone = new JigsawPool();
|
||||
clone.pieces = new ArrayList<>(this.pieces);
|
||||
|
||||
@ -1,12 +1,16 @@
|
||||
package com.hbm.world.gen.nbt;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.*;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import com.hbm.blocks.ModBlocks;
|
||||
import com.hbm.blocks.generic.BlockWand;
|
||||
import com.hbm.blocks.generic.BlockWandTandem.TileEntityWandTandem;
|
||||
@ -18,6 +22,7 @@ import com.hbm.util.Tuple.Pair;
|
||||
import com.hbm.util.Tuple.Quartet;
|
||||
import com.hbm.util.fauxpointtwelve.BlockPos;
|
||||
import com.hbm.world.gen.nbt.SpawnCondition.WorldCoordinate;
|
||||
import com.hbm.world.gen.nbt.selector.BiomeBlockSelector;
|
||||
|
||||
import cpw.mods.fml.common.registry.GameRegistry;
|
||||
import net.minecraft.block.*;
|
||||
@ -57,9 +62,11 @@ public class NBTStructure {
|
||||
|
||||
private static Map<String, SpawnCondition> namedMap = new HashMap<>();
|
||||
|
||||
protected static Map<Integer, List<SpawnCondition>> weightedMap = new HashMap<>();
|
||||
protected static Map<Integer, List<SpawnCondition>> spawnMap = new HashMap<>();
|
||||
protected static Map<Integer, List<SpawnCondition>> customSpawnMap = new HashMap<>();
|
||||
|
||||
private static Map<Integer, Map<Integer, WeightedSpawnList>> validBiomeCache = new HashMap<>();
|
||||
|
||||
private String name;
|
||||
|
||||
private boolean isLoaded;
|
||||
@ -84,6 +91,34 @@ public class NBTStructure {
|
||||
}
|
||||
}
|
||||
|
||||
public NBTStructure(String name, InputStream stream) {
|
||||
this.name = name;
|
||||
loadStructure(stream);
|
||||
}
|
||||
|
||||
public NBTStructure(File file) throws FileNotFoundException {
|
||||
this.name = file.getName();
|
||||
InputStream stream = new FileInputStream(file);
|
||||
loadStructure(stream);
|
||||
IOUtils.closeQuietly(stream);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name.substring(0, name.length() - 4); // trim .nbt
|
||||
}
|
||||
|
||||
public int getSizeX() {
|
||||
return size.x;
|
||||
}
|
||||
|
||||
public int getSizeY() {
|
||||
return size.y;
|
||||
}
|
||||
|
||||
public int getSizeZ() {
|
||||
return size.z;
|
||||
}
|
||||
|
||||
public static void register() {
|
||||
MapGenStructureIO.registerStructure(Start.class, "NBTStructures");
|
||||
MapGenStructureIO.func_143031_a(Component.class, "NBTComponents");
|
||||
@ -102,10 +137,8 @@ public class NBTStructure {
|
||||
return;
|
||||
}
|
||||
|
||||
List<SpawnCondition> weightedList = weightedMap.computeIfAbsent(dimensionId, integer -> new ArrayList<SpawnCondition>());
|
||||
for(int i = 0; i < spawn.spawnWeight; i++) {
|
||||
weightedList.add(spawn);
|
||||
}
|
||||
List<SpawnCondition> spawnList = spawnMap.computeIfAbsent(dimensionId, integer -> new ArrayList<SpawnCondition>());
|
||||
spawnList.add(spawn);
|
||||
}
|
||||
|
||||
public static void registerStructure(SpawnCondition spawn, int[] dimensionIds) {
|
||||
@ -122,10 +155,8 @@ public class NBTStructure {
|
||||
public static void registerNullWeight(int dimensionId, int weight, Predicate<BiomeGenBase> predicate) {
|
||||
SpawnCondition spawn = new SpawnCondition(weight, predicate);
|
||||
|
||||
List<SpawnCondition> weightedList = weightedMap.computeIfAbsent(dimensionId, integer -> new ArrayList<SpawnCondition>());
|
||||
for(int i = 0; i < spawn.spawnWeight; i++) {
|
||||
weightedList.add(spawn);
|
||||
}
|
||||
List<SpawnCondition> spawnList = spawnMap.computeIfAbsent(dimensionId, integer -> new ArrayList<SpawnCondition>());
|
||||
spawnList.add(spawn);
|
||||
}
|
||||
|
||||
// Presents a list of all structures registered (so far)
|
||||
@ -142,7 +173,7 @@ public class NBTStructure {
|
||||
}
|
||||
|
||||
// Saves a selected area into an NBT structure (+ some of our non-standard stuff to support 1.7.10)
|
||||
public static void saveArea(String filename, World world, int x1, int y1, int z1, int x2, int y2, int z2, Set<Pair<Block, Integer>> exclude) {
|
||||
public static NBTTagCompound saveArea(World world, int x1, int y1, int z1, int x2, int y2, int z2, Set<Pair<Block, Integer>> exclude) {
|
||||
NBTTagCompound structure = new NBTTagCompound();
|
||||
NBTTagList nbtBlocks = new NBTTagList();
|
||||
NBTTagList nbtPalette = new NBTTagList();
|
||||
@ -249,6 +280,13 @@ public class NBTStructure {
|
||||
|
||||
structure.setTag("entities", new NBTTagList());
|
||||
|
||||
return structure;
|
||||
}
|
||||
|
||||
// Writes out a specified area to an .nbt file with a given name
|
||||
public static File quickSaveArea(String filename, World world, int x1, int y1, int z1, int x2, int y2, int z2, Set<Pair<Block, Integer>> exclude) {
|
||||
NBTTagCompound structure = saveArea(world, x1, y1, z1, x2, y2, z2, exclude);
|
||||
|
||||
try {
|
||||
File structureDirectory = new File(Minecraft.getMinecraft().mcDataDir, "structures");
|
||||
structureDirectory.mkdir();
|
||||
@ -256,8 +294,12 @@ public class NBTStructure {
|
||||
File structureFile = new File(structureDirectory, filename);
|
||||
|
||||
CompressedStreamTools.writeCompressed(structure, new FileOutputStream(structureFile));
|
||||
|
||||
return structureFile;
|
||||
} catch (Exception ex) {
|
||||
MainRegistry.logger.warn("Failed to save NBT structure", ex);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -441,10 +483,14 @@ public class NBTStructure {
|
||||
}
|
||||
|
||||
public void build(World world, int x, int y, int z) {
|
||||
build(world, x, y, z, 0);
|
||||
build(world, x, y, z, 0, true, false);
|
||||
}
|
||||
|
||||
public void build(World world, int x, int y, int z, int coordBaseMode) {
|
||||
build(world, x, y, z, coordBaseMode, true, false);
|
||||
}
|
||||
|
||||
public void build(World world, int x, int y, int z, int coordBaseMode, boolean center, boolean wipeExisting) {
|
||||
if(!isLoaded) {
|
||||
MainRegistry.logger.info("NBTStructure is invalid");
|
||||
return;
|
||||
@ -452,9 +498,11 @@ public class NBTStructure {
|
||||
|
||||
HashMap<Short, Short> worldItemPalette = getWorldItemPalette();
|
||||
|
||||
boolean swizzle = coordBaseMode == 1 || coordBaseMode == 3;
|
||||
x -= (swizzle ? size.z : size.x) / 2;
|
||||
z -= (swizzle ? size.x : size.z) / 2;
|
||||
if(center) {
|
||||
boolean swizzle = coordBaseMode == 1 || coordBaseMode == 3;
|
||||
x -= (swizzle ? size.z : size.x) / 2;
|
||||
z -= (swizzle ? size.x : size.z) / 2;
|
||||
}
|
||||
|
||||
int maxX = size.x;
|
||||
int maxZ = size.z;
|
||||
@ -466,16 +514,17 @@ public class NBTStructure {
|
||||
|
||||
for(int by = 0; by < size.y; by++) {
|
||||
BlockState state = blockArray[bx][by][bz];
|
||||
if(state == null) continue;
|
||||
if(state == null) {
|
||||
if(wipeExisting) world.setBlock(rx, by + y, rz, Blocks.air, 0, 2);
|
||||
continue;
|
||||
}
|
||||
|
||||
int ry = by + y;
|
||||
|
||||
Block block = transformBlock(state.definition, null, world.rand);
|
||||
int meta = transformMeta(state.definition, null, coordBaseMode);
|
||||
|
||||
if(ry < 0 || ry >= world.getHeight()) continue;
|
||||
Block existing = world.getBlock(rx, ry, rz);
|
||||
if(existing == Blocks.bedrock) continue;
|
||||
if(ry < 1) continue;
|
||||
|
||||
world.setBlock(rx, ry, rz, block, meta, 2);
|
||||
|
||||
@ -535,12 +584,30 @@ public class NBTStructure {
|
||||
int minZ = Math.min(rotMinZ, rotMaxZ);
|
||||
int maxZ = Math.max(rotMinZ, rotMaxZ);
|
||||
|
||||
if(piece.blockTable != null || piece.platform != null) {
|
||||
BiomeGenBase biome = world.getWorldChunkManager().getBiomeGenAt(generatingBounds.getCenterX(), generatingBounds.getCenterZ());
|
||||
|
||||
if(piece.blockTable != null) {
|
||||
for(BlockSelector selector : piece.blockTable.values()) {
|
||||
if(selector instanceof BiomeBlockSelector) {
|
||||
((BiomeBlockSelector) selector).nextBiome = biome;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(piece.platform instanceof BiomeBlockSelector) {
|
||||
((BiomeBlockSelector) piece.platform).nextBiome = biome;
|
||||
}
|
||||
}
|
||||
|
||||
for(int bx = minX; bx <= maxX; bx++) {
|
||||
for(int bz = minZ; bz <= maxZ; bz++) {
|
||||
int rx = rotateX(bx, bz, coordBaseMode) + totalBounds.minX;
|
||||
int rz = rotateZ(bx, bz, coordBaseMode) + totalBounds.minZ;
|
||||
int oy = piece.conformToTerrain ? world.getTopSolidOrLiquidBlock(rx, rz) + piece.heightOffset : totalBounds.minY;
|
||||
|
||||
boolean hasBase = false;
|
||||
|
||||
for(int by = 0; by < size.y; by++) {
|
||||
BlockState state = blockArray[bx][by][bz];
|
||||
if(state == null) continue;
|
||||
@ -550,9 +617,7 @@ public class NBTStructure {
|
||||
Block block = transformBlock(state.definition, piece.blockTable, world.rand);
|
||||
int meta = transformMeta(state.definition, piece.blockTable, coordBaseMode);
|
||||
|
||||
if(ry < 0 || ry >= world.getHeight()) continue;
|
||||
Block existing = world.getBlock(rx, ry, rz);
|
||||
if(existing == Blocks.bedrock) continue;
|
||||
if(ry < 1) continue;
|
||||
|
||||
world.setBlock(rx, ry, rz, block, meta, 2);
|
||||
|
||||
@ -560,6 +625,16 @@ public class NBTStructure {
|
||||
TileEntity te = buildTileEntity(world, block, worldItemPalette, state.nbt, coordBaseMode, structureName);
|
||||
world.setTileEntity(rx, ry, rz, te);
|
||||
}
|
||||
|
||||
if(by == 0 && piece.platform != null && !block.getMaterial().isReplaceable()) hasBase = true;
|
||||
}
|
||||
|
||||
if(hasBase && !piece.conformToTerrain) {
|
||||
for(int y = oy - 1; y > 0; y--) {
|
||||
if(!world.getBlock(rx, y, rz).isReplaceable(world, rx, y, rz)) break;
|
||||
piece.platform.selectBlocks(world.rand, 0, 0, 0, false);
|
||||
world.setBlock(rx, y, rz, piece.platform.func_151561_a(), piece.platform.getSelectedBlockMetaData(), 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -602,7 +677,7 @@ public class NBTStructure {
|
||||
|
||||
for(int i = 0; i < items.tagCount(); i++) {
|
||||
NBTTagCompound item = items.getCompoundTagAt(i);
|
||||
item.setShort("id", palette.get(item.getShort("id")));
|
||||
item.setShort("id", palette.getOrDefault(item.getShort("id"), (short)0));
|
||||
}
|
||||
}
|
||||
|
||||
@ -940,6 +1015,8 @@ public class NBTStructure {
|
||||
List<Component> queuedComponents = new ArrayList<>();
|
||||
if(spawn.structure == null) queuedComponents.add(startComponent);
|
||||
|
||||
Set<JigsawPiece> requiredPieces = findRequiredPieces(spawn);
|
||||
|
||||
// Iterate through and build out all the components we intend to spawn
|
||||
while(!queuedComponents.isEmpty()) {
|
||||
queuedComponents.sort((a, b) -> b.priority - a.priority); // sort by placement priority descending
|
||||
@ -956,7 +1033,10 @@ public class NBTStructure {
|
||||
if(fromComponent.piece.structure.fromConnections == null) continue;
|
||||
|
||||
int distance = getDistanceTo(fromComponent.getBoundingBox());
|
||||
boolean fallbacksOnly = this.components.size() >= spawn.sizeLimit || distance >= spawn.rangeLimit;
|
||||
|
||||
// Only generate fallback pieces once we hit our size limit, unless we have a required component
|
||||
// Note that there is a HARD limit of 1024 pieces to prevent infinite generation
|
||||
boolean fallbacksOnly = requiredPieces.size() == 0 && (components.size() >= spawn.sizeLimit || distance >= spawn.rangeLimit) || components.size() > 1024;
|
||||
|
||||
for(List<JigsawConnection> unshuffledList : fromComponent.piece.structure.fromConnections) {
|
||||
List<JigsawConnection> connectionList = new ArrayList<>(unshuffledList);
|
||||
@ -994,6 +1074,8 @@ public class NBTStructure {
|
||||
if(nextComponent != null) {
|
||||
addComponent(nextComponent, fromConnection.placementPriority);
|
||||
queuedComponents.add(nextComponent);
|
||||
|
||||
requiredPieces.remove(nextComponent.piece);
|
||||
} 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!
|
||||
@ -1043,6 +1125,22 @@ public class NBTStructure {
|
||||
return new BlockPos(x, y, z);
|
||||
}
|
||||
|
||||
private Set<JigsawPiece> findRequiredPieces(SpawnCondition spawn) {
|
||||
Set<JigsawPiece> requiredPieces = new HashSet<>();
|
||||
|
||||
if(spawn.pools == null) return requiredPieces;
|
||||
|
||||
for(JigsawPool pool : spawn.pools.values()) {
|
||||
for(Pair<JigsawPiece, Integer> weight : pool.pieces) {
|
||||
if(weight.getKey().required) {
|
||||
requiredPieces.add(weight.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return requiredPieces;
|
||||
}
|
||||
|
||||
private Component buildNextComponent(Random rand, SpawnCondition spawn, JigsawPool pool, Component fromComponent, JigsawConnection fromConnection) {
|
||||
JigsawPiece nextPiece = pool.get(rand);
|
||||
if(nextPiece == null) {
|
||||
@ -1050,6 +1148,17 @@ public class NBTStructure {
|
||||
return null;
|
||||
}
|
||||
|
||||
if(nextPiece.instanceLimit > 0) {
|
||||
int instances = 0;
|
||||
for(Object component : components) {
|
||||
if(component instanceof Component && ((Component) component).piece == nextPiece) {
|
||||
instances++;
|
||||
|
||||
if(instances >= nextPiece.instanceLimit) return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<JigsawConnection> 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);
|
||||
@ -1153,7 +1262,7 @@ public class NBTStructure {
|
||||
}
|
||||
}
|
||||
|
||||
if (!weightedMap.containsKey(worldObj.provider.dimensionId))
|
||||
if (!spawnMap.containsKey(worldObj.provider.dimensionId))
|
||||
return null;
|
||||
|
||||
int x = chunkX;
|
||||
@ -1189,11 +1298,35 @@ public class NBTStructure {
|
||||
}
|
||||
|
||||
private SpawnCondition findSpawn(BiomeGenBase biome) {
|
||||
List<SpawnCondition> spawnList = weightedMap.get(worldObj.provider.dimensionId);
|
||||
Map<Integer, WeightedSpawnList> dimensionCache = validBiomeCache.computeIfAbsent(worldObj.provider.dimensionId, integer -> new HashMap<>());
|
||||
|
||||
for(int i = 0; i < 64; i++) {
|
||||
SpawnCondition spawn = spawnList.get(rand.nextInt(spawnList.size()));
|
||||
if(spawn.isValid(biome)) return spawn;
|
||||
WeightedSpawnList filteredList;
|
||||
if(!dimensionCache.containsKey(biome.biomeID)) {
|
||||
List<SpawnCondition> spawnList = spawnMap.get(worldObj.provider.dimensionId);
|
||||
|
||||
filteredList = new WeightedSpawnList();
|
||||
for(SpawnCondition spawn : spawnList) {
|
||||
if(spawn.isValid(biome)) {
|
||||
filteredList.add(spawn);
|
||||
filteredList.totalWeight += spawn.spawnWeight;
|
||||
}
|
||||
}
|
||||
|
||||
dimensionCache.put(biome.biomeID, filteredList);
|
||||
} else {
|
||||
filteredList = dimensionCache.get(biome.biomeID);
|
||||
}
|
||||
|
||||
if(filteredList.totalWeight == 0) return null;
|
||||
|
||||
int weight = rand.nextInt(filteredList.totalWeight);
|
||||
|
||||
for(SpawnCondition spawn : filteredList) {
|
||||
weight -= spawn.spawnWeight;
|
||||
|
||||
if(weight < 0) {
|
||||
return spawn;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -1201,4 +1334,10 @@ public class NBTStructure {
|
||||
|
||||
}
|
||||
|
||||
private static class WeightedSpawnList extends ArrayList<SpawnCondition> {
|
||||
|
||||
public int totalWeight = 0;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -18,34 +18,70 @@ public class SpawnCondition {
|
||||
|
||||
public final String name;
|
||||
|
||||
// If defined, will spawn a single jigsaw piece, for single nbt structures
|
||||
/**
|
||||
* If defined, will spawn a single jigsaw piece, for single nbt structures
|
||||
*/
|
||||
public JigsawPiece structure;
|
||||
|
||||
// If defined, will spawn in a non-nbt structure component
|
||||
/**
|
||||
* If defined, will spawn in a non-nbt structure component
|
||||
*/
|
||||
public Function<Quartet<World, Random, Integer, Integer>, StructureStart> start;
|
||||
|
||||
// If defined, will override regular spawn location checking, for placing at specific coordinates or with special rules
|
||||
/**
|
||||
* If defined, will override regular spawn location checking, for placing at specific coordinates or with special rules
|
||||
*/
|
||||
public Predicate<WorldCoordinate> checkCoordinates;
|
||||
|
||||
// Our regular spawning mechanics, based on biome, you should generally use these
|
||||
/**
|
||||
* Defines whether the current biome is valid for spawning this structure
|
||||
*/
|
||||
public Predicate<BiomeGenBase> canSpawn;
|
||||
|
||||
/**
|
||||
* The chance of this structure spawning relative to others,
|
||||
* higher weights will spawn more often.
|
||||
*/
|
||||
public int spawnWeight = 1;
|
||||
|
||||
// Named jigsaw pools that are referenced within the structure
|
||||
/**
|
||||
* Named jigsaw pools that are referenced by jigsaw blocks within the structure
|
||||
*/
|
||||
public Map<String, JigsawPool> pools;
|
||||
|
||||
/**
|
||||
* The name of the "core" pool, which the structure starts generation from,
|
||||
* must be a name of a pool defined within `pool`
|
||||
*/
|
||||
public String startPool;
|
||||
|
||||
// Maximum amount of components in this structure
|
||||
/**
|
||||
* Maximum amount of components in this structure.
|
||||
* Once the structure reaches this many components,
|
||||
* it will only generate fallback pieces and stop
|
||||
*
|
||||
* Note: there is a hard limit of 1024 pieces to prevent infinite generation,
|
||||
* even if some pieces are marked as required!
|
||||
*/
|
||||
public int sizeLimit = 8;
|
||||
|
||||
// How far the structure can extend horizontally from the center, maximum of 128
|
||||
// This could be increased by changing GenStructure:range from 8, but this is already quite reasonably large
|
||||
// This could be increased by changing GenStructure:range from 8, but this is
|
||||
// already quite reasonably large
|
||||
/**
|
||||
* How far the structure can extend horizontally from the center, maximum of 128
|
||||
*/
|
||||
public int rangeLimit = 128;
|
||||
|
||||
// Height modifiers, will clamp height that the start generates at, allowing for:
|
||||
// * Submarines that must spawn under the ocean surface
|
||||
// * Bunkers that sit underneath the ground
|
||||
/**
|
||||
* Height modifiers, will clamp height that the start generates at, allowing for:
|
||||
* * Submarines that must spawn under the ocean surface
|
||||
* * Bunkers that sit underneath the ground
|
||||
*/
|
||||
public int minHeight = 1;
|
||||
|
||||
/**
|
||||
* @see minHeight
|
||||
*/
|
||||
public int maxHeight = 128;
|
||||
|
||||
protected SpawnCondition(int weight, Predicate<BiomeGenBase> predicate) {
|
||||
|
||||
@ -0,0 +1,10 @@
|
||||
package com.hbm.world.gen.nbt.selector;
|
||||
|
||||
import net.minecraft.world.biome.BiomeGenBase;
|
||||
import net.minecraft.world.gen.structure.StructureComponent.BlockSelector;
|
||||
|
||||
public abstract class BiomeBlockSelector extends BlockSelector {
|
||||
|
||||
public BiomeGenBase nextBiome;
|
||||
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package com.hbm.world.gen.nbt.selector;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class BiomeFillerSelector extends BiomeBlockSelector {
|
||||
|
||||
@Override
|
||||
public void selectBlocks(Random rand, int x, int y, int z, boolean notInterior) {
|
||||
field_151562_a = nextBiome.fillerBlock;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package com.hbm.world.gen.nbt.selector;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class BiomeTopSelector extends BiomeBlockSelector {
|
||||
|
||||
@Override
|
||||
public void selectBlocks(Random rand, int x, int y, int z, boolean notInterior) {
|
||||
field_151562_a = nextBiome.topBlock;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
package com.hbm.world.gen.nbt.selector;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.world.gen.structure.StructureComponent.BlockSelector;
|
||||
|
||||
public class BrickSelector extends BlockSelector {
|
||||
|
||||
@Override
|
||||
public void selectBlocks(Random rand, int x, int y, int z, boolean notInterior) {
|
||||
field_151562_a = Blocks.brick_block;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package com.hbm.world.gen.nbt.selector;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.world.gen.structure.StructureComponent.BlockSelector;
|
||||
|
||||
public class StoneBrickSelector extends BlockSelector {
|
||||
|
||||
@Override
|
||||
public void selectBlocks(Random rand, int x, int y, int z, boolean notInterior) {
|
||||
field_151562_a = Blocks.stonebrick;
|
||||
float f = rand.nextFloat();
|
||||
|
||||
if (f < 0.2F) {
|
||||
this.selectedBlockMetaData = 2;
|
||||
} else if (f < 0.5F) {
|
||||
this.selectedBlockMetaData = 1;
|
||||
} else {
|
||||
this.selectedBlockMetaData = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -6354,6 +6354,8 @@ tile.wand_air.name=Structure Wand Block (Air)
|
||||
tile.wand_loot.name=Structure Wand Block (Lootable)
|
||||
tile.wand_jigsaw.name=Structure Wand Block (Jigsaw)
|
||||
tile.wand_logic.name=Structure Wand Block (Logic)
|
||||
tile.wand_structure.load.name=Structure Loading Block
|
||||
tile.wand_structure.save.name=Structure Saving Block
|
||||
tile.waste_earth.name=Dead Grass
|
||||
tile.waste_leaves.name=Dead Leaves
|
||||
tile.waste_log.name=Charred Log
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 289 B |
Binary file not shown.
|
After Width: | Height: | Size: 285 B |
Loading…
x
Reference in New Issue
Block a user