mirror of
https://github.com/Creators-of-Create/Create.git
synced 2025-01-23 03:18:06 +01:00
Schematicannon and Holograms
- Uploaded Blueprints can be previewed by the owner - The Schematicannon prints the schematic from blocks in attached inventories
This commit is contained in:
parent
550b477d8d
commit
b66aa4c4d3
15 changed files with 1002 additions and 66 deletions
|
@ -1,5 +1,6 @@
|
|||
package com.simibubi.create;
|
||||
|
||||
import com.simibubi.create.item.ItemBlueprint;
|
||||
import com.simibubi.create.item.ItemWandSymmetry;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
|
@ -11,7 +12,7 @@ public enum AllItems {
|
|||
|
||||
SYMMETRY_WAND(new ItemWandSymmetry(standardProperties())),
|
||||
EMPTY_BLUEPRINT(new Item(standardProperties().maxStackSize(1))),
|
||||
BLUEPRINT(new Item(standardProperties().maxStackSize(1)));
|
||||
BLUEPRINT(new ItemBlueprint(standardProperties()));
|
||||
|
||||
public Item item;
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ public class ClientSchematicLoader {
|
|||
Create.logger.fatal("Missing Schematic file: " + path.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
InputStream in;
|
||||
try {
|
||||
in = Files.newInputStream(path, StandardOpenOption.READ);
|
||||
|
@ -108,7 +108,7 @@ public class ClientSchematicLoader {
|
|||
activeUploads.remove(schematic);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void refresh() {
|
||||
FilesHelper.createFolderIfMissing("schematics");
|
||||
availableSchematics.clear();
|
||||
|
|
|
@ -4,6 +4,7 @@ import org.apache.logging.log4j.LogManager;
|
|||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import com.simibubi.create.networking.Packets;
|
||||
import com.simibubi.create.schematic.SchematicHologram;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.item.Item;
|
||||
|
@ -50,6 +51,7 @@ public class Create {
|
|||
AllTileEntities.registerRenderers();
|
||||
cSchematicLoader = new ClientSchematicLoader();
|
||||
sSchematicLoader = new ServerSchematicLoader();
|
||||
new SchematicHologram();
|
||||
// ScrollFixer.init();
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ import net.minecraft.util.text.TextFormatting;
|
|||
|
||||
public class ServerSchematicLoader {
|
||||
|
||||
private static final String PATH = "schematics/uploaded";
|
||||
public static final String PATH = "schematics/uploaded";
|
||||
private Map<String, OutputStream> activeDownloads;
|
||||
private Map<String, DimensionPos> activeTables;
|
||||
|
||||
|
@ -38,6 +38,9 @@ public class ServerSchematicLoader {
|
|||
|
||||
FilesHelper.createFolderIfMissing(playerPath);
|
||||
|
||||
if (activeDownloads.containsKey(playerSchematicId))
|
||||
return;
|
||||
|
||||
try {
|
||||
Files.deleteIfExists(Paths.get(PATH, playerSchematicId));
|
||||
OutputStream writer = Files.newOutputStream(Paths.get(PATH, playerSchematicId),
|
||||
|
@ -45,6 +48,15 @@ public class ServerSchematicLoader {
|
|||
Create.logger.info("Receiving New Schematic: " + playerSchematicId);
|
||||
activeDownloads.put(playerSchematicId, writer);
|
||||
activeTables.put(playerSchematicId, dimensionPos);
|
||||
|
||||
if (player.openContainer instanceof SchematicTableContainer) {
|
||||
SchematicTableContainer c = (SchematicTableContainer) player.openContainer;
|
||||
c.schematicUploading = schematic;
|
||||
c.isUploading = true;
|
||||
c.sendSchematicUpdate = true;
|
||||
player.openContainer.detectAndSendChanges();
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -53,11 +65,14 @@ public class ServerSchematicLoader {
|
|||
public void handleWriteRequest(ServerPlayerEntity player, String schematic, byte[] data) {
|
||||
String playerSchematicId = player.getName().getFormattedText() + "/" + schematic;
|
||||
if (activeDownloads.containsKey(playerSchematicId)) {
|
||||
|
||||
try {
|
||||
activeDownloads.get(playerSchematicId).write(data);
|
||||
Create.logger.info("Writing to Schematic: " + playerSchematicId);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
activeDownloads.remove(playerSchematicId);
|
||||
activeTables.remove(playerSchematicId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -68,13 +83,27 @@ public class ServerSchematicLoader {
|
|||
if (activeDownloads.containsKey(playerSchematicId)) {
|
||||
try {
|
||||
activeDownloads.get(playerSchematicId).close();
|
||||
activeDownloads.remove(playerSchematicId);
|
||||
Create.logger.info("Finished receiving Schematic: " + playerSchematicId);
|
||||
|
||||
DimensionPos dimpos = activeTables.remove(playerSchematicId);
|
||||
|
||||
if (dimpos == null)
|
||||
return;
|
||||
|
||||
BlockState blockState = dimpos.world.getBlockState(dimpos.pos);
|
||||
if (!AllBlocks.SCHEMATIC_TABLE.typeOf(blockState))
|
||||
return;
|
||||
|
||||
if (player.openContainer instanceof SchematicTableContainer) {
|
||||
SchematicTableContainer c = (SchematicTableContainer) player.openContainer;
|
||||
c.isUploading = false;
|
||||
c.schematicUploading = null;
|
||||
c.progress = 0;
|
||||
c.sendSchematicUpdate = true;
|
||||
c.detectAndSendChanges();
|
||||
}
|
||||
|
||||
SchematicTableTileEntity tileEntity = (SchematicTableTileEntity) dimpos.world.getTileEntity(dimpos.pos);
|
||||
if (tileEntity.inputStack.isEmpty())
|
||||
return;
|
||||
|
@ -82,15 +111,19 @@ public class ServerSchematicLoader {
|
|||
return;
|
||||
|
||||
tileEntity.inputStack = ItemStack.EMPTY;
|
||||
tileEntity.outputStack = new ItemStack(AllItems.BLUEPRINT.get());
|
||||
tileEntity.outputStack
|
||||
.setDisplayName(new StringTextComponent(TextFormatting.RESET + "" + TextFormatting.WHITE
|
||||
+ "Blueprint (" + TextFormatting.GOLD + schematic + TextFormatting.WHITE + ")"));
|
||||
tileEntity.markDirty();
|
||||
ItemStack blueprint = new ItemStack(AllItems.BLUEPRINT.get());
|
||||
blueprint.setDisplayName(new StringTextComponent(TextFormatting.RESET + "" + TextFormatting.WHITE
|
||||
+ "Blueprint (" + TextFormatting.GOLD + schematic + TextFormatting.WHITE + ")"));
|
||||
blueprint.getTag().putString("Owner", player.getName().getFormattedText());
|
||||
blueprint.getTag().putString("File", schematic);
|
||||
|
||||
tileEntity.outputStack = blueprint;
|
||||
|
||||
dimpos.world.notifyBlockUpdate(dimpos.pos, blockState, blockState, 3);
|
||||
|
||||
if (player.openContainer instanceof SchematicTableContainer) {
|
||||
((SchematicTableContainer) player.openContainer).updateContent();
|
||||
player.openContainer.detectAndSendChanges();
|
||||
SchematicTableContainer c = (SchematicTableContainer) player.openContainer;
|
||||
c.updateContent();
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
|
|
|
@ -2,14 +2,20 @@ package com.simibubi.create.block;
|
|||
|
||||
import com.simibubi.create.AllContainers;
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.networking.PacketSchematicTableContainer;
|
||||
import com.simibubi.create.networking.Packets;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.inventory.Inventory;
|
||||
import net.minecraft.inventory.container.Container;
|
||||
import net.minecraft.inventory.container.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.fml.network.PacketDistributor;
|
||||
|
||||
public class SchematicTableContainer extends Container {
|
||||
|
||||
|
@ -23,13 +29,20 @@ public class SchematicTableContainer extends Container {
|
|||
private SchematicTableTileEntity te;
|
||||
private Slot inputSlot;
|
||||
private Slot outputSlot;
|
||||
private PlayerEntity player;
|
||||
|
||||
public String schematicUploading;
|
||||
public boolean isUploading;
|
||||
public float progress;
|
||||
public boolean sendSchematicUpdate;
|
||||
|
||||
public SchematicTableContainer(int id, PlayerInventory inv) {
|
||||
this(id, inv, null);
|
||||
}
|
||||
|
||||
|
||||
public SchematicTableContainer(int id, PlayerInventory inv, SchematicTableTileEntity te) {
|
||||
super(AllContainers.SchematicTable.type, id);
|
||||
this.player = inv.player;
|
||||
this.te = te;
|
||||
|
||||
inputSlot = new Slot(tableInventory, 0, 31, 15) {
|
||||
|
@ -51,6 +64,10 @@ public class SchematicTableContainer extends Container {
|
|||
|
||||
updateContent();
|
||||
|
||||
if (te != null) {
|
||||
this.addListener(te);
|
||||
}
|
||||
|
||||
// player Slots
|
||||
tableInventory.openInventory(inv.player);
|
||||
for (int l = 0; l < 3; ++l) {
|
||||
|
@ -63,6 +80,12 @@ public class SchematicTableContainer extends Container {
|
|||
this.addSlot(new Slot(inv, i1, -8 + i1 * 18, 135));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void detectAndSendChanges() {
|
||||
super.detectAndSendChanges();
|
||||
sendSchematicInfo();
|
||||
}
|
||||
|
||||
public boolean canWrite() {
|
||||
return inputSlot.getHasStack() && !outputSlot.getHasStack();
|
||||
|
@ -98,14 +121,41 @@ public class SchematicTableContainer extends Container {
|
|||
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
|
||||
public void updateContent() {
|
||||
if (te != null) {
|
||||
inputSlot.putStack(te.inputStack);
|
||||
outputSlot.putStack(te.outputStack);
|
||||
schematicUploading = te.uploadingSchematic;
|
||||
progress = te.uploadingProgress;
|
||||
sendSchematicUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void sendSchematicInfo() {
|
||||
if (player instanceof ServerPlayerEntity) {
|
||||
if (sendSchematicUpdate) {
|
||||
Packets.channel.send(PacketDistributor.PLAYER.with(() -> (ServerPlayerEntity) player),
|
||||
new PacketSchematicTableContainer(schematicUploading, progress));
|
||||
sendSchematicUpdate = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void receiveSchematicInfo(String schematic, float progress) {
|
||||
if (schematic.isEmpty()) {
|
||||
this.schematicUploading = null;
|
||||
this.isUploading = false;
|
||||
this.progress = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
this.isUploading = true;
|
||||
this.schematicUploading = schematic;
|
||||
this.progress = .5f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onContainerClosed(PlayerEntity playerIn) {
|
||||
if (te != null) {
|
||||
|
@ -113,10 +163,10 @@ public class SchematicTableContainer extends Container {
|
|||
te.outputStack = outputSlot.getStack();
|
||||
te.markDirty();
|
||||
}
|
||||
|
||||
|
||||
super.onContainerClosed(playerIn);
|
||||
}
|
||||
|
||||
|
||||
public SchematicTableTileEntity getTileEntity() {
|
||||
return te;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import net.minecraft.entity.player.PlayerEntity;
|
|||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.inventory.ItemStackHelper;
|
||||
import net.minecraft.inventory.container.Container;
|
||||
import net.minecraft.inventory.container.IContainerListener;
|
||||
import net.minecraft.inventory.container.INamedContainerProvider;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
|
@ -16,11 +17,14 @@ import net.minecraft.util.NonNullList;
|
|||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
|
||||
public class SchematicTableTileEntity extends TileEntitySynced implements ITickableTileEntity, INamedContainerProvider {
|
||||
public class SchematicTableTileEntity extends TileEntitySynced implements ITickableTileEntity, INamedContainerProvider, IContainerListener {
|
||||
|
||||
public ItemStack inputStack;
|
||||
public ItemStack outputStack;
|
||||
|
||||
public String uploadingSchematic;
|
||||
public float uploadingProgress;
|
||||
|
||||
public SchematicTableTileEntity() {
|
||||
this(AllTileEntities.SchematicTable.type);
|
||||
}
|
||||
|
@ -69,5 +73,25 @@ public class SchematicTableTileEntity extends TileEntitySynced implements ITicka
|
|||
public ITextComponent getDisplayName() {
|
||||
return new StringTextComponent(getType().getRegistryName().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendAllContents(Container containerToSend, NonNullList<ItemStack> itemsList) {
|
||||
inputStack = itemsList.get(0);
|
||||
outputStack = itemsList.get(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendSlotContents(Container containerToSend, int slotInd, ItemStack stack) {
|
||||
if (slotInd == 0) {
|
||||
inputStack = stack;
|
||||
}
|
||||
if (slotInd == 1) {
|
||||
outputStack = stack;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendWindowProperty(Container containerIn, int varToUpdate, int newValue) {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,14 +3,12 @@ package com.simibubi.create.block;
|
|||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.BlockRayTraceResult;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.IWorldReader;
|
||||
|
||||
public class SchematicannonBlock extends Block {
|
||||
|
||||
|
@ -29,17 +27,16 @@ public class SchematicannonBlock extends Block {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
|
||||
BlockRayTraceResult hit) {
|
||||
TileEntity tileEntity = worldIn.getTileEntity(pos);
|
||||
if (worldIn.isRemote)
|
||||
return true;
|
||||
|
||||
if (tileEntity == null)
|
||||
return false;
|
||||
|
||||
player.sendMessage(new StringTextComponent("" + ((SchematicannonTileEntity) tileEntity).getTest()));
|
||||
return true;
|
||||
public BlockState updatePostPlacement(BlockState stateIn, Direction facing, BlockState facingState, IWorld worldIn,
|
||||
BlockPos currentPos, BlockPos facingPos) {
|
||||
((SchematicannonTileEntity) worldIn.getTileEntity(currentPos)).findInventories();
|
||||
return stateIn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNeighborChange(BlockState state, IWorldReader world, BlockPos pos, BlockPos neighbor) {
|
||||
((SchematicannonTileEntity) world.getTileEntity(pos)).findInventories();
|
||||
super.onNeighborChange(state, world, pos, neighbor);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,48 +1,155 @@
|
|||
package com.simibubi.create.block;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.ServerSchematicLoader;
|
||||
import com.simibubi.create.schematic.Cuboid;
|
||||
import com.simibubi.create.schematic.SchematicWorld;
|
||||
import com.simibubi.create.utility.TileEntitySynced;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.CompressedStreamTools;
|
||||
import net.minecraft.tileentity.ITickableTileEntity;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.gen.feature.template.PlacementSettings;
|
||||
import net.minecraft.world.gen.feature.template.Template;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
public class SchematicannonTileEntity extends TileEntitySynced implements ITickableTileEntity {
|
||||
|
||||
private int test = 0;
|
||||
|
||||
public static final int PLACEMENT_DELAY = 2;
|
||||
|
||||
private SchematicWorld reader;
|
||||
private BlockPos currentPos;
|
||||
public BlockPos anchor;
|
||||
public String schematicToPrint;
|
||||
public boolean missingBlock;
|
||||
|
||||
public List<IItemHandler> attachedInventories;
|
||||
|
||||
private int cooldown;
|
||||
|
||||
public SchematicannonTileEntity() {
|
||||
super(AllTileEntities.Schematicannon.type);
|
||||
this(AllTileEntities.Schematicannon.type);
|
||||
}
|
||||
|
||||
|
||||
public SchematicannonTileEntity(TileEntityType<?> tileEntityTypeIn) {
|
||||
super(tileEntityTypeIn);
|
||||
attachedInventories = new LinkedList<>();
|
||||
}
|
||||
|
||||
|
||||
public void findInventories() {
|
||||
for (Direction facing : Direction.values()) {
|
||||
TileEntity tileEntity = world.getTileEntity(pos.offset(facing));
|
||||
if (tileEntity != null) {
|
||||
LazyOptional<IItemHandler> capability = tileEntity.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, facing.getOpposite());
|
||||
if (capability.isPresent()) {
|
||||
attachedInventories.add(capability.orElse(null));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(CompoundNBT compound) {
|
||||
super.read(compound);
|
||||
test = compound.getInt("Test");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public CompoundNBT write(CompoundNBT compound) {
|
||||
compound.putInt("Test", test);
|
||||
return super.write(compound);
|
||||
}
|
||||
|
||||
public int getTest() {
|
||||
return test;
|
||||
}
|
||||
|
||||
public void setTest(int test) {
|
||||
this.test = test;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
test++;
|
||||
if (world.isRemote)
|
||||
return;
|
||||
if (schematicToPrint == null)
|
||||
return;
|
||||
if (cooldown-- > 0)
|
||||
return;
|
||||
cooldown = PLACEMENT_DELAY;
|
||||
|
||||
if (reader == null) {
|
||||
currentPos = BlockPos.ZERO;
|
||||
currentPos = currentPos.offset(Direction.WEST);
|
||||
|
||||
String filepath = ServerSchematicLoader.PATH + "/" + schematicToPrint;
|
||||
Template activeTemplate = new Template();
|
||||
|
||||
InputStream stream = null;
|
||||
try {
|
||||
stream = Files.newInputStream(Paths.get(filepath), StandardOpenOption.READ);
|
||||
CompoundNBT nbt = CompressedStreamTools.readCompressed(stream);
|
||||
activeTemplate.read(nbt);
|
||||
reader = new SchematicWorld(new HashMap<>(), new Cuboid(BlockPos.ZERO, 0, 0, 0), anchor);
|
||||
activeTemplate.addBlocksToWorld(reader, anchor, new PlacementSettings());
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (stream != null)
|
||||
IOUtils.closeQuietly(stream);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
BlockPos size = reader.getBounds().getSize();
|
||||
BlockState state;
|
||||
do {
|
||||
if (!missingBlock)
|
||||
currentPos = currentPos.offset(Direction.EAST);
|
||||
if (currentPos.getX() > size.getX()) {
|
||||
currentPos = new BlockPos(0, currentPos.getY(), currentPos.getZ() + 1);
|
||||
}
|
||||
if (currentPos.getZ() > size.getZ()) {
|
||||
currentPos = new BlockPos(currentPos.getX(), currentPos.getY() + 1, 0);
|
||||
}
|
||||
if (currentPos.getY() > size.getY()) {
|
||||
schematicToPrint = null;
|
||||
currentPos = null;
|
||||
anchor = null;
|
||||
reader = null;
|
||||
missingBlock = false;
|
||||
return;
|
||||
}
|
||||
state = reader.getBlockState(anchor.add(currentPos));
|
||||
} while (state.getBlock() == Blocks.AIR);
|
||||
|
||||
missingBlock = true;
|
||||
ItemStack requiredItem = new ItemStack(BlockItem.BLOCK_TO_ITEM.getOrDefault(state.getBlock(), Items.AIR));
|
||||
for (IItemHandler iItemHandler : attachedInventories) {
|
||||
for (int slot = 0; slot < iItemHandler.getSlots(); slot++) {
|
||||
ItemStack stackInSlot = iItemHandler.getStackInSlot(slot);
|
||||
if (!stackInSlot.isItemEqual(requiredItem))
|
||||
continue;
|
||||
iItemHandler.extractItem(slot, 1, false);
|
||||
world.setBlockState(currentPos.add(anchor), state);
|
||||
missingBlock = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -25,8 +25,6 @@ public class SchematicTableScreen extends ContainerScreen<SchematicTableContaine
|
|||
private SimiButton button;
|
||||
private DynamicLabel label;
|
||||
|
||||
private boolean isUploading;
|
||||
private String uploadingSchematic;
|
||||
private float progress;
|
||||
private float lastProgress;
|
||||
|
||||
|
@ -75,7 +73,10 @@ public class SchematicTableScreen extends ContainerScreen<SchematicTableContaine
|
|||
GuiResources.SCHEMATIC_TABLE.draw(this, xMainWindow, yMainWindow);
|
||||
GuiResources.PLAYER_INVENTORY.draw(this, x, y + 20);
|
||||
|
||||
font.drawString("Choose a Schematic", xMainWindow + 50, yMainWindow + 10, GuiResources.FONT_COLOR);
|
||||
if (container.isUploading)
|
||||
font.drawString("Uploading...", xMainWindow + 76, yMainWindow + 10, GuiResources.FONT_COLOR);
|
||||
else
|
||||
font.drawString("Choose a Schematic", xMainWindow + 50, yMainWindow + 10, GuiResources.FONT_COLOR);
|
||||
font.drawString("Inventory", x + 7, y + 26, 0x666666);
|
||||
|
||||
if (schematics == null) {
|
||||
|
@ -111,9 +112,17 @@ public class SchematicTableScreen extends ContainerScreen<SchematicTableContaine
|
|||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
if (isUploading) {
|
||||
if (container.isUploading) {
|
||||
lastProgress = progress;
|
||||
progress = Create.cSchematicLoader.getProgress(uploadingSchematic);
|
||||
progress = Create.cSchematicLoader.getProgress(container.schematicUploading);
|
||||
label.colored(0xCCDDFF);
|
||||
button.active = false;
|
||||
|
||||
} else {
|
||||
progress = 0;
|
||||
lastProgress = 0;
|
||||
label.colored(0xFFFFFF);
|
||||
button.active = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,9 +135,8 @@ public class SchematicTableScreen extends ContainerScreen<SchematicTableContaine
|
|||
|
||||
List<String> availableSchematics = Create.cSchematicLoader.getAvailableSchematics();
|
||||
lastProgress = progress = 0;
|
||||
uploadingSchematic = availableSchematics.get(schematics.getState());
|
||||
isUploading = true;
|
||||
Create.cSchematicLoader.startNewUpload(uploadingSchematic);
|
||||
String schematic = availableSchematics.get(schematics.getState());
|
||||
Create.cSchematicLoader.startNewUpload(schematic);
|
||||
}
|
||||
|
||||
return super.mouseClicked(p_mouseClicked_1_, p_mouseClicked_3_, p_mouseClicked_5_);
|
||||
|
|
102
src/main/java/com/simibubi/create/item/ItemBlueprint.java
Normal file
102
src/main/java/com/simibubi/create/item/ItemBlueprint.java
Normal file
|
@ -0,0 +1,102 @@
|
|||
package com.simibubi.create.item;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.block.SchematicannonTileEntity;
|
||||
import com.simibubi.create.schematic.SchematicHologram;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.inventory.EquipmentSlotType;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemUseContext;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.CompressedStreamTools;
|
||||
import net.minecraft.nbt.NBTUtil;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.gen.feature.template.Template;
|
||||
|
||||
public class ItemBlueprint extends Item {
|
||||
|
||||
public ItemBlueprint(Properties properties) {
|
||||
super(properties.maxStackSize(1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResultType onItemUse(ItemUseContext context) {
|
||||
|
||||
World world = context.getWorld();
|
||||
|
||||
CompoundNBT tag = context.getItem().getTag();
|
||||
if (tag.contains("File")) {
|
||||
|
||||
BlockPos pos = context.getPos();
|
||||
BlockState blockState = world.getBlockState(pos);
|
||||
if (AllBlocks.SCHEMATICANNON.typeOf(blockState)) {
|
||||
if (world.isRemote) {
|
||||
SchematicHologram.reset();
|
||||
return ActionResultType.SUCCESS;
|
||||
}
|
||||
if (!tag.contains("Anchor"))
|
||||
return ActionResultType.FAIL;
|
||||
|
||||
SchematicannonTileEntity te = (SchematicannonTileEntity) world.getTileEntity(pos);
|
||||
te.schematicToPrint = tag.getString("Owner") + "/" + tag.getString("File");
|
||||
te.anchor = NBTUtil.readBlockPos(tag.getCompound("Anchor"));
|
||||
context.getPlayer().setItemStackToSlot(EquipmentSlotType.MAINHAND, ItemStack.EMPTY);
|
||||
return ActionResultType.SUCCESS;
|
||||
}
|
||||
|
||||
tag.put("Anchor", NBTUtil.writeBlockPos(pos.offset(context.getFace())));
|
||||
|
||||
if (!world.isRemote) {
|
||||
return ActionResultType.SUCCESS;
|
||||
}
|
||||
|
||||
if (!(context.getPlayer().getName().getFormattedText().equals(tag.getString("Owner")))) {
|
||||
context.getPlayer()
|
||||
.sendStatusMessage(new StringTextComponent("You are not the Owner of this Schematic."), true);
|
||||
}
|
||||
|
||||
String filepath = "schematics/" + tag.getString("File");
|
||||
Template t = new Template();
|
||||
|
||||
InputStream stream = null;
|
||||
try {
|
||||
stream = Files.newInputStream(Paths.get(filepath), StandardOpenOption.READ);
|
||||
CompoundNBT nbt = CompressedStreamTools.readCompressed(stream);
|
||||
t.read(nbt);
|
||||
new SchematicHologram().startHologram(t, pos.offset(context.getFace()));
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (stream != null)
|
||||
IOUtils.closeQuietly(stream);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
context.getPlayer().getCooldownTracker().setCooldown(this, 10);
|
||||
return ActionResultType.SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResult<ItemStack> onItemRightClick(World worldIn, PlayerEntity playerIn, Hand handIn) {
|
||||
return super.onItemRightClick(worldIn, playerIn, handIn);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package com.simibubi.create.networking;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.simibubi.create.block.SchematicTableContainer;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.inventory.container.Container;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.fml.network.NetworkEvent.Context;
|
||||
|
||||
public class PacketSchematicTableContainer {
|
||||
|
||||
public String schematic;
|
||||
public float progress;
|
||||
|
||||
public PacketSchematicTableContainer(String schematicToUpload, float progress) {
|
||||
this.schematic = schematicToUpload;
|
||||
if (this.schematic == null)
|
||||
this.schematic = "";
|
||||
this.progress = progress;
|
||||
}
|
||||
|
||||
public PacketSchematicTableContainer(PacketBuffer buffer) {
|
||||
this.schematic = buffer.readString();
|
||||
this.progress = buffer.readFloat();
|
||||
}
|
||||
|
||||
public void toBytes(PacketBuffer buffer) {
|
||||
buffer.writeString(schematic);
|
||||
buffer.writeFloat(progress);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void handle(Supplier<Context> context) {
|
||||
context.get().enqueueWork(() -> {
|
||||
Container c = Minecraft.getInstance().player.openContainer;
|
||||
if (c != null && c instanceof SchematicTableContainer) {
|
||||
((SchematicTableContainer) c).receiveSchematicInfo(schematic, progress);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -13,16 +13,17 @@ public class Packets {
|
|||
public static final SimpleChannel channel = NetworkRegistry.newSimpleChannel(
|
||||
new ResourceLocation(Create.ID, "main"), () -> PROTOCOL_VERSION, PROTOCOL_VERSION::equals,
|
||||
PROTOCOL_VERSION::equals);
|
||||
|
||||
|
||||
public static void registerPackets() {
|
||||
int i = 0;
|
||||
|
||||
channel.registerMessage(i++, PacketNbt.class, PacketNbt::toBytes, PacketNbt::new,
|
||||
PacketNbt::handle);
|
||||
channel.registerMessage(i++, PacketSchematicUpload.class, PacketSchematicUpload::toBytes, PacketSchematicUpload::new,
|
||||
PacketSchematicUpload::handle);
|
||||
channel.registerMessage(i++, PacketSymmetryEffect.class, PacketSymmetryEffect::toBytes, PacketSymmetryEffect::new,
|
||||
PacketSymmetryEffect::handle);
|
||||
channel.registerMessage(i++, PacketNbt.class, PacketNbt::toBytes, PacketNbt::new, PacketNbt::handle);
|
||||
channel.registerMessage(i++, PacketSchematicTableContainer.class, PacketSchematicTableContainer::toBytes,
|
||||
PacketSchematicTableContainer::new, PacketSchematicTableContainer::handle);
|
||||
channel.registerMessage(i++, PacketSchematicUpload.class, PacketSchematicUpload::toBytes,
|
||||
PacketSchematicUpload::new, PacketSchematicUpload::handle);
|
||||
channel.registerMessage(i++, PacketSymmetryEffect.class, PacketSymmetryEffect::toBytes,
|
||||
PacketSymmetryEffect::new, PacketSymmetryEffect::handle);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
71
src/main/java/com/simibubi/create/schematic/Cuboid.java
Normal file
71
src/main/java/com/simibubi/create/schematic/Cuboid.java
Normal file
|
@ -0,0 +1,71 @@
|
|||
package com.simibubi.create.schematic;
|
||||
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
public class Cuboid {
|
||||
|
||||
public int x;
|
||||
public int y;
|
||||
public int z;
|
||||
public int width;
|
||||
public int height;
|
||||
public int length;
|
||||
|
||||
public Cuboid(BlockPos origin, BlockPos size) {
|
||||
this(origin, size.getX(), size.getY(), size.getZ());
|
||||
}
|
||||
|
||||
public Cuboid(BlockPos origin, int width, int height, int length) {
|
||||
this.x = origin.getX() + ((width < 0) ? width : 0);
|
||||
this.y = origin.getY() + ((height < 0) ? height : 0);
|
||||
this.z = origin.getZ() + ((length < 0) ? length : 0);
|
||||
this.width = Math.abs(width);
|
||||
this.height = Math.abs(height);
|
||||
this.length = Math.abs(length);
|
||||
}
|
||||
|
||||
public BlockPos getOrigin() {
|
||||
return new BlockPos(x, y, z);
|
||||
}
|
||||
|
||||
public BlockPos getSize() {
|
||||
return new BlockPos(width, height, length);
|
||||
}
|
||||
|
||||
public Cuboid clone() {
|
||||
return new Cuboid(new BlockPos(x, y, z), width, height, length);
|
||||
}
|
||||
|
||||
public void move(int x, int y, int z) {
|
||||
this.x += x;
|
||||
this.y += y;
|
||||
this.z += z;
|
||||
}
|
||||
|
||||
public void centerHorizontallyOn(BlockPos pos) {
|
||||
x = pos.getX() - (width / 2);
|
||||
y = pos.getY();
|
||||
z = pos.getZ() - (length / 2);
|
||||
}
|
||||
|
||||
public boolean intersects(Cuboid other) {
|
||||
return !(other.x >= x + width || other.z >= z + length || other.x + other.width <= x
|
||||
|| other.z + other.length <= z);
|
||||
}
|
||||
|
||||
public boolean contains(BlockPos pos) {
|
||||
return (pos.getX() >= x && pos.getX() < x + width) && (pos.getY() >= y && pos.getY() < y + height)
|
||||
&& (pos.getZ() >= z && pos.getZ() < z + length);
|
||||
}
|
||||
|
||||
public BlockPos getCenter() {
|
||||
return getOrigin().add(width / 2, height / 2, length / 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof Cuboid && ((Cuboid) obj).getOrigin().equals(getOrigin())
|
||||
&& ((Cuboid) obj).getSize().equals(getSize());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,210 @@
|
|||
package com.simibubi.create.schematic;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.ActiveRenderInfo;
|
||||
import net.minecraft.client.renderer.BlockRendererDispatcher;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.RegionRenderCacheBuilder;
|
||||
import net.minecraft.client.renderer.texture.AtlasTexture;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.client.renderer.vertex.VertexFormat;
|
||||
import net.minecraft.client.renderer.vertex.VertexFormatElement;
|
||||
import net.minecraft.client.renderer.vertex.VertexFormatElement.Usage;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.BlockRenderLayer;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.gen.feature.template.PlacementSettings;
|
||||
import net.minecraft.world.gen.feature.template.Template;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.client.ForgeHooksClient;
|
||||
import net.minecraftforge.client.event.RenderWorldLastEvent;
|
||||
import net.minecraftforge.client.model.data.EmptyModelData;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||
import net.minecraftforge.fml.common.gameevent.TickEvent;
|
||||
import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent;
|
||||
|
||||
@EventBusSubscriber(Dist.CLIENT)
|
||||
public class SchematicHologram {
|
||||
|
||||
// These buffers are large enough for an entire chunk, consider using
|
||||
// smaller buffers
|
||||
private static final RegionRenderCacheBuilder bufferCache = new RegionRenderCacheBuilder();
|
||||
private static final boolean[] usedBlockRenderLayers = new boolean[BlockRenderLayer.values().length];
|
||||
private static final boolean[] startedBufferBuilders = new boolean[BlockRenderLayer.values().length];
|
||||
|
||||
private static SchematicHologram instance;
|
||||
private boolean active;
|
||||
private boolean changed;
|
||||
private SchematicWorld schematic;
|
||||
private BlockPos anchor;
|
||||
|
||||
public SchematicHologram() {
|
||||
instance = this;
|
||||
changed = false;
|
||||
}
|
||||
|
||||
public void startHologram(Template schematic, BlockPos anchor) {
|
||||
this.schematic = new SchematicWorld(new HashMap<>(), new Cuboid(BlockPos.ZERO, BlockPos.ZERO), anchor);
|
||||
this.anchor = anchor;
|
||||
schematic.addBlocksToWorld(this.schematic, anchor, new PlacementSettings());
|
||||
active = true;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
public static SchematicHologram getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
// public static void display(Schematic schematic) {
|
||||
// instance = new SchematicHologram();
|
||||
// instance.startHologram(schematic);
|
||||
// }
|
||||
|
||||
public static void reset() {
|
||||
instance = null;
|
||||
}
|
||||
|
||||
public void schematicChanged() {
|
||||
changed = true;
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onClientTickEvent(final ClientTickEvent event) {
|
||||
if (instance != null && instance.active) {
|
||||
final Minecraft minecraft = Minecraft.getInstance();
|
||||
if (event.phase != TickEvent.Phase.END)
|
||||
return;
|
||||
if (minecraft.world == null)
|
||||
return;
|
||||
if (minecraft.player == null)
|
||||
return;
|
||||
if (instance.changed) {
|
||||
redraw(minecraft);
|
||||
instance.changed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void redraw(final Minecraft minecraft) {
|
||||
Arrays.fill(usedBlockRenderLayers, false);
|
||||
Arrays.fill(startedBufferBuilders, false);
|
||||
|
||||
final SchematicWorld blockAccess = instance.schematic;
|
||||
final BlockRendererDispatcher blockRendererDispatcher = minecraft.getBlockRendererDispatcher();
|
||||
|
||||
List<BlockState> blockstates = new LinkedList<>();
|
||||
|
||||
for (BlockPos localPos : BlockPos.getAllInBoxMutable(blockAccess.getBounds().getOrigin(),
|
||||
blockAccess.getBounds().getOrigin().add(blockAccess.getBounds().getSize()))) {
|
||||
BlockPos pos = localPos.add(instance.anchor);
|
||||
final BlockState state = blockAccess.getBlockState(pos);
|
||||
for (BlockRenderLayer blockRenderLayer : BlockRenderLayer.values()) {
|
||||
if (!state.getBlock().canRenderInLayer(state, blockRenderLayer)) {
|
||||
continue;
|
||||
}
|
||||
ForgeHooksClient.setRenderLayer(blockRenderLayer);
|
||||
final int blockRenderLayerId = blockRenderLayer.ordinal();
|
||||
final BufferBuilder bufferBuilder = bufferCache.getBuilder(blockRenderLayerId);
|
||||
if (!startedBufferBuilders[blockRenderLayerId]) {
|
||||
startedBufferBuilders[blockRenderLayerId] = true;
|
||||
// Copied from RenderChunk
|
||||
{
|
||||
bufferBuilder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
|
||||
}
|
||||
}
|
||||
// OptiFine Shaders compatibility
|
||||
// if (Config.isShaders()) SVertexBuilder.pushEntity(state, pos,
|
||||
// blockAccess, bufferBuilder);
|
||||
usedBlockRenderLayers[blockRenderLayerId] |= blockRendererDispatcher.renderBlock(state, pos,
|
||||
blockAccess, bufferBuilder, minecraft.world.rand, EmptyModelData.INSTANCE);
|
||||
blockstates.add(state);
|
||||
// if (Config.isShaders())
|
||||
// SVertexBuilder.popEntity(bufferBuilder);
|
||||
}
|
||||
ForgeHooksClient.setRenderLayer(null);
|
||||
}
|
||||
|
||||
// finishDrawing
|
||||
for (int blockRenderLayerId = 0; blockRenderLayerId < usedBlockRenderLayers.length; blockRenderLayerId++) {
|
||||
if (!startedBufferBuilders[blockRenderLayerId]) {
|
||||
continue;
|
||||
}
|
||||
bufferCache.getBuilder(blockRenderLayerId).finishDrawing();
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onRenderWorldLastEvent(final RenderWorldLastEvent event) {
|
||||
if (instance != null && instance.active) {
|
||||
final Entity entity = Minecraft.getInstance().getRenderViewEntity();
|
||||
|
||||
if (entity == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ActiveRenderInfo renderInfo = Minecraft.getInstance().gameRenderer.getActiveRenderInfo();
|
||||
Vec3d view = renderInfo.getProjectedView();
|
||||
double renderPosX = view.x;
|
||||
double renderPosY = view.y;
|
||||
double renderPosZ = view.z;
|
||||
|
||||
GlStateManager.enableAlphaTest();
|
||||
GlStateManager.enableBlend();
|
||||
Minecraft.getInstance().getTextureManager().bindTexture(AtlasTexture.LOCATION_BLOCKS_TEXTURE);
|
||||
|
||||
for (int blockRenderLayerId = 0; blockRenderLayerId < usedBlockRenderLayers.length; blockRenderLayerId++) {
|
||||
if (!usedBlockRenderLayers[blockRenderLayerId]) {
|
||||
continue;
|
||||
}
|
||||
final BufferBuilder bufferBuilder = bufferCache.getBuilder(blockRenderLayerId);
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translated(-renderPosX, -renderPosY, -renderPosZ);
|
||||
drawBuffer(bufferBuilder);
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
GlStateManager.disableAlphaTest();
|
||||
GlStateManager.disableBlend();
|
||||
}
|
||||
}
|
||||
|
||||
// Coppied from the Tesselator's vboUploader - Draw everything but don't
|
||||
// reset the buffer
|
||||
private static void drawBuffer(final BufferBuilder bufferBuilder) {
|
||||
if (bufferBuilder.getVertexCount() > 0) {
|
||||
|
||||
VertexFormat vertexformat = bufferBuilder.getVertexFormat();
|
||||
int size = vertexformat.getSize();
|
||||
ByteBuffer bytebuffer = bufferBuilder.getByteBuffer();
|
||||
List<VertexFormatElement> list = vertexformat.getElements();
|
||||
|
||||
for (int index = 0; index < list.size(); ++index) {
|
||||
VertexFormatElement vertexformatelement = list.get(index);
|
||||
Usage usage = vertexformatelement.getUsage();
|
||||
bytebuffer.position(vertexformat.getOffset(index));
|
||||
usage.preDraw(vertexformat, index, size, bytebuffer);
|
||||
}
|
||||
|
||||
GlStateManager.drawArrays(bufferBuilder.getDrawMode(), 0, bufferBuilder.getVertexCount());
|
||||
|
||||
for (int index = 0; index < list.size(); ++index) {
|
||||
VertexFormatElement vertexformatelement = list.get(index);
|
||||
Usage usage = vertexformatelement.getUsage();
|
||||
usage.postDraw(vertexformat, index, size, bytebuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
282
src/main/java/com/simibubi/create/schematic/SchematicWorld.java
Normal file
282
src/main/java/com/simibubi/create/schematic/SchematicWorld.java
Normal file
|
@ -0,0 +1,282 @@
|
|||
package com.simibubi.create.schematic;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.fluid.Fluid;
|
||||
import net.minecraft.fluid.FluidState;
|
||||
import net.minecraft.fluid.Fluids;
|
||||
import net.minecraft.fluid.IFluidState;
|
||||
import net.minecraft.particles.IParticleData;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.SoundEvent;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.DifficultyInstance;
|
||||
import net.minecraft.world.EmptyTickList;
|
||||
import net.minecraft.world.ITickList;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.LightType;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.biome.Biomes;
|
||||
import net.minecraft.world.border.WorldBorder;
|
||||
import net.minecraft.world.chunk.AbstractChunkProvider;
|
||||
import net.minecraft.world.chunk.ChunkStatus;
|
||||
import net.minecraft.world.chunk.IChunk;
|
||||
import net.minecraft.world.dimension.Dimension;
|
||||
import net.minecraft.world.gen.Heightmap.Type;
|
||||
import net.minecraft.world.storage.WorldInfo;
|
||||
|
||||
public class SchematicWorld implements IWorld {
|
||||
|
||||
private Map<BlockPos, BlockState> blocks;
|
||||
private Cuboid bounds;
|
||||
private BlockPos anchor;
|
||||
|
||||
public SchematicWorld(Map<BlockPos, BlockState> blocks, Cuboid bounds, BlockPos anchor) {
|
||||
this.blocks = blocks;
|
||||
this.setBounds(bounds);
|
||||
this.anchor = anchor;
|
||||
updateBlockstates();
|
||||
}
|
||||
|
||||
private void updateBlockstates() {
|
||||
Set<BlockPos> keySet = new HashSet<>(blocks.keySet());
|
||||
keySet.forEach(pos -> {
|
||||
BlockState blockState = blocks.get(pos);
|
||||
if (blockState == null)
|
||||
return;
|
||||
blockState.updateNeighbors(this, pos.add(anchor), 16);
|
||||
});
|
||||
}
|
||||
|
||||
public Set<BlockPos> getAllPositions() {
|
||||
return blocks.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileEntity getTileEntity(BlockPos pos) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getBlockState(BlockPos globalPos) {
|
||||
BlockPos pos = globalPos.subtract(anchor);
|
||||
if (getBounds().contains(pos) && blocks.containsKey(pos)) {
|
||||
return blocks.get(pos);
|
||||
} else {
|
||||
return Blocks.AIR.getDefaultState();
|
||||
}
|
||||
}
|
||||
|
||||
public Map<BlockPos, BlockState> getBlockMap() {
|
||||
return blocks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFluidState getFluidState(BlockPos pos) {
|
||||
return new FluidState(Fluids.EMPTY, ImmutableMap.of());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getBiome(BlockPos pos) {
|
||||
return Biomes.THE_VOID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLightFor(LightType type, BlockPos pos) {
|
||||
return 10;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Entity> getEntitiesInAABBexcluding(Entity arg0, AxisAlignedBB arg1, Predicate<? super Entity> arg2) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Entity> List<T> getEntitiesWithinAABB(Class<? extends T> arg0, AxisAlignedBB arg1,
|
||||
Predicate<? super T> arg2) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends PlayerEntity> getPlayers() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLightSubtracted(BlockPos pos, int amount) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IChunk getChunk(int x, int z, ChunkStatus requiredStatus, boolean nonnull) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos getHeight(Type heightmapType, BlockPos pos) {
|
||||
return BlockPos.ZERO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight(Type heightmapType, int x, int z) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSkylightSubtracted() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorldBorder getWorldBorder() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRemote() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSeaLevel() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getDimension() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasBlockState(BlockPos pos, Predicate<BlockState> predicate) {
|
||||
return predicate.test(getBlockState(pos));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean destroyBlock(BlockPos arg0, boolean arg1) {
|
||||
return setBlockState(arg0, Blocks.AIR.getDefaultState(), 3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeBlock(BlockPos arg0, boolean arg1) {
|
||||
return setBlockState(arg0, Blocks.AIR.getDefaultState(), 3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBlockState(BlockPos pos, BlockState arg1, int arg2) {
|
||||
pos = pos.subtract(anchor);
|
||||
if (pos.getX() < bounds.x) {
|
||||
bounds.width += bounds.x - pos.getX();
|
||||
bounds.x = pos.getX();
|
||||
}
|
||||
if (pos.getY() < bounds.y) {
|
||||
bounds.height += bounds.y - pos.getY();
|
||||
bounds.y = pos.getY();
|
||||
}
|
||||
if (pos.getZ() < bounds.z) {
|
||||
bounds.length += bounds.z - pos.getZ();
|
||||
bounds.z = pos.getZ();
|
||||
}
|
||||
BlockPos boundsMax = bounds.getOrigin().add(bounds.getSize());
|
||||
if (boundsMax.getX() <= pos.getX()) {
|
||||
bounds.width += pos.getX() - boundsMax.getX() + 1;
|
||||
}
|
||||
if (boundsMax.getY() <= pos.getY()) {
|
||||
bounds.height += pos.getY() - boundsMax.getY() + 1;
|
||||
}
|
||||
if (boundsMax.getZ() <= pos.getZ()) {
|
||||
bounds.length += pos.getZ() - boundsMax.getZ() + 1;
|
||||
}
|
||||
|
||||
blocks.put(pos, arg1);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSeed() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITickList<Block> getPendingBlockTicks() {
|
||||
return EmptyTickList.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITickList<Fluid> getPendingFluidTicks() {
|
||||
return EmptyTickList.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public World getWorld() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorldInfo getWorldInfo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DifficultyInstance getDifficultyForLocation(BlockPos pos) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractChunkProvider getChunkProvider() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Random getRandom() {
|
||||
return new Random();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyNeighbors(BlockPos pos, Block blockIn) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos getSpawnPoint() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playSound(PlayerEntity player, BlockPos pos, SoundEvent soundIn, SoundCategory category, float volume,
|
||||
float pitch) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addParticle(IParticleData particleData, double x, double y, double z, double xSpeed, double ySpeed,
|
||||
double zSpeed) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playEvent(PlayerEntity player, int type, BlockPos pos, int data) {
|
||||
}
|
||||
|
||||
public Cuboid getBounds() {
|
||||
return bounds;
|
||||
}
|
||||
|
||||
public void setBounds(Cuboid bounds) {
|
||||
this.bounds = bounds;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue