Added Blueprints

- Blueprints are item references to schematic files on the server
- Added a block to upload schematics from the client
This commit is contained in:
simibubi 2019-07-11 19:55:11 +02:00
parent ddc846d860
commit 550b477d8d
28 changed files with 1151 additions and 15 deletions

View file

@ -1,6 +1,8 @@
package com.simibubi.create;
import com.simibubi.create.block.IJustForRendering;
import com.simibubi.create.block.SchematicTableBlock;
import com.simibubi.create.block.SchematicannonBlock;
import com.simibubi.create.block.symmetry.BlockSymmetryCrossPlane;
import com.simibubi.create.block.symmetry.BlockSymmetryPlane;
import com.simibubi.create.block.symmetry.BlockSymmetryTriplePlane;
@ -13,6 +15,9 @@ import net.minecraftforge.registries.IForgeRegistry;
public enum AllBlocks {
SCHEMATICANNON(new SchematicannonBlock()),
SCHEMATIC_TABLE(new SchematicTableBlock()),
SYMMETRY_PLANE(new BlockSymmetryPlane()),
SYMMETRY_CROSSPLANE(new BlockSymmetryCrossPlane()),
SYMMETRY_TRIPLEPLANE(new BlockSymmetryTriplePlane());

View file

@ -0,0 +1,41 @@
package com.simibubi.create;
import com.simibubi.create.block.SchematicTableContainer;
import com.simibubi.create.gui.SchematicTableScreen;
import net.minecraft.client.gui.ScreenManager;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.ContainerType;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
@EventBusSubscriber(bus = Bus.MOD)
public enum AllContainers {
SchematicTable();
public ContainerType<? extends Container> type;
private AllContainers() {
}
@SubscribeEvent
public static void onContainerTypeRegistry(final RegistryEvent.Register<ContainerType<?>> e) {
SchematicTable.type = new ContainerType<>(SchematicTableContainer::new)
.setRegistryName(SchematicTable.name().toLowerCase());
e.getRegistry().register(SchematicTable.type);
}
@SuppressWarnings("unchecked")
@OnlyIn(Dist.CLIENT)
public static void registerScreenFactories() {
ScreenManager.<SchematicTableContainer, SchematicTableScreen>registerFactory(
(ContainerType<SchematicTableContainer>) SchematicTable.type, SchematicTableScreen::new);
}
}

View file

@ -9,7 +9,9 @@ import net.minecraftforge.registries.IForgeRegistry;
public enum AllItems {
SYMMETRY_WAND(new ItemWandSymmetry(standardProperties()));
SYMMETRY_WAND(new ItemWandSymmetry(standardProperties())),
EMPTY_BLUEPRINT(new Item(standardProperties().maxStackSize(1))),
BLUEPRINT(new Item(standardProperties().maxStackSize(1)));
public Item item;

View file

@ -0,0 +1,49 @@
package com.simibubi.create;
import java.util.function.Supplier;
import com.simibubi.create.block.SchematicTableTileEntity;
import com.simibubi.create.block.SchematicannonTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
@Mod.EventBusSubscriber(bus = Bus.MOD)
public enum AllTileEntities {
Schematicannon(SchematicannonTileEntity::new, AllBlocks.SCHEMATICANNON),
SchematicTable(SchematicTableTileEntity::new, AllBlocks.SCHEMATIC_TABLE);
private Supplier<? extends TileEntity> supplier;
public TileEntityType<?> type;
private AllBlocks block;
private AllTileEntities(Supplier<? extends TileEntity> supplier, AllBlocks block) {
this.supplier = supplier;
this.block = block;
}
@SubscribeEvent
public static void onTileEntityRegistry(final RegistryEvent.Register<TileEntityType<?>> event) {
for (AllTileEntities tileEntity : values()) {
ResourceLocation resourceLocation = new ResourceLocation(Create.ID, tileEntity.name().toLowerCase());
tileEntity.type = TileEntityType.Builder.create(tileEntity.supplier, tileEntity.block.get()).build(null)
.setRegistryName(resourceLocation);
event.getRegistry().register(tileEntity.type);
}
}
public static void registerRenderers() {
}
// private static <T extends TileEntity> void bind(Class<T> clazz, TileEntityRenderer<? super T> renderer) {
// ClientRegistry.bindTileEntitySpecialRenderer(clazz, renderer);
// }
}

View file

@ -0,0 +1,148 @@
package com.simibubi.create;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import com.simibubi.create.networking.PacketSchematicUpload;
import com.simibubi.create.networking.Packets;
import com.simibubi.create.utility.FilesHelper;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
@OnlyIn(Dist.CLIENT)
public class ClientSchematicLoader {
public static final int PACKET_DELAY = 10;
public static final int PACKET_SIZE = 500;
private List<String> availableSchematics;
private Map<String, InputStream> activeUploads;
private Map<String, ReadProgress> progress;
private int packetCycle;
public ClientSchematicLoader() {
availableSchematics = new ArrayList<>();
activeUploads = new HashMap<>();
progress = new HashMap<>();
refresh();
}
public void tick() {
if (activeUploads.isEmpty())
return;
if (packetCycle-- > 0)
return;
packetCycle = PACKET_DELAY;
for (String schematic : new HashSet<>(activeUploads.keySet())) {
continueUpload(schematic);
}
}
public float getProgress(String schematic) {
if (progress.containsKey(schematic)) {
return progress.get(schematic).getProgress();
}
return 0;
}
public void startNewUpload(String schematic) {
Path path = Paths.get("schematics", schematic);
if (!Files.exists(path)) {
Create.logger.fatal("Missing Schematic file: " + path.toString());
return;
}
InputStream in;
try {
in = Files.newInputStream(path, StandardOpenOption.READ);
activeUploads.put(schematic, in);
ReadProgress tracker = new ReadProgress();
tracker.length = Files.size(path);
progress.put(schematic, tracker);
Packets.channel.sendToServer(PacketSchematicUpload.begin(schematic));
} catch (IOException e) {
e.printStackTrace();
}
}
private void continueUpload(String schematic) {
if (activeUploads.containsKey(schematic)) {
byte[] data = new byte[PACKET_SIZE];
try {
int status = activeUploads.get(schematic).read(data);
progress.get(schematic).progress += status;
if (status < PACKET_SIZE) {
data = Arrays.copyOf(data, status);
}
Packets.channel.sendToServer(PacketSchematicUpload.write(schematic, data));
if (status < PACKET_SIZE)
finishUpload(schematic);
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void finishUpload(String schematic) {
if (activeUploads.containsKey(schematic)) {
Packets.channel.sendToServer(PacketSchematicUpload.finish(schematic));
activeUploads.remove(schematic);
}
}
public void refresh() {
FilesHelper.createFolderIfMissing("schematics");
availableSchematics.clear();
try {
Files.list(Paths.get("schematics/"))
.forEach(path -> {
if (Files.isDirectory(path))
return;
availableSchematics.add(path.getFileName().toString());
});
} catch (NoSuchFileException e) {
// No Schematics created yet
} catch (IOException e) {
e.printStackTrace();
}
}
public List<String> getAvailableSchematics() {
return availableSchematics;
}
public Path getPath(String name) {
return Paths.get("schematics", name + ".nbt");
}
public static class ReadProgress {
public long length;
public long progress;
public float getProgress() {
return (float) (progress * 1d / length);
}
}
}

View file

@ -1,5 +1,6 @@
package com.simibubi.create;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.simibubi.create.networking.Packets;
@ -7,12 +8,16 @@ import com.simibubi.create.networking.Packets;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
@ -25,9 +30,14 @@ public class Create {
public static final String NAME = "Create";
public static final String VERSION = "0.0.1";
public static Logger logger;
public static Logger logger = LogManager.getLogger();
public static ItemGroup creativeTab = new CreateItemGroup();
@OnlyIn(Dist.CLIENT)
public static ClientSchematicLoader cSchematicLoader;
public static ServerSchematicLoader sSchematicLoader;
public Create() {
IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
@ -37,12 +47,21 @@ public class Create {
private void clientInit(FMLClientSetupEvent event) {
AllItems.initColorHandlers();
AllTileEntities.registerRenderers();
cSchematicLoader = new ClientSchematicLoader();
sSchematicLoader = new ServerSchematicLoader();
// ScrollFixer.init();
}
private void init(final FMLCommonSetupEvent event) {
Packets.registerPackets();
DistExecutor.runWhenOn(Dist.CLIENT, () -> AllContainers::registerScreenFactories);
}
@OnlyIn(Dist.CLIENT)
@SubscribeEvent
public static void onClientTick(ClientTickEvent event) {
cSchematicLoader.tick();
}
@EventBusSubscriber(bus = Bus.MOD)

View file

@ -0,0 +1,102 @@
package com.simibubi.create;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.HashMap;
import java.util.Map;
import com.simibubi.create.block.SchematicTableContainer;
import com.simibubi.create.block.SchematicTableTileEntity;
import com.simibubi.create.networking.PacketSchematicUpload.DimensionPos;
import com.simibubi.create.utility.FilesHelper;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TextFormatting;
public class ServerSchematicLoader {
private static final String PATH = "schematics/uploaded";
private Map<String, OutputStream> activeDownloads;
private Map<String, DimensionPos> activeTables;
public ServerSchematicLoader() {
activeDownloads = new HashMap<>();
activeTables = new HashMap<>();
FilesHelper.createFolderIfMissing("schematics");
FilesHelper.createFolderIfMissing(PATH);
}
public void handleNewUpload(ServerPlayerEntity player, String schematic, DimensionPos dimensionPos) {
String playerPath = PATH + "/" + player.getName().getFormattedText();
String playerSchematicId = player.getName().getFormattedText() + "/" + schematic;
FilesHelper.createFolderIfMissing(playerPath);
try {
Files.deleteIfExists(Paths.get(PATH, playerSchematicId));
OutputStream writer = Files.newOutputStream(Paths.get(PATH, playerSchematicId),
StandardOpenOption.CREATE_NEW);
Create.logger.info("Receiving New Schematic: " + playerSchematicId);
activeDownloads.put(playerSchematicId, writer);
activeTables.put(playerSchematicId, dimensionPos);
} catch (IOException e) {
e.printStackTrace();
}
}
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();
}
}
}
public void handleFinishedUpload(ServerPlayerEntity player, String schematic) {
String playerSchematicId = player.getName().getFormattedText() + "/" + schematic;
if (activeDownloads.containsKey(playerSchematicId)) {
try {
activeDownloads.get(playerSchematicId).close();
Create.logger.info("Finished receiving Schematic: " + playerSchematicId);
DimensionPos dimpos = activeTables.remove(playerSchematicId);
BlockState blockState = dimpos.world.getBlockState(dimpos.pos);
if (!AllBlocks.SCHEMATIC_TABLE.typeOf(blockState))
return;
SchematicTableTileEntity tileEntity = (SchematicTableTileEntity) dimpos.world.getTileEntity(dimpos.pos);
if (tileEntity.inputStack.isEmpty())
return;
if (!tileEntity.outputStack.isEmpty())
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();
dimpos.world.notifyBlockUpdate(dimpos.pos, blockState, blockState, 3);
if (player.openContainer instanceof SchematicTableContainer) {
((SchematicTableContainer) player.openContainer).updateContent();
player.openContainer.detectAndSendChanges();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

View file

@ -0,0 +1,66 @@
package com.simibubi.create.block;
import net.minecraft.block.BlockRenderType;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.ContainerBlock;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.InventoryHelper;
import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
public class SchematicTableBlock extends ContainerBlock {
public SchematicTableBlock() {
super(Properties.from(Blocks.OAK_PLANKS));
}
@Override
public BlockRenderType getRenderType(BlockState state) {
return BlockRenderType.MODEL;
}
@Override
public boolean hasTileEntity() {
return true;
}
@Override
public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
BlockRayTraceResult hit) {
if (worldIn.isRemote) {
return true;
} else {
INamedContainerProvider inamedcontainerprovider = this.getContainer(state, worldIn, pos);
if (inamedcontainerprovider != null) {
player.openContainer(inamedcontainerprovider);
}
return true;
}
}
@Override
public TileEntity createNewTileEntity(IBlockReader worldIn) {
return new SchematicTableTileEntity();
}
@Override
public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
if (worldIn.getTileEntity(pos) == null)
return;
SchematicTableTileEntity te = (SchematicTableTileEntity) worldIn.getTileEntity(pos);
if (!te.inputStack.isEmpty())
InventoryHelper.spawnItemStack(worldIn, pos.getX(), pos.getY(), pos.getZ(), te.inputStack);
if (!te.outputStack.isEmpty())
InventoryHelper.spawnItemStack(worldIn, pos.getX(), pos.getY(), pos.getZ(), te.outputStack);
}
}

View file

@ -0,0 +1,124 @@
package com.simibubi.create.block;
import com.simibubi.create.AllContainers;
import com.simibubi.create.AllItems;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
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;
public class SchematicTableContainer extends Container {
private final IInventory tableInventory = new Inventory(2) {
public void markDirty() {
super.markDirty();
onCraftMatrixChanged(this);
}
};
private SchematicTableTileEntity te;
private Slot inputSlot;
private Slot outputSlot;
public SchematicTableContainer(int id, PlayerInventory inv) {
this(id, inv, null);
}
public SchematicTableContainer(int id, PlayerInventory inv, SchematicTableTileEntity te) {
super(AllContainers.SchematicTable.type, id);
this.te = te;
inputSlot = new Slot(tableInventory, 0, 31, 15) {
@Override
public boolean isItemValid(ItemStack stack) {
return AllItems.EMPTY_BLUEPRINT.typeOf(stack);
}
};
outputSlot = new Slot(tableInventory, 1, 115, 15) {
@Override
public boolean isItemValid(ItemStack stack) {
return false;
}
};
addSlot(inputSlot);
addSlot(outputSlot);
updateContent();
// player Slots
tableInventory.openInventory(inv.player);
for (int l = 0; l < 3; ++l) {
for (int j1 = 0; j1 < 9; ++j1) {
this.addSlot(new Slot(inv, j1 + l * 9 + 9, -8 + j1 * 18, 77 + l * 18));
}
}
for (int i1 = 0; i1 < 9; ++i1) {
this.addSlot(new Slot(inv, i1, -8 + i1 * 18, 135));
}
}
public boolean canWrite() {
return inputSlot.getHasStack() && !outputSlot.getHasStack();
}
@Override
public boolean canInteractWith(PlayerEntity playerIn) {
return true;
}
@Override
public ItemStack transferStackInSlot(PlayerEntity playerIn, int index) {
Slot clickedSlot = getSlot(index);
if (!clickedSlot.getHasStack())
return ItemStack.EMPTY;
ItemStack stack = clickedSlot.getStack();
if (clickedSlot == inputSlot || clickedSlot == outputSlot) {
int indexToPut = playerIn.inventory.getFirstEmptyStack();
if (indexToPut == -1)
return ItemStack.EMPTY;
playerIn.inventory.setInventorySlotContents(indexToPut, stack);
clickedSlot.putStack(ItemStack.EMPTY);
return ItemStack.EMPTY;
}
if (AllItems.EMPTY_BLUEPRINT.typeOf(stack) && !inputSlot.getHasStack()) {
clickedSlot.putStack(ItemStack.EMPTY);
inputSlot.putStack(stack);
}
return ItemStack.EMPTY;
}
public void updateContent() {
if (te != null) {
inputSlot.putStack(te.inputStack);
outputSlot.putStack(te.outputStack);
}
}
@Override
public void onContainerClosed(PlayerEntity playerIn) {
if (te != null) {
te.inputStack = inputSlot.getStack();
te.outputStack = outputSlot.getStack();
te.markDirty();
}
super.onContainerClosed(playerIn);
}
public SchematicTableTileEntity getTileEntity() {
return te;
}
}

View file

@ -0,0 +1,73 @@
package com.simibubi.create.block;
import com.simibubi.create.AllTileEntities;
import com.simibubi.create.utility.TileEntitySynced;
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.INamedContainerProvider;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.tileentity.TileEntityType;
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 ItemStack inputStack;
public ItemStack outputStack;
public SchematicTableTileEntity() {
this(AllTileEntities.SchematicTable.type);
}
public SchematicTableTileEntity(TileEntityType<?> tileEntityTypeIn) {
super(tileEntityTypeIn);
inputStack = ItemStack.EMPTY;
outputStack = ItemStack.EMPTY;
}
@Override
public void read(CompoundNBT compound) {
NonNullList<ItemStack> stacks = NonNullList.create();
ItemStackHelper.loadAllItems(compound, stacks);
if (!stacks.isEmpty()) {
inputStack = stacks.get(0);
outputStack = stacks.get(1);
}
super.read(compound);
}
@Override
public CompoundNBT write(CompoundNBT compound) {
NonNullList<ItemStack> stacks = NonNullList.create();
stacks.add(inputStack);
stacks.add(outputStack);
ItemStackHelper.saveAllItems(compound, stacks);
return super.write(compound);
}
@Override
public void tick() {
}
@Override
public Container createMenu(int p_createMenu_1_, PlayerInventory p_createMenu_2_, PlayerEntity p_createMenu_3_) {
return new SchematicTableContainer(p_createMenu_1_, p_createMenu_2_, this);
}
@Override
public ITextComponent getDisplayName() {
return new StringTextComponent(getType().getRegistryName().toString());
}
}

View file

@ -0,0 +1,45 @@
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.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
public class SchematicannonBlock extends Block {
public SchematicannonBlock() {
super(Properties.from(Blocks.DISPENSER));
}
@Override
public boolean hasTileEntity(BlockState state) {
return true;
}
@Override
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
return new SchematicannonTileEntity();
}
@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;
}
}

View file

@ -0,0 +1,48 @@
package com.simibubi.create.block;
import com.simibubi.create.AllTileEntities;
import com.simibubi.create.utility.TileEntitySynced;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.tileentity.TileEntityType;
public class SchematicannonTileEntity extends TileEntitySynced implements ITickableTileEntity {
private int test = 0;
public SchematicannonTileEntity() {
super(AllTileEntities.Schematicannon.type);
}
public SchematicannonTileEntity(TileEntityType<?> tileEntityTypeIn) {
super(tileEntityTypeIn);
}
@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++;
}
}

View file

@ -0,0 +1,5 @@
package com.simibubi.create.gui;
public class GuiHandler {
}

View file

@ -10,11 +10,9 @@ public enum GuiResources {
// Inventories
PLAYER_INVENTORY("player_inventory.png", 176, 108),
COMPOSER("composer.png", 256, 58),
PALETTES("palette_picker.png", 256, 236),
EXPORTER("design_exporter.png", 200, 111),
THEME_EDITOR("theme_editor.png", 200, 187),
WAND_SYMMETRY("wand_symmetry.png", 207, 58),
SCHEMATIC_TABLE("schematic_table.png", 207, 89),
SCHEMATIC_TABLE_PROGRESS("schematic_table.png", 209, 0, 24, 17),
// Widgets
PALETTE_BUTTON("palette_picker.png", 0, 236, 20, 20),
@ -29,11 +27,6 @@ public enum GuiResources {
INDICATOR_RED("widgets.png", 36, 23, 18, 5),
GRAY("background.png", 0, 0, 16, 16),
SCROLLBAR_AXIS("widgets.png", 224, 0, 32, 256),
SCROLLBAR_CAP("widgets.png", 0, 87, 40, 6),
SCROLLBAR_INDICATOR("widgets.png", 0, 75, 40, 12),
SCROLLBAR_BACKGROUND("widgets.png", 0, 93, 40, 16),
// Icons
ICON_NONE("icons.png", 16, 16, 16, 16),
ICON_ADD("icons.png", 16, 16),

View file

@ -0,0 +1,147 @@
package com.simibubi.create.gui;
import java.util.List;
import com.mojang.blaze3d.platform.GlStateManager;
import com.simibubi.create.Create;
import com.simibubi.create.block.SchematicTableContainer;
import com.simibubi.create.gui.widgets.AbstractSimiWidget;
import com.simibubi.create.gui.widgets.DynamicLabel;
import com.simibubi.create.gui.widgets.OptionScrollArea;
import com.simibubi.create.gui.widgets.ScrollArea;
import com.simibubi.create.gui.widgets.SimiButton;
import net.minecraft.client.gui.IHasContainer;
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
import net.minecraft.client.gui.widget.Widget;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.text.ITextComponent;
public class SchematicTableScreen extends ContainerScreen<SchematicTableContainer>
implements IHasContainer<SchematicTableContainer> {
private ScrollArea schematics;
private SimiButton button;
private DynamicLabel label;
private boolean isUploading;
private String uploadingSchematic;
private float progress;
private float lastProgress;
private int xTopLeft;
private int yTopLeft;
private int xMainWindow;
private int yMainWindow;
public SchematicTableScreen(SchematicTableContainer container, PlayerInventory playerInventory,
ITextComponent title) {
super(container, playerInventory, title);
}
@Override
protected void init() {
super.init();
xTopLeft = (width - GuiResources.SCHEMATIC_TABLE.width) / 2;
yTopLeft = (height - GuiResources.SCHEMATIC_TABLE.height) / 2;
xMainWindow = xTopLeft;
yMainWindow = yTopLeft - 80;
buttons.clear();
Create.cSchematicLoader.refresh();
List<String> availableSchematics = Create.cSchematicLoader.getAvailableSchematics();
if (!availableSchematics.isEmpty()) {
label = new DynamicLabel(xMainWindow + 36, yMainWindow + 26, "").withShadow();
schematics = new OptionScrollArea(xMainWindow + 33, yMainWindow + 23, 134, 14)
.forOptions(availableSchematics).titled("Available Schematics").writingTo(label);
buttons.add(schematics);
buttons.add(label);
} else {
}
button = new SimiButton(xMainWindow + 69, yMainWindow + 55, GuiResources.ICON_CONFIRM);
buttons.add(button);
}
@Override
protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) {
int x = xTopLeft;
int y = yTopLeft;
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);
font.drawString("Inventory", x + 7, y + 26, 0x666666);
if (schematics == null) {
font.drawStringWithShadow(" No Schematics Saved ", xMainWindow + 39, yMainWindow + 26, 0xFFDD44);
}
}
@Override
public void render(int mouseX, int mouseY, float pt) {
renderBackground();
super.render(mouseX, mouseY, pt);
minecraft.getTextureManager().bindTexture(GuiResources.SCHEMATIC_TABLE_PROGRESS.location);
int width = (int) (GuiResources.SCHEMATIC_TABLE_PROGRESS.width * MathHelper.lerp(pt, lastProgress, progress));
int height = GuiResources.SCHEMATIC_TABLE_PROGRESS.height;
GlStateManager.disableLighting();
blit(xMainWindow + 94, yMainWindow + 56, GuiResources.SCHEMATIC_TABLE_PROGRESS.startX, GuiResources.SCHEMATIC_TABLE_PROGRESS.startY, width, height);
renderHoveredToolTip(mouseX, mouseY);
for (Widget w : buttons) {
if (w instanceof AbstractSimiWidget && w.isHovered()) {
List<String> toolTip = ((AbstractSimiWidget) w).getToolTip();
renderTooltip(toolTip, mouseX, mouseY);
}
}
}
@Override
public boolean isPauseScreen() {
return false;
}
@Override
public void tick() {
super.tick();
if (isUploading) {
lastProgress = progress;
progress = Create.cSchematicLoader.getProgress(uploadingSchematic);
}
}
@Override
public boolean mouseClicked(double p_mouseClicked_1_, double p_mouseClicked_3_, int p_mouseClicked_5_) {
if (button.isHovered() && ((SchematicTableContainer) container).canWrite() && schematics != null) {
button.active = false;
schematics.active = false;
label.colored(0xCCDDFF);
List<String> availableSchematics = Create.cSchematicLoader.getAvailableSchematics();
lastProgress = progress = 0;
uploadingSchematic = availableSchematics.get(schematics.getState());
isUploading = true;
Create.cSchematicLoader.startNewUpload(uploadingSchematic);
}
return super.mouseClicked(p_mouseClicked_1_, p_mouseClicked_3_, p_mouseClicked_5_);
}
@Override
public boolean mouseScrolled(double p_mouseScrolled_1_, double p_mouseScrolled_3_, double p_mouseScrolled_5_) {
boolean b = false;
for (Widget w : buttons) {
if (w.mouseScrolled(p_mouseScrolled_1_, p_mouseScrolled_3_, p_mouseScrolled_5_))
b = true;
}
return b || super.mouseScrolled(p_mouseScrolled_1_, p_mouseScrolled_3_, p_mouseScrolled_5_);
}
}

View file

@ -24,7 +24,7 @@ public class SimiButton extends AbstractSimiWidget {
this.isHovered = mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.width && mouseY < this.y + this.height;
GuiResources button =
(pressed) ? button = GuiResources.BUTTON_DOWN :
(pressed || !active) ? button = GuiResources.BUTTON_DOWN :
(isHovered) ? GuiResources.BUTTON_HOVER :
GuiResources.BUTTON;

View file

@ -0,0 +1,86 @@
package com.simibubi.create.networking;
import java.util.function.Supplier;
import com.simibubi.create.Create;
import com.simibubi.create.block.SchematicTableContainer;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.ServerWorld;
import net.minecraftforge.fml.network.NetworkEvent.Context;
public class PacketSchematicUpload {
public static final int BEGIN = 0;
public static final int WRITE = 1;
public static final int FINISH = 2;
private int code;
private String schematic;
private byte[] data;
public PacketSchematicUpload(int code, String schematic) {
this.code = code;
this.schematic = schematic;
}
public static PacketSchematicUpload begin(String schematic) {
PacketSchematicUpload pkt = new PacketSchematicUpload(BEGIN, schematic);
return pkt;
}
public static PacketSchematicUpload write(String schematic, byte[] data) {
PacketSchematicUpload pkt = new PacketSchematicUpload(WRITE, schematic);
pkt.data = data;
return pkt;
}
public static PacketSchematicUpload finish(String schematic) {
return new PacketSchematicUpload(FINISH, schematic);
}
public PacketSchematicUpload(PacketBuffer buffer) {
code = buffer.readInt();
schematic = buffer.readString();
if (code == WRITE)
data = buffer.readByteArray();
}
public void toBytes(PacketBuffer buffer) {
buffer.writeInt(code);
buffer.writeString(schematic);
if (code == WRITE)
buffer.writeByteArray(data);
}
public void handle(Supplier<Context> context) {
context.get().enqueueWork(() -> {
ServerPlayerEntity player = context.get().getSender();
if (code == BEGIN) {
BlockPos pos = ((SchematicTableContainer) player.openContainer).getTileEntity().getPos();
Create.sSchematicLoader.handleNewUpload(player, schematic, new DimensionPos(player, pos));
}
if (code == WRITE) {
Create.sSchematicLoader.handleWriteRequest(player, schematic, data);
}
if (code == FINISH) {
Create.sSchematicLoader.handleFinishedUpload(player, schematic);
}
});
}
public static class DimensionPos {
public ServerWorld world;
public BlockPos pos;
public DimensionPos(ServerPlayerEntity player, BlockPos pos) {
this.world = player.getServerWorld();
this.pos = pos;
}
}
}

View file

@ -8,14 +8,19 @@ import net.minecraftforge.fml.network.simple.SimpleChannel;
public class Packets {
public static final SimpleChannel channel = NetworkRegistry.newSimpleChannel(
new ResourceLocation(Create.ID, "simple_channel"), () -> "1", v -> v.equals("1"), v -> v.equals("1"));
private static final String PROTOCOL_VERSION = "1";
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);
}

View file

@ -0,0 +1,109 @@
package com.simibubi.create.utility;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.google.gson.internal.Streams;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.simibubi.create.Create;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.JsonToNBT;
public class FilesHelper {
public static void createFolderIfMissing(String name) {
if (!Files.isDirectory(Paths.get(name))) {
try {
Files.createDirectory(Paths.get(name));
} catch (IOException e) {
Create.logger.warn("Could not create Folder: " + name);
}
}
}
public static String findFirstValidFilename(String name, String folderPath, String extension) {
int index = 0;
String filename;
String filepath;
do {
filename = slug(name) + ((index == 0) ? "" : "_" + index) + "." + extension;
index++;
filepath = folderPath + "/" + filename;
} while (Files.exists(Paths.get(filepath)));
return filename;
}
public static String slug(String name) {
return name.toLowerCase().replace(' ', '_');
}
public static boolean saveTagCompoundAsJson(CompoundNBT compound, String path) {
try {
Files.deleteIfExists(Paths.get(path));
JsonWriter writer = new JsonWriter(Files.newBufferedWriter(Paths.get(path), StandardOpenOption.CREATE));
writer.setIndent(" ");
Streams.write(new JsonParser().parse(compound.toString()), writer);
writer.close();
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
public static boolean saveTagCompoundAsJsonCompact(CompoundNBT compound, String path) {
try {
Files.deleteIfExists(Paths.get(path));
JsonWriter writer = new JsonWriter(Files.newBufferedWriter(Paths.get(path), StandardOpenOption.CREATE));
Streams.write(new JsonParser().parse(compound.toString()), writer);
writer.close();
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
public static CompoundNBT loadJsonNBT(InputStream inputStream) {
try {
JsonReader reader = new JsonReader(new BufferedReader(new InputStreamReader(inputStream)));
reader.setLenient(true);
JsonElement element = Streams.parse(reader);
reader.close();
inputStream.close();
return JsonToNBT.getTagFromJson(element.toString());
} catch (IOException e) {
e.printStackTrace();
} catch (CommandSyntaxException e) {
e.printStackTrace();
}
return null;
}
public static CompoundNBT loadJsonResourceAsNBT(String filepath) {
return loadJsonNBT(Create.class.getClassLoader().getResourceAsStream(filepath));
}
public static CompoundNBT loadJsonAsNBT(String filepath) {
try {
return loadJsonNBT(Files.newInputStream(Paths.get(filepath), StandardOpenOption.READ));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}

View file

@ -0,0 +1,35 @@
package com.simibubi.create.utility;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.server.SUpdateTileEntityPacket;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityType;
public abstract class TileEntitySynced extends TileEntity {
public TileEntitySynced(TileEntityType<?> tileEntityTypeIn) {
super(tileEntityTypeIn);
}
@Override
public CompoundNBT getUpdateTag() {
return write(new CompoundNBT());
}
@Override
public void handleUpdateTag(CompoundNBT tag) {
read(tag);
}
@Override
public SUpdateTileEntityPacket getUpdatePacket(){
return new SUpdateTileEntityPacket(getPos(), 1, write(new CompoundNBT()));
}
@Override
public void onDataPacket(NetworkManager net, SUpdateTileEntityPacket pkt){
read(pkt.getNbtCompound());
}
}

View file

@ -0,0 +1,6 @@
{
"forgemarker": 1,
"variants": {
"": { "model": "block/crafting_table" }
}
}

View file

@ -0,0 +1,6 @@
{
"forgemarker": 1,
"variants": {
"": { "model": "block/dropper_vertical" }
}
}

View file

@ -1,4 +1,8 @@
{
"item.create.symmetry_wand": "Staff of Symmetry",
"item.create.empty_blueprint": "Empty Blueprint",
"item.create.blueprint": "Blueprint",
"block.create.schematicannon": "SchematiCannon 9000",
"block.create.schematic_table": "Schematic Planner",
"itemGroup.create": "Create"
}

View file

@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "create:item/blueprint_filled"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "create:item/blueprint_empty"
}
}

View file

@ -0,0 +1,3 @@
{
"parent": "block/crafting_table"
}

View file

@ -0,0 +1,3 @@
{
"parent": "block/dropper_vertical"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB