mirror of
https://github.com/Creators-of-Create/Create.git
synced 2025-01-23 11:28:10 +01:00
Blueprint Placement Tools
- New tools for modifying the blueprints location and orientation - Fixed client classes loading on physical servers
This commit is contained in:
parent
c6c9a8f8eb
commit
56139aab20
39 changed files with 1309 additions and 125 deletions
|
@ -6,6 +6,8 @@ import com.simibubi.create.item.ItemWandSymmetry;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.Item.Properties;
|
import net.minecraft.item.Item.Properties;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
import net.minecraftforge.registries.IForgeRegistry;
|
import net.minecraftforge.registries.IForgeRegistry;
|
||||||
|
|
||||||
public enum AllItems {
|
public enum AllItems {
|
||||||
|
@ -39,6 +41,7 @@ public enum AllItems {
|
||||||
return stack.getItem() == item;
|
return stack.getItem() == item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
public static void initColorHandlers() {
|
public static void initColorHandlers() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,8 @@ import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.tileentity.TileEntityType;
|
import net.minecraft.tileentity.TileEntityType;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
import net.minecraftforge.event.RegistryEvent;
|
import net.minecraftforge.event.RegistryEvent;
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.client.registry.ClientRegistry;
|
import net.minecraftforge.fml.client.registry.ClientRegistry;
|
||||||
|
@ -42,10 +44,12 @@ public enum AllTileEntities {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
public static void registerRenderers() {
|
public static void registerRenderers() {
|
||||||
bind(SchematicannonTileEntity.class, new SchematicannonRenderer());
|
bind(SchematicannonTileEntity.class, new SchematicannonRenderer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
private static <T extends TileEntity> void bind(Class<T> clazz, TileEntityRenderer<? super T> renderer) {
|
private static <T extends TileEntity> void bind(Class<T> clazz, TileEntityRenderer<? super T> renderer) {
|
||||||
ClientRegistry.bindTileEntitySpecialRenderer(clazz, renderer);
|
ClientRegistry.bindTileEntitySpecialRenderer(clazz, renderer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,13 @@ package com.simibubi.create;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import com.simibubi.create.gui.Keyboard;
|
||||||
import com.simibubi.create.networking.Packets;
|
import com.simibubi.create.networking.Packets;
|
||||||
|
import com.simibubi.create.schematic.BlueprintHandler;
|
||||||
import com.simibubi.create.schematic.SchematicHologram;
|
import com.simibubi.create.schematic.SchematicHologram;
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.client.settings.KeyBinding;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemGroup;
|
import net.minecraft.item.ItemGroup;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
@ -15,6 +18,7 @@ import net.minecraftforge.event.RegistryEvent;
|
||||||
import net.minecraftforge.eventbus.api.IEventBus;
|
import net.minecraftforge.eventbus.api.IEventBus;
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.DistExecutor;
|
import net.minecraftforge.fml.DistExecutor;
|
||||||
|
import net.minecraftforge.fml.client.registry.ClientRegistry;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
|
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
|
||||||
|
@ -37,6 +41,8 @@ public class Create {
|
||||||
|
|
||||||
@OnlyIn(Dist.CLIENT)
|
@OnlyIn(Dist.CLIENT)
|
||||||
public static ClientSchematicLoader cSchematicLoader;
|
public static ClientSchematicLoader cSchematicLoader;
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public static KeyBinding TOOL_MENU;
|
||||||
|
|
||||||
public static ServerSchematicLoader sSchematicLoader;
|
public static ServerSchematicLoader sSchematicLoader;
|
||||||
|
|
||||||
|
@ -47,17 +53,24 @@ public class Create {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clientInit(FMLClientSetupEvent event) {
|
private void clientInit(FMLClientSetupEvent event) {
|
||||||
AllItems.initColorHandlers();
|
DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> {
|
||||||
AllTileEntities.registerRenderers();
|
AllItems.initColorHandlers();
|
||||||
cSchematicLoader = new ClientSchematicLoader();
|
AllTileEntities.registerRenderers();
|
||||||
sSchematicLoader = new ServerSchematicLoader();
|
cSchematicLoader = new ClientSchematicLoader();
|
||||||
new SchematicHologram();
|
new SchematicHologram();
|
||||||
// ScrollFixer.init();
|
new BlueprintHandler();
|
||||||
|
ScrollFixer.init();
|
||||||
|
ScrollFixer.addMouseWheelListener(BlueprintHandler.instance::onScroll);
|
||||||
|
|
||||||
|
TOOL_MENU = new KeyBinding("Tool Menu (Hold)", Keyboard.LALT, NAME);
|
||||||
|
ClientRegistry.registerKeyBinding(TOOL_MENU);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void init(final FMLCommonSetupEvent event) {
|
private void init(final FMLCommonSetupEvent event) {
|
||||||
Packets.registerPackets();
|
Packets.registerPackets();
|
||||||
DistExecutor.runWhenOn(Dist.CLIENT, () -> AllContainers::registerScreenFactories);
|
DistExecutor.runWhenOn(Dist.CLIENT, () -> AllContainers::registerScreenFactories);
|
||||||
|
sSchematicLoader = new ServerSchematicLoader();
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnlyIn(Dist.CLIENT)
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
|
|
@ -10,14 +10,13 @@ import java.util.Map;
|
||||||
|
|
||||||
import com.simibubi.create.block.SchematicTableContainer;
|
import com.simibubi.create.block.SchematicTableContainer;
|
||||||
import com.simibubi.create.block.SchematicTableTileEntity;
|
import com.simibubi.create.block.SchematicTableTileEntity;
|
||||||
|
import com.simibubi.create.item.ItemBlueprint;
|
||||||
import com.simibubi.create.networking.PacketSchematicUpload.DimensionPos;
|
import com.simibubi.create.networking.PacketSchematicUpload.DimensionPos;
|
||||||
import com.simibubi.create.utility.FilesHelper;
|
import com.simibubi.create.utility.FilesHelper;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.text.StringTextComponent;
|
|
||||||
import net.minecraft.util.text.TextFormatting;
|
|
||||||
|
|
||||||
public class ServerSchematicLoader {
|
public class ServerSchematicLoader {
|
||||||
|
|
||||||
|
@ -111,13 +110,7 @@ public class ServerSchematicLoader {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tileEntity.inputStack = ItemStack.EMPTY;
|
tileEntity.inputStack = ItemStack.EMPTY;
|
||||||
ItemStack blueprint = new ItemStack(AllItems.BLUEPRINT.get());
|
tileEntity.outputStack = ItemBlueprint.create(schematic, player.getName().getFormattedText());
|
||||||
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);
|
dimpos.world.notifyBlockUpdate(dimpos.pos, blockState, blockState, 3);
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
package com.simibubi.create.block;
|
package com.simibubi.create.block;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.Blocks;
|
import net.minecraft.block.Blocks;
|
||||||
import net.minecraft.block.HorizontalBlock;
|
import net.minecraft.block.HorizontalBlock;
|
||||||
import net.minecraft.block.ITileEntityProvider;
|
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.inventory.InventoryHelper;
|
import net.minecraft.inventory.InventoryHelper;
|
||||||
import net.minecraft.inventory.container.INamedContainerProvider;
|
import net.minecraft.inventory.container.INamedContainerProvider;
|
||||||
|
@ -19,8 +16,7 @@ import net.minecraft.util.math.BlockRayTraceResult;
|
||||||
import net.minecraft.world.IBlockReader;
|
import net.minecraft.world.IBlockReader;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
public class SchematicTableBlock extends HorizontalBlock {
|
||||||
public class SchematicTableBlock extends HorizontalBlock implements ITileEntityProvider {
|
|
||||||
|
|
||||||
public SchematicTableBlock() {
|
public SchematicTableBlock() {
|
||||||
super(Properties.from(Blocks.OAK_PLANKS));
|
super(Properties.from(Blocks.OAK_PLANKS));
|
||||||
|
@ -43,17 +39,18 @@ public class SchematicTableBlock extends HorizontalBlock implements ITileEntityP
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasTileEntity() {
|
public boolean hasTileEntity(BlockState state) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
|
public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
|
||||||
BlockRayTraceResult hit) {
|
BlockRayTraceResult hit) {
|
||||||
|
|
||||||
if (worldIn.isRemote) {
|
if (worldIn.isRemote) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
INamedContainerProvider inamedcontainerprovider = this.getContainer(state, worldIn, pos);
|
INamedContainerProvider inamedcontainerprovider = (INamedContainerProvider) worldIn.getTileEntity(pos);
|
||||||
if (inamedcontainerprovider != null) {
|
if (inamedcontainerprovider != null) {
|
||||||
player.openContainer(inamedcontainerprovider);
|
player.openContainer(inamedcontainerprovider);
|
||||||
}
|
}
|
||||||
|
@ -63,7 +60,7 @@ public class SchematicTableBlock extends HorizontalBlock implements ITileEntityP
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TileEntity createNewTileEntity(IBlockReader worldIn) {
|
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
|
||||||
return new SchematicTableTileEntity();
|
return new SchematicTableTileEntity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,16 +77,4 @@ public class SchematicTableBlock extends HorizontalBlock implements ITileEntityP
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean eventReceived(BlockState state, World worldIn, BlockPos pos, int id, int param) {
|
|
||||||
super.eventReceived(state, worldIn, pos, id, param);
|
|
||||||
TileEntity tileentity = worldIn.getTileEntity(pos);
|
|
||||||
return tileentity == null ? false : tileentity.receiveClientEvent(id, param);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public INamedContainerProvider getContainer(BlockState state, World worldIn, BlockPos pos) {
|
|
||||||
TileEntity tileentity = worldIn.getTileEntity(pos);
|
|
||||||
return tileentity instanceof INamedContainerProvider ? (INamedContainerProvider) tileentity : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,14 +45,14 @@ public class SchematicTableContainer extends Container {
|
||||||
this.player = inv.player;
|
this.player = inv.player;
|
||||||
this.te = te;
|
this.te = te;
|
||||||
|
|
||||||
inputSlot = new Slot(tableInventory, 0, -9, 15) {
|
inputSlot = new Slot(tableInventory, 0, -9, 40) {
|
||||||
@Override
|
@Override
|
||||||
public boolean isItemValid(ItemStack stack) {
|
public boolean isItemValid(ItemStack stack) {
|
||||||
return AllItems.EMPTY_BLUEPRINT.typeOf(stack);
|
return AllItems.EMPTY_BLUEPRINT.typeOf(stack);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
outputSlot = new Slot(tableInventory, 1, 75, 15) {
|
outputSlot = new Slot(tableInventory, 1, 75, 40) {
|
||||||
@Override
|
@Override
|
||||||
public boolean isItemValid(ItemStack stack) {
|
public boolean isItemValid(ItemStack stack) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -72,12 +72,12 @@ public class SchematicTableContainer extends Container {
|
||||||
tableInventory.openInventory(inv.player);
|
tableInventory.openInventory(inv.player);
|
||||||
for (int l = 0; l < 3; ++l) {
|
for (int l = 0; l < 3; ++l) {
|
||||||
for (int j1 = 0; j1 < 9; ++j1) {
|
for (int j1 = 0; j1 < 9; ++j1) {
|
||||||
this.addSlot(new Slot(inv, j1 + l * 9 + 9, -8 + j1 * 18, 77 + l * 18));
|
this.addSlot(new Slot(inv, j1 + l * 9 + 9, -8 + j1 * 18, 102 + l * 18));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i1 = 0; i1 < 9; ++i1) {
|
for (int i1 = 0; i1 < 9; ++i1) {
|
||||||
this.addSlot(new Slot(inv, i1, -8 + i1 * 18, 135));
|
this.addSlot(new Slot(inv, i1, -8 + i1 * 18, 160));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,8 @@ import net.minecraft.tileentity.ITickableTileEntity;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.tileentity.TileEntityType;
|
import net.minecraft.tileentity.TileEntityType;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.SoundCategory;
|
||||||
|
import net.minecraft.util.SoundEvents;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
@ -262,19 +264,27 @@ public class SchematicannonTileEntity extends TileEntitySynced implements ITicka
|
||||||
anchor = null;
|
anchor = null;
|
||||||
reader = null;
|
reader = null;
|
||||||
missingBlock = false;
|
missingBlock = false;
|
||||||
|
target = getPos().add(1, 0, 0);
|
||||||
|
world.playSound(null, pos.getX(), pos.getY(), pos.getZ(), SoundEvents.BLOCK_NOTE_BLOCK_BELL,
|
||||||
|
SoundCategory.BLOCKS, 1, .7f);
|
||||||
|
world.notifyBlockUpdate(getPos(), getBlockState(), getBlockState(), 2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
state = reader.getBlockState(anchor.add(currentPos));
|
state = reader.getBlockState(anchor.add(currentPos));
|
||||||
} while (state.getBlock() == Blocks.AIR);
|
} while (state.getBlock() == Blocks.AIR);
|
||||||
|
|
||||||
target = anchor.add(currentPos);
|
target = anchor.add(currentPos);
|
||||||
|
missingBlock = false;
|
||||||
|
|
||||||
// Update orientation
|
// Update orientation
|
||||||
world.notifyBlockUpdate(getPos(), getBlockState(), getBlockState(), 3);
|
world.notifyBlockUpdate(getPos(), getBlockState(), getBlockState(), 2);
|
||||||
|
|
||||||
|
if (target.withinDistance(getPos(), 2f)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (creative) {
|
if (creative) {
|
||||||
launchBlock(currentPos.add(anchor), state);
|
launchBlock(currentPos.add(anchor), state);
|
||||||
missingBlock = false;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,7 +295,6 @@ public class SchematicannonTileEntity extends TileEntitySynced implements ITicka
|
||||||
|
|
||||||
// Overwrite in case its rotated
|
// Overwrite in case its rotated
|
||||||
launchBlock(target, state);
|
launchBlock(target, state);
|
||||||
missingBlock = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search for required item
|
// Search for required item
|
||||||
|
|
|
@ -8,7 +8,10 @@ import com.simibubi.create.gui.widgets.AbstractSimiWidget;
|
||||||
import net.minecraft.client.gui.screen.Screen;
|
import net.minecraft.client.gui.screen.Screen;
|
||||||
import net.minecraft.client.gui.widget.Widget;
|
import net.minecraft.client.gui.widget.Widget;
|
||||||
import net.minecraft.util.text.StringTextComponent;
|
import net.minecraft.util.text.StringTextComponent;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
public abstract class AbstractSimiScreen extends Screen {
|
public abstract class AbstractSimiScreen extends Screen {
|
||||||
|
|
||||||
protected int sWidth, sHeight;
|
protected int sWidth, sHeight;
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
package com.simibubi.create.gui;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
|
|
||||||
|
import net.minecraft.client.MainWindow;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.gui.AbstractGui;
|
||||||
|
|
||||||
|
public class BlueprintHotbarOverlay extends AbstractGui {
|
||||||
|
|
||||||
|
public void renderOn(int slot) {
|
||||||
|
MainWindow mainWindow = Minecraft.getInstance().mainWindow;
|
||||||
|
int x = mainWindow.getScaledWidth() / 2 - 92;
|
||||||
|
int y = mainWindow.getScaledHeight() - 23;
|
||||||
|
GlStateManager.enableBlend();
|
||||||
|
GlStateManager.enableAlphaTest();
|
||||||
|
GuiResources.BLUEPRINT_SLOT.draw(this, x + 20 * slot, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +0,0 @@
|
||||||
package com.simibubi.create.gui;
|
|
||||||
|
|
||||||
public class GuiHandler {
|
|
||||||
|
|
||||||
}
|
|
|
@ -2,11 +2,14 @@ package com.simibubi.create.gui;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.screen.Screen;
|
import net.minecraft.client.gui.screen.Screen;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||||
import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent;
|
import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent;
|
||||||
|
|
||||||
@EventBusSubscriber
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
@EventBusSubscriber(value = Dist.CLIENT)
|
||||||
public class GuiOpener {
|
public class GuiOpener {
|
||||||
|
|
||||||
private static Screen openedGuiNextTick;
|
private static Screen openedGuiNextTick;
|
||||||
|
|
|
@ -27,6 +27,8 @@ public enum GuiResources {
|
||||||
INDICATOR_RED("widgets.png", 36, 23, 18, 5),
|
INDICATOR_RED("widgets.png", 36, 23, 18, 5),
|
||||||
GRAY("background.png", 0, 0, 16, 16),
|
GRAY("background.png", 0, 0, 16, 16),
|
||||||
|
|
||||||
|
BLUEPRINT_SLOT("widgets.png", 90, 0, 24, 24),
|
||||||
|
|
||||||
// Icons
|
// Icons
|
||||||
ICON_NONE("icons.png", 16, 16, 16, 16),
|
ICON_NONE("icons.png", 16, 16, 16, 16),
|
||||||
ICON_ADD("icons.png", 16, 16),
|
ICON_ADD("icons.png", 16, 16),
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
package com.simibubi.create.utility;
|
package com.simibubi.create.gui;
|
||||||
|
|
||||||
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.util.InputMappings;
|
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
|
||||||
|
@ -24,7 +25,7 @@ public class Keyboard {
|
||||||
public static final int G = 71;
|
public static final int G = 71;
|
||||||
|
|
||||||
public static boolean isKeyDown(int key) {
|
public static boolean isKeyDown(int key) {
|
||||||
return InputMappings.isKeyDown(Minecraft.getInstance().mainWindow.getHandle(), key);
|
return GLFW.glfwGetKey(Minecraft.getInstance().mainWindow.getHandle(), key) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -2,8 +2,6 @@ package com.simibubi.create.gui;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL11;
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.platform.GlStateManager;
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.Create;
|
import com.simibubi.create.Create;
|
||||||
|
@ -18,15 +16,11 @@ import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.IHasContainer;
|
import net.minecraft.client.gui.IHasContainer;
|
||||||
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
|
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
|
||||||
import net.minecraft.client.gui.widget.Widget;
|
import net.minecraft.client.gui.widget.Widget;
|
||||||
import net.minecraft.client.renderer.BufferBuilder;
|
import net.minecraft.client.renderer.RenderHelper;
|
||||||
import net.minecraft.client.renderer.Tessellator;
|
|
||||||
import net.minecraft.client.renderer.texture.AtlasTexture;
|
import net.minecraft.client.renderer.texture.AtlasTexture;
|
||||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
|
||||||
import net.minecraft.entity.player.PlayerInventory;
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
import net.minecraft.util.text.ITextComponent;
|
import net.minecraft.util.text.ITextComponent;
|
||||||
import net.minecraftforge.client.model.data.EmptyModelData;
|
|
||||||
|
|
||||||
public class SchematicTableScreen extends ContainerScreen<SchematicTableContainer>
|
public class SchematicTableScreen extends ContainerScreen<SchematicTableContainer>
|
||||||
implements IHasContainer<SchematicTableContainer> {
|
implements IHasContainer<SchematicTableContainer> {
|
||||||
|
@ -53,7 +47,7 @@ public class SchematicTableScreen extends ContainerScreen<SchematicTableContaine
|
||||||
protected void init() {
|
protected void init() {
|
||||||
super.init();
|
super.init();
|
||||||
xTopLeft = (width - GuiResources.SCHEMATIC_TABLE.width) / 2;
|
xTopLeft = (width - GuiResources.SCHEMATIC_TABLE.width) / 2;
|
||||||
yTopLeft = (height - GuiResources.SCHEMATIC_TABLE.height) / 2;
|
yTopLeft = (height - GuiResources.SCHEMATIC_TABLE.height + 50) / 2;
|
||||||
xMainWindow = xTopLeft - 40;
|
xMainWindow = xTopLeft - 40;
|
||||||
yMainWindow = yTopLeft - 80;
|
yMainWindow = yTopLeft - 80;
|
||||||
buttons.clear();
|
buttons.clear();
|
||||||
|
@ -113,21 +107,17 @@ public class SchematicTableScreen extends ContainerScreen<SchematicTableContaine
|
||||||
GlStateManager.enableBlend();
|
GlStateManager.enableBlend();
|
||||||
GlStateManager.enableRescaleNormal();
|
GlStateManager.enableRescaleNormal();
|
||||||
GlStateManager.enableAlphaTest();
|
GlStateManager.enableAlphaTest();
|
||||||
|
RenderHelper.enableGUIStandardItemLighting();
|
||||||
GlStateManager.alphaFunc(516, 0.1F);
|
GlStateManager.alphaFunc(516, 0.1F);
|
||||||
GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
|
GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
|
||||||
GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F);
|
GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||||
|
|
||||||
GlStateManager.translated(xTopLeft + 220, yTopLeft + 30, 200);
|
GlStateManager.translated(xTopLeft + 220, yTopLeft + 30, 200);
|
||||||
GlStateManager.rotatef(140, -.1f, 1, -.2f);
|
GlStateManager.rotatef(50, -.5f, 1, -.2f);
|
||||||
GlStateManager.scaled(50, -50, 50);
|
GlStateManager.scaled(50, -50, 50);
|
||||||
|
|
||||||
Minecraft.getInstance().getTextureManager().bindTexture(AtlasTexture.LOCATION_BLOCKS_TEXTURE);
|
Minecraft.getInstance().getTextureManager().bindTexture(AtlasTexture.LOCATION_BLOCKS_TEXTURE);
|
||||||
BufferBuilder buffer = Tessellator.getInstance().getBuffer();
|
minecraft.getBlockRendererDispatcher().renderBlockBrightness(AllBlocks.SCHEMATIC_TABLE.get().getDefaultState(), 1);
|
||||||
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
|
|
||||||
minecraft.getBlockRendererDispatcher().renderBlock(AllBlocks.SCHEMATIC_TABLE.get().getDefaultState(),
|
|
||||||
new BlockPos(0, 0, 0), minecraft.world, buffer, minecraft.world.rand, EmptyModelData.INSTANCE);
|
|
||||||
|
|
||||||
Tessellator.getInstance().draw();
|
|
||||||
|
|
||||||
GlStateManager.disableAlphaTest();
|
GlStateManager.disableAlphaTest();
|
||||||
GlStateManager.disableRescaleNormal();
|
GlStateManager.disableRescaleNormal();
|
||||||
|
|
103
src/main/java/com/simibubi/create/gui/ToolSelectionScreen.java
Normal file
103
src/main/java/com/simibubi/create/gui/ToolSelectionScreen.java
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
package com.simibubi.create.gui;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
|
import com.simibubi.create.schematic.Tools;
|
||||||
|
|
||||||
|
import net.minecraft.client.MainWindow;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.gui.screen.Screen;
|
||||||
|
import net.minecraft.util.text.StringTextComponent;
|
||||||
|
|
||||||
|
public class ToolSelectionScreen extends Screen {
|
||||||
|
|
||||||
|
protected List<Tools> tools;
|
||||||
|
protected Consumer<Tools> callback;
|
||||||
|
public boolean focused;
|
||||||
|
private float yOffset;
|
||||||
|
protected int selection;
|
||||||
|
|
||||||
|
protected int w;
|
||||||
|
protected int h;
|
||||||
|
|
||||||
|
public ToolSelectionScreen(List<Tools> tools, Consumer<Tools> callback) {
|
||||||
|
super(new StringTextComponent("Tool Selection"));
|
||||||
|
this.minecraft = Minecraft.getInstance();
|
||||||
|
this.tools = tools;
|
||||||
|
this.callback = callback;
|
||||||
|
focused = false;
|
||||||
|
yOffset = 0;
|
||||||
|
selection = 0;
|
||||||
|
|
||||||
|
callback.accept(tools.get(selection));
|
||||||
|
|
||||||
|
w = tools.size() * 50 + 30;
|
||||||
|
h = 30;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSelectedElement(Tools tool) {
|
||||||
|
if (!tools.contains(tool))
|
||||||
|
return;
|
||||||
|
selection = tools.indexOf(tool);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cycle(int direction) {
|
||||||
|
selection += (direction < 0)? 1 : -1;
|
||||||
|
selection = (selection + tools.size()) % tools.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void draw(float partialTicks) {
|
||||||
|
MainWindow mainWindow = Minecraft.getInstance().mainWindow;
|
||||||
|
|
||||||
|
int x = (mainWindow.getScaledWidth() - w) / 2 + 15;
|
||||||
|
int y = mainWindow.getScaledHeight() - h - 75;
|
||||||
|
|
||||||
|
GlStateManager.pushMatrix();
|
||||||
|
GlStateManager.translatef(0, -yOffset, 0);
|
||||||
|
|
||||||
|
GuiResources gray = GuiResources.GRAY;
|
||||||
|
GlStateManager.enableBlend();
|
||||||
|
GlStateManager.enableAlphaTest();
|
||||||
|
GlStateManager.color4f(1, 1, 1, focused? 7 / 8f : 1 / 2f);
|
||||||
|
|
||||||
|
Minecraft.getInstance().getTextureManager().bindTexture(gray.location);
|
||||||
|
blit(x - 15, y, gray.startX, gray.startY, w, h, gray.width, gray.height);
|
||||||
|
GlStateManager.color4f(1, 1, 1, 1);
|
||||||
|
|
||||||
|
for (int i = 0; i < tools.size(); i++) {
|
||||||
|
GlStateManager.pushMatrix();
|
||||||
|
|
||||||
|
float alpha = focused? 1 : .2f;
|
||||||
|
if (i == selection) {
|
||||||
|
GlStateManager.translatef(0, -10, 0);
|
||||||
|
drawCenteredString(minecraft.fontRenderer, tools.get(i).getDisplayName(), x + i * 50 + 24, y + 28, 0xCCDDFF);
|
||||||
|
alpha = 1;
|
||||||
|
}
|
||||||
|
GlStateManager.color4f(0, 0, 0, alpha);
|
||||||
|
tools.get(i).getIcon().draw(this, x + i * 50 + 16, y + 12);
|
||||||
|
GlStateManager.color4f(1, 1, 1, alpha);
|
||||||
|
tools.get(i).getIcon().draw(this, x + i * 50 + 16, y + 11);
|
||||||
|
|
||||||
|
GlStateManager.popMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
GlStateManager.popMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update() {
|
||||||
|
if (focused) yOffset += (10 - yOffset) * .1f;
|
||||||
|
else yOffset *= .9f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void renderPassive(float partialTicks) {
|
||||||
|
draw(partialTicks);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClose() {
|
||||||
|
callback.accept(tools.get(selection));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,7 +2,7 @@ package com.simibubi.create.gui.widgets;
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import com.simibubi.create.utility.Keyboard;
|
import com.simibubi.create.gui.Keyboard;
|
||||||
|
|
||||||
import net.minecraft.util.text.TextFormatting;
|
import net.minecraft.util.text.TextFormatting;
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import java.nio.file.StandardOpenOption;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
|
import com.simibubi.create.AllItems;
|
||||||
import com.simibubi.create.block.SchematicannonTileEntity;
|
import com.simibubi.create.block.SchematicannonTileEntity;
|
||||||
import com.simibubi.create.schematic.SchematicHologram;
|
import com.simibubi.create.schematic.SchematicHologram;
|
||||||
|
|
||||||
|
@ -24,10 +25,15 @@ import net.minecraft.nbt.NBTUtil;
|
||||||
import net.minecraft.util.ActionResult;
|
import net.minecraft.util.ActionResult;
|
||||||
import net.minecraft.util.ActionResultType;
|
import net.minecraft.util.ActionResultType;
|
||||||
import net.minecraft.util.Hand;
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraft.util.Mirror;
|
||||||
|
import net.minecraft.util.Rotation;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.text.StringTextComponent;
|
import net.minecraft.util.text.StringTextComponent;
|
||||||
|
import net.minecraft.util.text.TextFormatting;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraft.world.gen.feature.template.PlacementSettings;
|
||||||
import net.minecraft.world.gen.feature.template.Template;
|
import net.minecraft.world.gen.feature.template.Template;
|
||||||
|
import net.minecraftforge.fml.common.thread.SidedThreadGroups;
|
||||||
|
|
||||||
public class ItemBlueprint extends Item {
|
public class ItemBlueprint extends Item {
|
||||||
|
|
||||||
|
@ -35,6 +41,70 @@ public class ItemBlueprint extends Item {
|
||||||
super(properties.maxStackSize(1));
|
super(properties.maxStackSize(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ItemStack create(String schematic, String owner) {
|
||||||
|
ItemStack blueprint = new ItemStack(AllItems.BLUEPRINT.item);
|
||||||
|
|
||||||
|
CompoundNBT tag = new CompoundNBT();
|
||||||
|
tag.putBoolean("Deployed", false);
|
||||||
|
tag.putString("Owner", owner);
|
||||||
|
tag.putString("File", schematic);
|
||||||
|
tag.put("Anchor", NBTUtil.writeBlockPos(BlockPos.ZERO));
|
||||||
|
tag.putString("Rotation", Rotation.NONE.name());
|
||||||
|
tag.putString("Mirror", Mirror.NONE.name());
|
||||||
|
blueprint.setTag(tag);
|
||||||
|
|
||||||
|
writeSize(blueprint);
|
||||||
|
blueprint.setDisplayName(new StringTextComponent(TextFormatting.RESET + "" + TextFormatting.WHITE
|
||||||
|
+ "Blueprint (" + TextFormatting.GOLD + schematic + TextFormatting.WHITE + ")"));
|
||||||
|
|
||||||
|
return blueprint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void writeSize(ItemStack blueprint) {
|
||||||
|
CompoundNBT tag = blueprint.getTag();
|
||||||
|
Template t = getSchematic(blueprint);
|
||||||
|
tag.put("Bounds", NBTUtil.writeBlockPos(t.getSize()));
|
||||||
|
blueprint.setTag(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PlacementSettings getSettings(ItemStack blueprint) {
|
||||||
|
CompoundNBT tag = blueprint.getTag();
|
||||||
|
|
||||||
|
PlacementSettings settings = new PlacementSettings();
|
||||||
|
settings.setRotation(Rotation.valueOf(tag.getString("Rotation")));
|
||||||
|
settings.setMirror(Mirror.valueOf(tag.getString("Mirror")));
|
||||||
|
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Template getSchematic(ItemStack blueprint) {
|
||||||
|
Template t = new Template();
|
||||||
|
String owner = blueprint.getTag().getString("Owner");
|
||||||
|
String schematic = blueprint.getTag().getString("File");
|
||||||
|
|
||||||
|
String filepath = "";
|
||||||
|
|
||||||
|
if (Thread.currentThread().getThreadGroup() == SidedThreadGroups.SERVER)
|
||||||
|
filepath = "schematics/uploaded/" + owner + "/" + schematic;
|
||||||
|
else
|
||||||
|
filepath = "schematics/" + schematic;
|
||||||
|
|
||||||
|
InputStream stream = null;
|
||||||
|
try {
|
||||||
|
stream = Files.newInputStream(Paths.get(filepath), StandardOpenOption.READ);
|
||||||
|
CompoundNBT nbt = CompressedStreamTools.readCompressed(stream);
|
||||||
|
t.read(nbt);
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
if (stream != null)
|
||||||
|
IOUtils.closeQuietly(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ActionResultType onItemUse(ItemUseContext context) {
|
public ActionResultType onItemUse(ItemUseContext context) {
|
||||||
|
|
||||||
|
@ -66,28 +136,6 @@ public class ItemBlueprint extends Item {
|
||||||
return ActionResultType.SUCCESS;
|
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);
|
context.getPlayer().getCooldownTracker().setCooldown(this, 10);
|
||||||
|
|
|
@ -31,6 +31,9 @@ import net.minecraft.util.math.shapes.ISelectionContext;
|
||||||
import net.minecraft.util.text.StringTextComponent;
|
import net.minecraft.util.text.StringTextComponent;
|
||||||
import net.minecraft.util.text.TextFormatting;
|
import net.minecraft.util.text.TextFormatting;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
import net.minecraftforge.fml.DistExecutor;
|
||||||
import net.minecraftforge.fml.network.PacketDistributor;
|
import net.minecraftforge.fml.network.PacketDistributor;
|
||||||
|
|
||||||
public class ItemWandSymmetry extends Item {
|
public class ItemWandSymmetry extends Item {
|
||||||
|
@ -68,8 +71,9 @@ public class ItemWandSymmetry extends Item {
|
||||||
SymmetryElement newElement = new SymmetryPlane(pos3d);
|
SymmetryElement newElement = new SymmetryPlane(pos3d);
|
||||||
|
|
||||||
if (previousElement instanceof SymmetryEmptySlot) {
|
if (previousElement instanceof SymmetryEmptySlot) {
|
||||||
newElement.setOrientation((player.getHorizontalFacing() == Direction.NORTH
|
newElement.setOrientation(
|
||||||
|| player.getHorizontalFacing() == Direction.SOUTH) ? SymmetryPlane.Align.XY.ordinal()
|
(player.getHorizontalFacing() == Direction.NORTH || player.getHorizontalFacing() == Direction.SOUTH)
|
||||||
|
? SymmetryPlane.Align.XY.ordinal()
|
||||||
: SymmetryPlane.Align.YZ.ordinal());
|
: SymmetryPlane.Align.YZ.ordinal());
|
||||||
newElement.enable = true;
|
newElement.enable = true;
|
||||||
player.sendStatusMessage(new StringTextComponent(TextFormatting.GREEN + "New Plane created"), true);
|
player.sendStatusMessage(new StringTextComponent(TextFormatting.GREEN + "New Plane created"), true);
|
||||||
|
@ -105,12 +109,19 @@ public class ItemWandSymmetry extends Item {
|
||||||
@Override
|
@Override
|
||||||
public ActionResult<ItemStack> onItemRightClick(World worldIn, PlayerEntity playerIn, Hand handIn) {
|
public ActionResult<ItemStack> onItemRightClick(World worldIn, PlayerEntity playerIn, Hand handIn) {
|
||||||
if (worldIn.isRemote) {
|
if (worldIn.isRemote) {
|
||||||
GuiOpener.open(new GuiWandSymmetry(playerIn.getHeldItem(handIn)));
|
DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> {
|
||||||
|
openWandGUI(playerIn.getHeldItem(handIn));
|
||||||
|
});
|
||||||
playerIn.getCooldownTracker().setCooldown(this, 5);
|
playerIn.getCooldownTracker().setCooldown(this, 5);
|
||||||
}
|
}
|
||||||
return super.onItemRightClick(worldIn, playerIn, handIn);
|
return super.onItemRightClick(worldIn, playerIn, handIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
private void openWandGUI(ItemStack wand) {
|
||||||
|
GuiOpener.open(new GuiWandSymmetry(wand));
|
||||||
|
}
|
||||||
|
|
||||||
private static void checkNBT(ItemStack wand) {
|
private static void checkNBT(ItemStack wand) {
|
||||||
if (!wand.hasTag() || !wand.getTag().contains($SYMMETRY)) {
|
if (!wand.hasTag() || !wand.getTag().contains($SYMMETRY)) {
|
||||||
wand.setTag(new CompoundNBT());
|
wand.setTag(new CompoundNBT());
|
||||||
|
@ -136,8 +147,7 @@ public class ItemWandSymmetry extends Item {
|
||||||
|
|
||||||
Map<BlockPos, BlockState> blockSet = new HashMap<>();
|
Map<BlockPos, BlockState> blockSet = new HashMap<>();
|
||||||
blockSet.put(pos, block);
|
blockSet.put(pos, block);
|
||||||
SymmetryElement symmetry = SymmetryElement
|
SymmetryElement symmetry = SymmetryElement.fromNBT((CompoundNBT) wand.getTag().getCompound($SYMMETRY));
|
||||||
.fromNBT((CompoundNBT) wand.getTag().getCompound($SYMMETRY));
|
|
||||||
|
|
||||||
Vec3d mirrorPos = symmetry.getPosition();
|
Vec3d mirrorPos = symmetry.getPosition();
|
||||||
if (mirrorPos.distanceTo(new Vec3d(pos)) > 50)
|
if (mirrorPos.distanceTo(new Vec3d(pos)) > 50)
|
||||||
|
@ -156,7 +166,8 @@ public class ItemWandSymmetry extends Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Packets.channel.send(PacketDistributor.TRACKING_ENTITY_AND_SELF.with(() -> player), new PacketSymmetryEffect(to, targets));
|
Packets.channel.send(PacketDistributor.TRACKING_ENTITY_AND_SELF.with(() -> player),
|
||||||
|
new PacketSymmetryEffect(to, targets));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void remove(World world, ItemStack wand, PlayerEntity player, BlockPos pos) {
|
public static void remove(World world, ItemStack wand, PlayerEntity player, BlockPos pos) {
|
||||||
|
@ -167,8 +178,7 @@ public class ItemWandSymmetry extends Item {
|
||||||
|
|
||||||
Map<BlockPos, BlockState> blockSet = new HashMap<>();
|
Map<BlockPos, BlockState> blockSet = new HashMap<>();
|
||||||
blockSet.put(pos, air);
|
blockSet.put(pos, air);
|
||||||
SymmetryElement symmetry = SymmetryElement
|
SymmetryElement symmetry = SymmetryElement.fromNBT((CompoundNBT) wand.getTag().getCompound($SYMMETRY));
|
||||||
.fromNBT((CompoundNBT) wand.getTag().getCompound($SYMMETRY));
|
|
||||||
|
|
||||||
Vec3d mirrorPos = symmetry.getPosition();
|
Vec3d mirrorPos = symmetry.getPosition();
|
||||||
if (mirrorPos.distanceTo(new Vec3d(pos)) > 50)
|
if (mirrorPos.distanceTo(new Vec3d(pos)) > 50)
|
||||||
|
@ -185,7 +195,8 @@ public class ItemWandSymmetry extends Item {
|
||||||
world.setBlockState(position, air);
|
world.setBlockState(position, air);
|
||||||
}
|
}
|
||||||
|
|
||||||
Packets.channel.send(PacketDistributor.TRACKING_ENTITY_AND_SELF.with(() -> player), new PacketSymmetryEffect(to, targets));
|
Packets.channel.send(PacketDistributor.TRACKING_ENTITY_AND_SELF.with(() -> player),
|
||||||
|
new PacketSymmetryEffect(to, targets));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,26 +10,44 @@ import net.minecraftforge.fml.network.NetworkEvent.Context;
|
||||||
public class PacketNbt {
|
public class PacketNbt {
|
||||||
|
|
||||||
public ItemStack stack;
|
public ItemStack stack;
|
||||||
|
public int slot;
|
||||||
|
|
||||||
public PacketNbt(ItemStack stack) {
|
public PacketNbt(ItemStack stack) {
|
||||||
|
this(stack, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PacketNbt(ItemStack stack, int slot) {
|
||||||
this.stack = stack;
|
this.stack = stack;
|
||||||
|
this.slot = slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PacketNbt(PacketBuffer buffer) {
|
public PacketNbt(PacketBuffer buffer) {
|
||||||
stack = buffer.readItemStack();
|
stack = buffer.readItemStack();
|
||||||
|
slot = buffer.readInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void toBytes(PacketBuffer buffer) {
|
public void toBytes(PacketBuffer buffer) {
|
||||||
buffer.writeItemStack(stack);
|
buffer.writeItemStack(stack);
|
||||||
|
buffer.writeInt(slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handle(Supplier<Context> context) {
|
public void handle(Supplier<Context> context) {
|
||||||
context.get().enqueueWork(() -> {
|
context.get().enqueueWork(() -> {
|
||||||
ServerPlayerEntity player = context.get().getSender();
|
ServerPlayerEntity player = context.get().getSender();
|
||||||
ItemStack heldItem = player.getHeldItemMainhand();
|
|
||||||
if (heldItem.getItem() == stack.getItem()) {
|
if (slot == -1) {
|
||||||
heldItem.setTag(stack.getTag());
|
ItemStack heldItem = player.getHeldItemMainhand();
|
||||||
|
if (heldItem.getItem() == stack.getItem()) {
|
||||||
|
heldItem.setTag(stack.getTag());
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ItemStack heldInSlot = player.inventory.getStackInSlot(slot);
|
||||||
|
if (heldInSlot.getItem() == stack.getItem()) {
|
||||||
|
heldInSlot.setTag(stack.getTag());
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,6 @@ import com.simibubi.create.block.SchematicTableContainer;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.inventory.container.Container;
|
import net.minecraft.inventory.container.Container;
|
||||||
import net.minecraft.network.PacketBuffer;
|
import net.minecraft.network.PacketBuffer;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
|
||||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
|
||||||
import net.minecraftforge.fml.network.NetworkEvent.Context;
|
import net.minecraftforge.fml.network.NetworkEvent.Context;
|
||||||
|
|
||||||
public class PacketSchematicTableContainer {
|
public class PacketSchematicTableContainer {
|
||||||
|
@ -33,14 +31,12 @@ public class PacketSchematicTableContainer {
|
||||||
buffer.writeFloat(progress);
|
buffer.writeFloat(progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnlyIn(Dist.CLIENT)
|
|
||||||
public void handle(Supplier<Context> context) {
|
public void handle(Supplier<Context> context) {
|
||||||
context.get().enqueueWork(() -> {
|
context.get().enqueueWork(() -> {
|
||||||
Container c = Minecraft.getInstance().player.openContainer;
|
Container c = Minecraft.getInstance().player.openContainer;
|
||||||
if (c != null && c instanceof SchematicTableContainer) {
|
if (c != null && c instanceof SchematicTableContainer) {
|
||||||
((SchematicTableContainer) c).receiveSchematicInfo(schematic, progress);
|
((SchematicTableContainer) c).receiveSchematicInfo(schematic, progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ public class PacketSchematicUpload {
|
||||||
|
|
||||||
public PacketSchematicUpload(PacketBuffer buffer) {
|
public PacketSchematicUpload(PacketBuffer buffer) {
|
||||||
code = buffer.readInt();
|
code = buffer.readInt();
|
||||||
schematic = buffer.readString();
|
schematic = buffer.readString(256);
|
||||||
|
|
||||||
if (code == WRITE)
|
if (code == WRITE)
|
||||||
data = buffer.readByteArray();
|
data = buffer.readByteArray();
|
||||||
|
|
|
@ -10,13 +10,14 @@ public class Packets {
|
||||||
|
|
||||||
private static final String PROTOCOL_VERSION = "1";
|
private static final String PROTOCOL_VERSION = "1";
|
||||||
|
|
||||||
public static final SimpleChannel channel = NetworkRegistry.newSimpleChannel(
|
public static SimpleChannel channel;
|
||||||
new ResourceLocation(Create.ID, "main"), () -> PROTOCOL_VERSION, PROTOCOL_VERSION::equals,
|
|
||||||
PROTOCOL_VERSION::equals);
|
|
||||||
|
|
||||||
public static void registerPackets() {
|
public static void registerPackets() {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
|
channel = NetworkRegistry.newSimpleChannel(new ResourceLocation(Create.ID, "main"), () -> PROTOCOL_VERSION,
|
||||||
|
PROTOCOL_VERSION::equals, PROTOCOL_VERSION::equals);
|
||||||
|
|
||||||
channel.registerMessage(i++, PacketNbt.class, PacketNbt::toBytes, PacketNbt::new, PacketNbt::handle);
|
channel.registerMessage(i++, PacketNbt.class, PacketNbt::toBytes, PacketNbt::new, PacketNbt::handle);
|
||||||
channel.registerMessage(i++, PacketSchematicTableContainer.class, PacketSchematicTableContainer::toBytes,
|
channel.registerMessage(i++, PacketSchematicTableContainer.class, PacketSchematicTableContainer::toBytes,
|
||||||
PacketSchematicTableContainer::new, PacketSchematicTableContainer::handle);
|
PacketSchematicTableContainer::new, PacketSchematicTableContainer::handle);
|
||||||
|
|
|
@ -0,0 +1,355 @@
|
||||||
|
package com.simibubi.create.schematic;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.simibubi.create.AllItems;
|
||||||
|
import com.simibubi.create.Create;
|
||||||
|
import com.simibubi.create.gui.BlueprintHotbarOverlay;
|
||||||
|
import com.simibubi.create.gui.Keyboard;
|
||||||
|
import com.simibubi.create.gui.ToolSelectionScreen;
|
||||||
|
import com.simibubi.create.item.ItemBlueprint;
|
||||||
|
import com.simibubi.create.networking.PacketNbt;
|
||||||
|
import com.simibubi.create.networking.Packets;
|
||||||
|
import com.simibubi.create.utility.TessellatorHelper;
|
||||||
|
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.entity.player.ClientPlayerEntity;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
import net.minecraft.nbt.NBTUtil;
|
||||||
|
import net.minecraft.util.Direction.Axis;
|
||||||
|
import net.minecraft.util.Mirror;
|
||||||
|
import net.minecraft.util.Rotation;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.text.StringTextComponent;
|
||||||
|
import net.minecraft.world.gen.feature.template.PlacementSettings;
|
||||||
|
import net.minecraft.world.gen.feature.template.Template;
|
||||||
|
import net.minecraftforge.client.event.InputEvent.KeyInputEvent;
|
||||||
|
import net.minecraftforge.client.event.InputEvent.MouseInputEvent;
|
||||||
|
import net.minecraftforge.client.event.RenderGameOverlayEvent;
|
||||||
|
import net.minecraftforge.client.event.RenderWorldLastEvent;
|
||||||
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
|
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||||
|
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
|
||||||
|
import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent;
|
||||||
|
|
||||||
|
@EventBusSubscriber(bus = Bus.FORGE)
|
||||||
|
public class BlueprintHandler {
|
||||||
|
|
||||||
|
public static BlueprintHandler instance;
|
||||||
|
|
||||||
|
public Template cachedSchematic;
|
||||||
|
public String cachedSchematicName;
|
||||||
|
public PlacementSettings cachedSettings;
|
||||||
|
|
||||||
|
public BlockPos anchor;
|
||||||
|
public BlockPos size;
|
||||||
|
public boolean active;
|
||||||
|
public boolean deployed;
|
||||||
|
public int slot;
|
||||||
|
public ItemStack item;
|
||||||
|
|
||||||
|
public Tools currentTool;
|
||||||
|
public ToolSelectionScreen selectionScreen;
|
||||||
|
|
||||||
|
public static final int SYNC_DELAY = 20;
|
||||||
|
public int syncCooldown;
|
||||||
|
|
||||||
|
private BlueprintHotbarOverlay overlay;
|
||||||
|
|
||||||
|
public BlueprintHandler() {
|
||||||
|
instance = this;
|
||||||
|
currentTool = Tools.Deploy;
|
||||||
|
overlay = new BlueprintHotbarOverlay();
|
||||||
|
selectionScreen = new ToolSelectionScreen(ImmutableList.of(Tools.Deploy), this::equip);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void onClientTick(ClientTickEvent event) {
|
||||||
|
ClientPlayerEntity player = Minecraft.getInstance().player;
|
||||||
|
|
||||||
|
if (player == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ItemStack stack = findBlueprintInHand(player);
|
||||||
|
if (stack == null) {
|
||||||
|
instance.active = false;
|
||||||
|
instance.syncCooldown = 0;
|
||||||
|
instance.slot = 0;
|
||||||
|
if (instance.item != null && itemLost(player)) {
|
||||||
|
instance.item = null;
|
||||||
|
SchematicHologram.reset();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Newly equipped
|
||||||
|
if (!instance.active || !stack.getTag().getString("File").equals(instance.cachedSchematicName)) {
|
||||||
|
instance.loadSettings(stack);
|
||||||
|
instance.cachedSchematicName = stack.getTag().getString("File");
|
||||||
|
instance.active = true;
|
||||||
|
if (instance.deployed) {
|
||||||
|
Tools toolBefore = instance.currentTool;
|
||||||
|
instance.selectionScreen = new ToolSelectionScreen(Tools.getTools(), instance::equip);
|
||||||
|
if (toolBefore != null) {
|
||||||
|
instance.selectionScreen.setSelectedElement(toolBefore);
|
||||||
|
instance.equip(toolBefore);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
instance.selectionScreen = new ToolSelectionScreen(ImmutableList.of(Tools.Deploy), instance::equip);
|
||||||
|
instance.sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!instance.active)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (instance.syncCooldown > 0)
|
||||||
|
instance.syncCooldown--;
|
||||||
|
if (instance.syncCooldown == 1)
|
||||||
|
instance.sync();
|
||||||
|
|
||||||
|
instance.selectionScreen.update();
|
||||||
|
instance.currentTool.getTool().updateSelection();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void onRenderWorld(RenderWorldLastEvent event) {
|
||||||
|
if (!instance.active)
|
||||||
|
return;
|
||||||
|
|
||||||
|
TessellatorHelper.prepareForDrawing();
|
||||||
|
instance.currentTool.getTool().renderTool();
|
||||||
|
TessellatorHelper.cleanUpAfterDrawing();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void onRenderOverlay(RenderGameOverlayEvent event) {
|
||||||
|
if (!instance.active)
|
||||||
|
return;
|
||||||
|
|
||||||
|
instance.overlay.renderOn(instance.slot);
|
||||||
|
instance.currentTool.getTool().renderOverlay();
|
||||||
|
instance.selectionScreen.renderPassive(event.getPartialTicks());
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void onClick(MouseInputEvent event) {
|
||||||
|
if (Minecraft.getInstance().currentScreen != null)
|
||||||
|
return;
|
||||||
|
if (event.getAction() != Keyboard.PRESS)
|
||||||
|
return;
|
||||||
|
if (event.getButton() != 1)
|
||||||
|
return;
|
||||||
|
if (!instance.active)
|
||||||
|
return;
|
||||||
|
|
||||||
|
instance.currentTool.getTool().handleRightClick();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void onKeyTyped(KeyInputEvent event) {
|
||||||
|
if (Minecraft.getInstance().currentScreen != null)
|
||||||
|
return;
|
||||||
|
if (event.getKey() != Create.TOOL_MENU.getKey().getKeyCode())
|
||||||
|
return;
|
||||||
|
if (!instance.active)
|
||||||
|
return;
|
||||||
|
|
||||||
|
boolean released = event.getAction() == Keyboard.RELEASE;
|
||||||
|
|
||||||
|
ToolSelectionScreen toolSelection = instance.selectionScreen;
|
||||||
|
if (released && toolSelection.focused) {
|
||||||
|
toolSelection.focused = false;
|
||||||
|
toolSelection.onClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!released && !toolSelection.focused)
|
||||||
|
toolSelection.focused = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean onScroll(double delta) {
|
||||||
|
if (!active)
|
||||||
|
return false;
|
||||||
|
if (selectionScreen.focused) {
|
||||||
|
selectionScreen.cycle((int) delta);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (Keyboard.isKeyDown(GLFW.GLFW_KEY_LEFT_CONTROL)) {
|
||||||
|
return currentTool.getTool().handleMouseWheel(delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ItemStack findBlueprintInHand(PlayerEntity player) {
|
||||||
|
ItemStack stack = player.getHeldItemMainhand();
|
||||||
|
if (!AllItems.BLUEPRINT.typeOf(stack))
|
||||||
|
return null;
|
||||||
|
if (!stack.hasTag())
|
||||||
|
return null;
|
||||||
|
|
||||||
|
instance.item = stack;
|
||||||
|
instance.slot = player.inventory.currentItem;
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean itemLost(PlayerEntity player) {
|
||||||
|
for (int i = 0; i < PlayerInventory.getHotbarSize(); i++) {
|
||||||
|
if (!player.inventory.getStackInSlot(i).isItemEqual(instance.item))
|
||||||
|
continue;
|
||||||
|
if (!ItemStack.areItemStackTagsEqual(player.inventory.getStackInSlot(i), instance.item))
|
||||||
|
continue;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void markDirty() {
|
||||||
|
syncCooldown = SYNC_DELAY;
|
||||||
|
SchematicHologram.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sync() {
|
||||||
|
Minecraft.getInstance().player.sendStatusMessage(new StringTextComponent("Syncing..."), true);
|
||||||
|
Packets.channel.sendToServer(new PacketNbt(item, slot));
|
||||||
|
|
||||||
|
SchematicWorld w = new SchematicWorld(new HashMap<>(), new Cuboid(), anchor);
|
||||||
|
PlacementSettings settings = cachedSettings.copy();
|
||||||
|
settings.setBoundingBox(null);
|
||||||
|
ItemBlueprint.getSchematic(item).addBlocksToWorld(w, anchor, settings);
|
||||||
|
|
||||||
|
new SchematicHologram().startHologram(w);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void equip(Tools tool) {
|
||||||
|
this.currentTool = tool;
|
||||||
|
currentTool.getTool().init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadSettings(ItemStack blueprint) {
|
||||||
|
CompoundNBT tag = blueprint.getTag();
|
||||||
|
cachedSettings = new PlacementSettings();
|
||||||
|
cachedSettings.setRotation(Rotation.valueOf(tag.getString("Rotation")));
|
||||||
|
cachedSettings.setMirror(Mirror.valueOf(tag.getString("Mirror")));
|
||||||
|
|
||||||
|
deployed = tag.getBoolean("Deployed");
|
||||||
|
if (deployed)
|
||||||
|
anchor = NBTUtil.readBlockPos(tag.getCompound("Anchor"));
|
||||||
|
|
||||||
|
size = NBTUtil.readBlockPos(tag.getCompound("Bounds"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void flip(Axis axis) {
|
||||||
|
|
||||||
|
Rotation r = cachedSettings.getRotation();
|
||||||
|
boolean rotationAt90s = r == Rotation.CLOCKWISE_90 || r == Rotation.COUNTERCLOCKWISE_90;
|
||||||
|
Mirror mirror = axis == Axis.Z ^ rotationAt90s ? Mirror.FRONT_BACK : Mirror.LEFT_RIGHT;
|
||||||
|
|
||||||
|
BlockPos coordModifier = new BlockPos((r == Rotation.NONE || r == Rotation.COUNTERCLOCKWISE_90) ? 1 : -1, 0,
|
||||||
|
(r == Rotation.NONE || r == Rotation.CLOCKWISE_90) ? 1 : -1);
|
||||||
|
BlockPos anchorOffset = axis == Axis.Z
|
||||||
|
? new BlockPos(((rotationAt90s ? size.getZ() : size.getX()) - 1) * coordModifier.getX(), 0, 0)
|
||||||
|
: new BlockPos(0, 0, ((!rotationAt90s ? size.getZ() : size.getX()) - 1) * coordModifier.getZ());
|
||||||
|
|
||||||
|
Mirror m = cachedSettings.getMirror();
|
||||||
|
|
||||||
|
if (m == Mirror.NONE) {
|
||||||
|
cachedSettings.setMirror(mirror);
|
||||||
|
anchor = anchor.add(anchorOffset);
|
||||||
|
Minecraft.getInstance().player.sendStatusMessage(
|
||||||
|
new StringTextComponent("Mirror: " + cachedSettings.getMirror().toString()), true);
|
||||||
|
|
||||||
|
} else if (m == mirror) {
|
||||||
|
cachedSettings.setMirror(Mirror.NONE);
|
||||||
|
anchor = anchor.subtract(anchorOffset);
|
||||||
|
Minecraft.getInstance().player.sendStatusMessage(
|
||||||
|
new StringTextComponent("Mirror: " + cachedSettings.getMirror().toString()), true);
|
||||||
|
|
||||||
|
} else if (m != mirror) {
|
||||||
|
cachedSettings.setMirror(Mirror.NONE);
|
||||||
|
anchor = anchor.add(anchorOffset);
|
||||||
|
cachedSettings.setRotation(r.add(Rotation.CLOCKWISE_180));
|
||||||
|
Minecraft.getInstance().player.sendStatusMessage(
|
||||||
|
new StringTextComponent("Mirror: None, Rotation: " + cachedSettings.getRotation().toString()),
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
|
||||||
|
item.getTag().put("Anchor", NBTUtil.writeBlockPos(anchor));
|
||||||
|
item.getTag().putString("Mirror", cachedSettings.getMirror().name());
|
||||||
|
item.getTag().putString("Rotation", r.name());
|
||||||
|
|
||||||
|
markDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void rotate(Rotation rotation) {
|
||||||
|
Rotation r = cachedSettings.getRotation();
|
||||||
|
BlockPos center = centerOfSchematic();
|
||||||
|
cachedSettings.setRotation(r.add(rotation));
|
||||||
|
BlockPos diff = center.subtract(anchor);
|
||||||
|
BlockPos move = diff.subtract(diff.rotate(rotation));
|
||||||
|
anchor = anchor.add(move);
|
||||||
|
|
||||||
|
item.getTag().put("Anchor", NBTUtil.writeBlockPos(anchor));
|
||||||
|
item.getTag().putString("Rotation", cachedSettings.getRotation().name());
|
||||||
|
|
||||||
|
Minecraft.getInstance().player.sendStatusMessage(
|
||||||
|
new StringTextComponent("Rotation: " + cachedSettings.getRotation().toString()), true);
|
||||||
|
|
||||||
|
markDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void moveTo(BlockPos anchor) {
|
||||||
|
if (!deployed)
|
||||||
|
instance.selectionScreen = new ToolSelectionScreen(Tools.getTools(), instance::equip);
|
||||||
|
|
||||||
|
deployed = true;
|
||||||
|
this.anchor = anchor;
|
||||||
|
item.getTag().putBoolean("Deployed", true);
|
||||||
|
item.getTag().put("Anchor", NBTUtil.writeBlockPos(anchor));
|
||||||
|
markDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockPos getTransformedSize() {
|
||||||
|
BlockPos flipped = size;
|
||||||
|
if (cachedSettings.getMirror() == Mirror.FRONT_BACK)
|
||||||
|
flipped = new BlockPos(-flipped.getX(), flipped.getY(), flipped.getZ());
|
||||||
|
if (cachedSettings.getMirror() == Mirror.LEFT_RIGHT)
|
||||||
|
flipped = new BlockPos(flipped.getX(), flipped.getY(), -flipped.getZ());
|
||||||
|
|
||||||
|
BlockPos rotate = flipped.rotate(cachedSettings.getRotation());
|
||||||
|
return rotate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockPos getTransformedAnchor() {
|
||||||
|
BlockPos anchor = this.anchor;
|
||||||
|
Rotation r = cachedSettings.getRotation();
|
||||||
|
|
||||||
|
BlockPos flipOffset = BlockPos.ZERO;
|
||||||
|
if (cachedSettings.getMirror() == Mirror.FRONT_BACK)
|
||||||
|
flipOffset = new BlockPos(1, 0, 0);
|
||||||
|
if (cachedSettings.getMirror() == Mirror.LEFT_RIGHT)
|
||||||
|
flipOffset = new BlockPos(0, 0, 1);
|
||||||
|
|
||||||
|
flipOffset = flipOffset.rotate(r);
|
||||||
|
anchor = anchor.add(flipOffset);
|
||||||
|
|
||||||
|
if (r == Rotation.CLOCKWISE_90 || r == Rotation.CLOCKWISE_180)
|
||||||
|
anchor = anchor.add(1, 0, 0);
|
||||||
|
if (r == Rotation.COUNTERCLOCKWISE_90 || r == Rotation.CLOCKWISE_180)
|
||||||
|
anchor = anchor.add(0, 0, 1);
|
||||||
|
return anchor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockPos centerOfSchematic() {
|
||||||
|
BlockPos size = getTransformedSize();
|
||||||
|
BlockPos center = new BlockPos(size.getX() / 2, 0, size.getZ() / 2);
|
||||||
|
return anchor.add(center);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -11,6 +11,10 @@ public class Cuboid {
|
||||||
public int height;
|
public int height;
|
||||||
public int length;
|
public int length;
|
||||||
|
|
||||||
|
public Cuboid() {
|
||||||
|
this(BlockPos.ZERO, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
public Cuboid(BlockPos origin, BlockPos size) {
|
public Cuboid(BlockPos origin, BlockPos size) {
|
||||||
this(origin, size.getX(), size.getY(), size.getZ());
|
this(origin, size.getX(), size.getY(), size.getZ());
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.simibubi.create.schematic;
|
||||||
|
|
||||||
|
public interface ISchematicTool {
|
||||||
|
|
||||||
|
public void init();
|
||||||
|
public void updateSelection();
|
||||||
|
|
||||||
|
public boolean handleRightClick();
|
||||||
|
public boolean handleMouseWheel(double delta);
|
||||||
|
|
||||||
|
public void renderTool();
|
||||||
|
public void renderOverlay();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
package com.simibubi.create.schematic;
|
||||||
|
|
||||||
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
|
import com.simibubi.create.gui.Keyboard;
|
||||||
|
|
||||||
|
import net.minecraft.client.renderer.WorldRenderer;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraft.util.math.MutableBoundingBox;
|
||||||
|
|
||||||
|
public class SchematicDeployTool extends SchematicPlacementToolBase {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
super.init();
|
||||||
|
selectionRange = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateSelection() {
|
||||||
|
if (blueprint.active && selectionRange == -1) {
|
||||||
|
selectionRange = (int) blueprint.size.manhattanDistance(BlockPos.ZERO) / 2;
|
||||||
|
selectionRange = MathHelper.clamp(selectionRange, 1, 100);
|
||||||
|
}
|
||||||
|
selectIgnoreBlocks = Keyboard.isKeyDown(GLFW.GLFW_KEY_LEFT_CONTROL);
|
||||||
|
|
||||||
|
super.updateSelection();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void renderTool() {
|
||||||
|
super.renderTool();
|
||||||
|
|
||||||
|
if (selectedPos == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
BlockPos size = blueprint.getTransformedSize();
|
||||||
|
BlockPos min = selectedPos.add(Math.round(size.getX() * -.5f), 0, Math.round(size.getZ() * -.5f));
|
||||||
|
BlockPos max = min.add(size.getX(), size.getY(), size.getZ());
|
||||||
|
|
||||||
|
if (blueprint.deployed) {
|
||||||
|
MutableBoundingBox bb = new MutableBoundingBox(min, min.add(blueprint.getTransformedSize()));
|
||||||
|
min = new BlockPos(bb.minX, bb.minY, bb.minZ);
|
||||||
|
max = new BlockPos(bb.maxX, bb.maxY, bb.maxZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
GlStateManager.lineWidth(3);
|
||||||
|
GlStateManager.color4f(.5f, .8f, 1, 1);
|
||||||
|
GlStateManager.disableTexture();
|
||||||
|
|
||||||
|
WorldRenderer.drawBoundingBox(min.getX() - 1 / 8d, min.getY() + 1 / 16d, min.getZ() - 1 / 8d,
|
||||||
|
max.getX() + 1 / 8d, max.getY() + 1 / 8d, max.getZ() + 1 / 8d, 1, 1, 1, 1);
|
||||||
|
|
||||||
|
GlStateManager.lineWidth(1);
|
||||||
|
GlStateManager.enableTexture();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handleMouseWheel(double delta) {
|
||||||
|
|
||||||
|
if (selectIgnoreBlocks) {
|
||||||
|
selectionRange += delta;
|
||||||
|
selectionRange = MathHelper.clamp(selectionRange, 1, 100);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.handleMouseWheel(delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handleRightClick() {
|
||||||
|
if (selectedPos == null)
|
||||||
|
return super.handleRightClick();
|
||||||
|
|
||||||
|
BlockPos size = blueprint.getTransformedSize();
|
||||||
|
blueprint.moveTo(selectedPos.add(Math.round(size.getX() * -.5f), 0, Math.round(size.getZ() * -.5f)));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package com.simibubi.create.schematic;
|
||||||
|
|
||||||
|
public class SchematicFlipTool extends SchematicPlacementToolBase {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
super.init();
|
||||||
|
renderSelectedFace = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handleRightClick() {
|
||||||
|
mirror();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handleMouseWheel(double delta) {
|
||||||
|
mirror();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateSelection() {
|
||||||
|
super.updateSelection();
|
||||||
|
|
||||||
|
if (!schematicSelected)
|
||||||
|
return;
|
||||||
|
|
||||||
|
renderSelectedFace = selectedFace.getAxis().isHorizontal();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void mirror() {
|
||||||
|
if (schematicSelected && selectedFace.getAxis().isHorizontal()) {
|
||||||
|
blueprint.flip(selectedFace.getAxis());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -28,6 +28,7 @@ import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.gen.feature.template.PlacementSettings;
|
import net.minecraft.world.gen.feature.template.PlacementSettings;
|
||||||
import net.minecraft.world.gen.feature.template.Template;
|
import net.minecraft.world.gen.feature.template.Template;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
import net.minecraftforge.client.ForgeHooksClient;
|
import net.minecraftforge.client.ForgeHooksClient;
|
||||||
import net.minecraftforge.client.event.RenderWorldLastEvent;
|
import net.minecraftforge.client.event.RenderWorldLastEvent;
|
||||||
import net.minecraftforge.client.model.data.EmptyModelData;
|
import net.minecraftforge.client.model.data.EmptyModelData;
|
||||||
|
@ -36,6 +37,7 @@ import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||||
import net.minecraftforge.fml.common.gameevent.TickEvent;
|
import net.minecraftforge.fml.common.gameevent.TickEvent;
|
||||||
import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent;
|
import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent;
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
@EventBusSubscriber(Dist.CLIENT)
|
@EventBusSubscriber(Dist.CLIENT)
|
||||||
public class SchematicHologram {
|
public class SchematicHologram {
|
||||||
|
|
||||||
|
@ -64,6 +66,13 @@ public class SchematicHologram {
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void startHologram(SchematicWorld world) {
|
||||||
|
this.anchor = world.anchor;
|
||||||
|
this.schematic = world;
|
||||||
|
this.active = true;
|
||||||
|
this.changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
public static SchematicHologram getInstance() {
|
public static SchematicHologram getInstance() {
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.simibubi.create.schematic;
|
||||||
|
|
||||||
|
public class SchematicMoveTool extends SchematicPlacementToolBase {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
super.init();
|
||||||
|
renderSelectedFace = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handleMouseWheel(double delta) {
|
||||||
|
|
||||||
|
if (schematicSelected && selectedFace.getAxis().isHorizontal()) {
|
||||||
|
blueprint.moveTo(delta < 0 ? blueprint.anchor.add(selectedFace.getDirectionVec())
|
||||||
|
: blueprint.anchor.subtract(selectedFace.getDirectionVec()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.handleMouseWheel(delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.simibubi.create.schematic;
|
||||||
|
|
||||||
|
public class SchematicMoveVerticalTool extends SchematicPlacementToolBase {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handleMouseWheel(double delta) {
|
||||||
|
|
||||||
|
if (blueprint.deployed) {
|
||||||
|
blueprint.moveTo(blueprint.anchor.add(0, delta, 0));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.handleMouseWheel(delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package com.simibubi.create.schematic;
|
||||||
|
|
||||||
|
public abstract class SchematicPlacementToolBase extends SchematicToolBase {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
super.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateSelection() {
|
||||||
|
super.updateSelection();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void renderTool() {
|
||||||
|
super.renderTool();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void renderOverlay() {
|
||||||
|
super.renderOverlay();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handleMouseWheel(double delta) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handleRightClick() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.simibubi.create.schematic;
|
||||||
|
|
||||||
|
import net.minecraft.util.Rotation;
|
||||||
|
|
||||||
|
public class SchematicRotateTool extends SchematicPlacementToolBase {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handleMouseWheel(double delta) {
|
||||||
|
blueprint.rotate(delta > 0 ? Rotation.CLOCKWISE_90 : Rotation.COUNTERCLOCKWISE_90);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,122 @@
|
||||||
|
package com.simibubi.create.schematic;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
|
import com.simibubi.create.utility.RaycastHelper;
|
||||||
|
import com.simibubi.create.utility.RaycastHelper.PredicateTraceResult;
|
||||||
|
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.entity.player.ClientPlayerEntity;
|
||||||
|
import net.minecraft.client.renderer.WorldRenderer;
|
||||||
|
import net.minecraft.item.BlockItemUseContext;
|
||||||
|
import net.minecraft.item.ItemUseContext;
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.BlockRayTraceResult;
|
||||||
|
import net.minecraft.util.math.MutableBoundingBox;
|
||||||
|
import net.minecraft.util.math.RayTraceResult.Type;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
|
public abstract class SchematicToolBase implements ISchematicTool {
|
||||||
|
|
||||||
|
protected BlueprintHandler blueprint;
|
||||||
|
|
||||||
|
public BlockPos selectedPos;
|
||||||
|
public boolean selectIgnoreBlocks;
|
||||||
|
public int selectionRange;
|
||||||
|
|
||||||
|
public boolean schematicSelected;
|
||||||
|
public boolean renderSelectedFace;
|
||||||
|
public Direction selectedFace;
|
||||||
|
|
||||||
|
public SchematicToolBase() {
|
||||||
|
blueprint = BlueprintHandler.instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
selectedPos = null;
|
||||||
|
selectedFace = null;
|
||||||
|
schematicSelected = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateSelection() {
|
||||||
|
ClientPlayerEntity player = Minecraft.getInstance().player;
|
||||||
|
|
||||||
|
// Select Blueprint
|
||||||
|
if (blueprint.deployed) {
|
||||||
|
PredicateTraceResult result = RaycastHelper.rayTraceUntil(player, 70,
|
||||||
|
pos -> new MutableBoundingBox(BlockPos.ZERO, blueprint.getTransformedSize())
|
||||||
|
.isVecInside(pos.subtract(blueprint.anchor)));
|
||||||
|
schematicSelected = !result.missed();
|
||||||
|
selectedFace = schematicSelected ? result.getFacing() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select location at distance
|
||||||
|
if (selectIgnoreBlocks) {
|
||||||
|
selectedPos = new BlockPos(player.getEyePosition(Minecraft.getInstance().getRenderPartialTicks())
|
||||||
|
.add(player.getLookVec().scale(selectionRange)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select targeted Block
|
||||||
|
BlockRayTraceResult trace = RaycastHelper.rayTraceRange(player.world, player, 75);
|
||||||
|
if (trace != null && trace.getType() == Type.BLOCK) {
|
||||||
|
|
||||||
|
BlockPos hit = new BlockPos(trace.getHitVec());
|
||||||
|
boolean replaceable = player.world.getBlockState(hit)
|
||||||
|
.isReplaceable(new BlockItemUseContext(new ItemUseContext(player, Hand.MAIN_HAND, trace)));
|
||||||
|
if (trace.getFace().getAxis().isVertical() && !replaceable)
|
||||||
|
hit = hit.offset(trace.getFace());
|
||||||
|
|
||||||
|
selectedPos = hit;
|
||||||
|
} else {
|
||||||
|
selectedPos = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void renderTool() {
|
||||||
|
|
||||||
|
if (blueprint.deployed) {
|
||||||
|
GlStateManager.lineWidth(5);
|
||||||
|
GlStateManager.color4f(1, 1, 1, 1);
|
||||||
|
GlStateManager.disableTexture();
|
||||||
|
|
||||||
|
BlockPos min = blueprint.getTransformedAnchor();
|
||||||
|
MutableBoundingBox bb = new MutableBoundingBox(min, min.add(blueprint.getTransformedSize()));
|
||||||
|
min = new BlockPos(bb.minX, bb.minY, bb.minZ);
|
||||||
|
BlockPos max = new BlockPos(bb.maxX, bb.maxY, bb.maxZ);
|
||||||
|
|
||||||
|
WorldRenderer.drawBoundingBox(min.getX() - 1 / 8d, min.getY() + 1 / 16d, min.getZ() - 1 / 8d,
|
||||||
|
max.getX() + 1 / 8d, max.getY() + 1 / 8d, max.getZ() + 1 / 8d, .3f, .4f, 1, 1);
|
||||||
|
|
||||||
|
if (schematicSelected && renderSelectedFace) {
|
||||||
|
Vec3d vec = new Vec3d(selectedFace.getDirectionVec());
|
||||||
|
Vec3d center = new Vec3d(min.add(max)).scale(1 / 2f);
|
||||||
|
Vec3d radii = new Vec3d(max.subtract(min)).scale(1 / 2f);
|
||||||
|
|
||||||
|
Vec3d onFaceOffset = new Vec3d(1 - Math.abs(vec.x), 1 - Math.abs(vec.y), 1 - Math.abs(vec.z))
|
||||||
|
.mul(radii);
|
||||||
|
Vec3d faceMin = center.add(vec.mul(radii).add(onFaceOffset));
|
||||||
|
Vec3d faceMax = center.add(vec.mul(radii).subtract(onFaceOffset));
|
||||||
|
|
||||||
|
GlStateManager.lineWidth(4);
|
||||||
|
WorldRenderer.drawBoundingBox(faceMin.getX(), faceMin.getY() + 1 / 16d, faceMin.getZ(), faceMax.getX(),
|
||||||
|
faceMax.getY() + 1 / 8d, faceMax.getZ(), 1, 1, 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
GlStateManager.lineWidth(1);
|
||||||
|
GlStateManager.enableTexture();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void renderOverlay() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -45,7 +45,7 @@ public class SchematicWorld implements IWorld {
|
||||||
|
|
||||||
private Map<BlockPos, BlockState> blocks;
|
private Map<BlockPos, BlockState> blocks;
|
||||||
private Cuboid bounds;
|
private Cuboid bounds;
|
||||||
private BlockPos anchor;
|
public BlockPos anchor;
|
||||||
|
|
||||||
public SchematicWorld(Map<BlockPos, BlockState> blocks, Cuboid bounds, BlockPos anchor) {
|
public SchematicWorld(Map<BlockPos, BlockState> blocks, Cuboid bounds, BlockPos anchor) {
|
||||||
this.blocks = blocks;
|
this.blocks = blocks;
|
||||||
|
|
46
src/main/java/com/simibubi/create/schematic/Tools.java
Normal file
46
src/main/java/com/simibubi/create/schematic/Tools.java
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
package com.simibubi.create.schematic;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.simibubi.create.gui.GuiResources;
|
||||||
|
|
||||||
|
public enum Tools {
|
||||||
|
|
||||||
|
Deploy(new SchematicDeployTool(), "Deploy", GuiResources.ICON_3x3),
|
||||||
|
|
||||||
|
Move(new SchematicMoveTool(), "Move XZ", GuiResources.ICON_3x3),
|
||||||
|
MoveY(new SchematicMoveVerticalTool(), "Move Y", GuiResources.ICON_3x3),
|
||||||
|
Rotate(new SchematicRotateTool(), "Rotate", GuiResources.ICON_3x3),
|
||||||
|
Flip(new SchematicFlipTool(), "Flip", GuiResources.ICON_3x3);
|
||||||
|
|
||||||
|
private ISchematicTool tool;
|
||||||
|
private String displayName;
|
||||||
|
private GuiResources icon;
|
||||||
|
|
||||||
|
private Tools(ISchematicTool tool, String name, GuiResources icon) {
|
||||||
|
this.tool = tool;
|
||||||
|
this.displayName = name;
|
||||||
|
this.icon = icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ISchematicTool getTool() {
|
||||||
|
return tool;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDisplayName() {
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GuiResources getIcon() {
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Tools> getTools() {
|
||||||
|
List<Tools> tools = new ArrayList<>();
|
||||||
|
Collections.addAll(tools, Move, MoveY, Deploy, Rotate, Flip);
|
||||||
|
return tools;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
195
src/main/java/com/simibubi/create/utility/RaycastHelper.java
Normal file
195
src/main/java/com/simibubi/create/utility/RaycastHelper.java
Normal file
|
@ -0,0 +1,195 @@
|
||||||
|
package com.simibubi.create.utility;
|
||||||
|
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.BlockRayTraceResult;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraft.util.math.RayTraceContext;
|
||||||
|
import net.minecraft.util.math.RayTraceContext.BlockMode;
|
||||||
|
import net.minecraft.util.math.RayTraceContext.FluidMode;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
public class RaycastHelper {
|
||||||
|
|
||||||
|
public static BlockRayTraceResult rayTraceRange(World worldIn, PlayerEntity playerIn, double range) {
|
||||||
|
Vec3d origin = getTraceOrigin(playerIn);
|
||||||
|
Vec3d target = getTraceTarget(playerIn, range, origin);
|
||||||
|
RayTraceContext context = new RayTraceContext(origin, target, BlockMode.COLLIDER, FluidMode.NONE, playerIn);
|
||||||
|
return worldIn.rayTraceBlocks(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PredicateTraceResult rayTraceUntil(PlayerEntity playerIn, double range, Predicate<BlockPos> predicate) {
|
||||||
|
Vec3d origin = getTraceOrigin(playerIn);
|
||||||
|
Vec3d target = getTraceTarget(playerIn, range, origin);
|
||||||
|
return rayTraceUntil(origin, target, predicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Vec3d getTraceTarget(PlayerEntity playerIn, double range, Vec3d origin) {
|
||||||
|
float f = playerIn.rotationPitch;
|
||||||
|
float f1 = playerIn.rotationYaw;
|
||||||
|
float f2 = MathHelper.cos(-f1 * 0.017453292F - (float) Math.PI);
|
||||||
|
float f3 = MathHelper.sin(-f1 * 0.017453292F - (float) Math.PI);
|
||||||
|
float f4 = -MathHelper.cos(-f * 0.017453292F);
|
||||||
|
float f5 = MathHelper.sin(-f * 0.017453292F);
|
||||||
|
float f6 = f3 * f4;
|
||||||
|
float f7 = f2 * f4;
|
||||||
|
double d3 = range;
|
||||||
|
Vec3d vec3d1 = origin.add((double) f6 * d3, (double) f5 * d3, (double) f7 * d3);
|
||||||
|
return vec3d1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Vec3d getTraceOrigin(PlayerEntity playerIn) {
|
||||||
|
double d0 = playerIn.posX;
|
||||||
|
double d1 = playerIn.posY + (double) playerIn.getEyeHeight();
|
||||||
|
double d2 = playerIn.posZ;
|
||||||
|
Vec3d vec3d = new Vec3d(d0, d1, d2);
|
||||||
|
return vec3d;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static PredicateTraceResult rayTraceUntil(Vec3d start, Vec3d end, Predicate<BlockPos> predicate) {
|
||||||
|
if (Double.isNaN(start.x) || Double.isNaN(start.y) || Double.isNaN(start.z))
|
||||||
|
return null;
|
||||||
|
if (Double.isNaN(end.x) || Double.isNaN(end.y) || Double.isNaN(end.z))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
int dx = MathHelper.floor(end.x);
|
||||||
|
int dy = MathHelper.floor(end.y);
|
||||||
|
int dz = MathHelper.floor(end.z);
|
||||||
|
int x = MathHelper.floor(start.x);
|
||||||
|
int y = MathHelper.floor(start.y);
|
||||||
|
int z = MathHelper.floor(start.z);
|
||||||
|
|
||||||
|
BlockPos currentPos = new BlockPos(x, y, z);
|
||||||
|
|
||||||
|
if (predicate.test(currentPos))
|
||||||
|
return new PredicateTraceResult(currentPos, Direction.getFacingFromVector(dx - x, dy - y, dz - z));
|
||||||
|
|
||||||
|
int remainingDistance = 200;
|
||||||
|
|
||||||
|
while (remainingDistance-- >= 0) {
|
||||||
|
if (Double.isNaN(start.x) || Double.isNaN(start.y) || Double.isNaN(start.z)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x == dx && y == dy && z == dz) {
|
||||||
|
return new PredicateTraceResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean flag2 = true;
|
||||||
|
boolean flag = true;
|
||||||
|
boolean flag1 = true;
|
||||||
|
double d0 = 999.0D;
|
||||||
|
double d1 = 999.0D;
|
||||||
|
double d2 = 999.0D;
|
||||||
|
|
||||||
|
if (dx > x) {
|
||||||
|
d0 = (double) x + 1.0D;
|
||||||
|
} else if (dx < x) {
|
||||||
|
d0 = (double) x + 0.0D;
|
||||||
|
} else {
|
||||||
|
flag2 = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dy > y) {
|
||||||
|
d1 = (double) y + 1.0D;
|
||||||
|
} else if (dy < y) {
|
||||||
|
d1 = (double) y + 0.0D;
|
||||||
|
} else {
|
||||||
|
flag = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dz > z) {
|
||||||
|
d2 = (double) z + 1.0D;
|
||||||
|
} else if (dz < z) {
|
||||||
|
d2 = (double) z + 0.0D;
|
||||||
|
} else {
|
||||||
|
flag1 = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
double d3 = 999.0D;
|
||||||
|
double d4 = 999.0D;
|
||||||
|
double d5 = 999.0D;
|
||||||
|
double d6 = end.x - start.x;
|
||||||
|
double d7 = end.y - start.y;
|
||||||
|
double d8 = end.z - start.z;
|
||||||
|
|
||||||
|
if (flag2) {
|
||||||
|
d3 = (d0 - start.x) / d6;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flag) {
|
||||||
|
d4 = (d1 - start.y) / d7;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flag1) {
|
||||||
|
d5 = (d2 - start.z) / d8;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d3 == -0.0D) {
|
||||||
|
d3 = -1.0E-4D;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d4 == -0.0D) {
|
||||||
|
d4 = -1.0E-4D;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d5 == -0.0D) {
|
||||||
|
d5 = -1.0E-4D;
|
||||||
|
}
|
||||||
|
|
||||||
|
Direction enumfacing;
|
||||||
|
|
||||||
|
if (d3 < d4 && d3 < d5) {
|
||||||
|
enumfacing = dx > x ? Direction.WEST : Direction.EAST;
|
||||||
|
start = new Vec3d(d0, start.y + d7 * d3, start.z + d8 * d3);
|
||||||
|
} else if (d4 < d5) {
|
||||||
|
enumfacing = dy > y ? Direction.DOWN : Direction.UP;
|
||||||
|
start = new Vec3d(start.x + d6 * d4, d1, start.z + d8 * d4);
|
||||||
|
} else {
|
||||||
|
enumfacing = dz > z ? Direction.NORTH : Direction.SOUTH;
|
||||||
|
start = new Vec3d(start.x + d6 * d5, start.y + d7 * d5, d2);
|
||||||
|
}
|
||||||
|
|
||||||
|
x = MathHelper.floor(start.x) - (enumfacing == Direction.EAST ? 1 : 0);
|
||||||
|
y = MathHelper.floor(start.y) - (enumfacing == Direction.UP ? 1 : 0);
|
||||||
|
z = MathHelper.floor(start.z) - (enumfacing == Direction.SOUTH ? 1 : 0);
|
||||||
|
currentPos = new BlockPos(x, y, z);
|
||||||
|
|
||||||
|
if (predicate.test(currentPos))
|
||||||
|
return new PredicateTraceResult(currentPos, enumfacing);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new PredicateTraceResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class PredicateTraceResult {
|
||||||
|
private BlockPos pos;
|
||||||
|
private Direction facing;
|
||||||
|
|
||||||
|
public PredicateTraceResult(BlockPos pos, Direction facing) {
|
||||||
|
this.pos = pos;
|
||||||
|
this.facing = facing;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PredicateTraceResult() {
|
||||||
|
// missed, no result
|
||||||
|
}
|
||||||
|
|
||||||
|
public Direction getFacing() {
|
||||||
|
return facing;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockPos getPos() {
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean missed() {
|
||||||
|
return this.pos == null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.simibubi.create.utility;
|
||||||
|
|
||||||
|
import com.simibubi.create.Create;
|
||||||
|
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
|
||||||
|
public enum TessellatorTextures {
|
||||||
|
|
||||||
|
Room("inner.png"),
|
||||||
|
RoomTransparent("inner_transparent.png"),
|
||||||
|
SelectedRoom("inner_selected.png"),
|
||||||
|
SuperSelectedRoom("inner_super_selected.png"),
|
||||||
|
Selection("select.png"),
|
||||||
|
Exporter("exporter.png"),
|
||||||
|
Trim("trim.png");
|
||||||
|
|
||||||
|
private ResourceLocation location;
|
||||||
|
|
||||||
|
private TessellatorTextures(String filename) {
|
||||||
|
location = new ResourceLocation(Create.ID,
|
||||||
|
"textures/block/marker/" + filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bind() {
|
||||||
|
Minecraft.getInstance().getTextureManager().bindTexture(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,8 +1,9 @@
|
||||||
{
|
{
|
||||||
"item.create.symmetry_wand": "Staff of Symmetry",
|
"item.create.symmetry_wand": "Staff of Symmetry",
|
||||||
"item.create.empty_blueprint": "Empty Blueprint",
|
"item.create.empty_blueprint": "Empty Schematic",
|
||||||
"item.create.blueprint": "Blueprint",
|
"item.create.blueprint": "Schematic",
|
||||||
"block.create.schematicannon": "SchematiCannon 9000",
|
"block.create.schematicannon": "SchematiCannon 9000",
|
||||||
"block.create.schematic_table": "Schematic Planner",
|
"block.create.schematic_table": "Schematic Table",
|
||||||
|
"block.create.creative_crate": "SchematiCannon Creatifier",
|
||||||
"itemGroup.create": "Create"
|
"itemGroup.create": "Create"
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.4 KiB |
Loading…
Reference in a new issue