diff --git a/dependencies.gradle b/dependencies.gradle index 6fdbc82e5e..c20289b11a 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -5,8 +5,13 @@ dependencies { api('com.github.GTNewHorizons:GTNHLib:0.6.30:dev') compileOnly('com.github.GTNewHorizons:BuildCraft:7.1.43:api') {transitive=false} - compileOnly('com.github.GTNewHorizons:ForgeMultipart:1.6.4:dev') {transitive=false} - devOnlyNonPublishable('com.github.GTNewHorizons:NotEnoughItems:2.7.51-GTNH:dev') + compileOnly('com.github.GTNewHorizons:ModularUI2:2.2.15-1.7.10:dev') +// devOnlyNonPublishable('com.github.GTNewHorizons:ModularUI2:2.2.15-1.7.10:dev') + compileOnly('com.github.GTNewHorizons:BuildCraft:7.1.43:api') {transitive=false} + compileOnly('com.github.GTNewHorizons:ForgeMultipart:1.6.6:dev') {transitive=false} + + devOnlyNonPublishable('com.github.GTNewHorizons:NotEnoughItems:2.7.52-GTNH:dev') + compileOnly('com.github.GTNewHorizons:Railcraft:9.16.30:api') {transitive=false} compileOnly('com.github.GTNewHorizons:StorageDrawers:2.1.2-GTNH:api') {transitive=false} compileOnly('curse.maven:cofh-lib-220333:2388748') diff --git a/src/main/java/vazkii/botania/client/core/handler/KeyHandler.java b/src/main/java/vazkii/botania/client/core/handler/KeyHandler.java index b0e6a86bd4..7295290a77 100644 --- a/src/main/java/vazkii/botania/client/core/handler/KeyHandler.java +++ b/src/main/java/vazkii/botania/client/core/handler/KeyHandler.java @@ -1,28 +1,37 @@ package vazkii.botania.client.core.handler; -import net.minecraft.client.settings.KeyBinding; -import vazkii.botania.common.network.PacketHandler; -import vazkii.botania.common.network.PacketLokiClear; -import vazkii.botania.common.network.PacketLokiMirror; -import vazkii.botania.common.network.PacketLokiToggle; import cpw.mods.fml.client.registry.ClientRegistry; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.eventhandler.SubscribeEvent; import cpw.mods.fml.common.gameevent.InputEvent; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.client.Minecraft; +import net.minecraft.client.settings.KeyBinding; +import net.minecraft.item.ItemStack; +import vazkii.botania.client.gui.loki.GuiLokiSchematics; +import vazkii.botania.common.item.relic.ItemLokiRing; +import vazkii.botania.common.network.PacketHandler; +import vazkii.botania.common.network.PacketLokiClear; +import vazkii.botania.common.network.PacketLokiMirror; +import vazkii.botania.common.network.PacketLokiSaveSchematic; +import vazkii.botania.common.network.PacketLokiToggle; public class KeyHandler { private static final KeyBinding keyToggleRingOfLoki= new KeyBinding("botaniamisc.toggleLoki", 0, "botaniamisc.keyCategory"); private static final KeyBinding keyRingOfLokiClear= new KeyBinding("botaniamisc.ringOfLokiClear", 0, "botaniamisc.keyCategory"); private static final KeyBinding keyRingOfLokiMirror= new KeyBinding("botaniamisc.ringOfLokiMirror", 0, "botaniamisc.keyCategory"); + private static final KeyBinding keyRingOfLokiSaveSchematic= new KeyBinding("botaniamisc.ringOfLokiSaveSchematic", 0, "botaniamisc.keyCategory"); + private static final KeyBinding keyRingOfLokiOpenUI= new KeyBinding("botaniamisc.ringOfLokiOpenUI", 0, "botaniamisc.keyCategory"); public KeyHandler() { FMLCommonHandler.instance().bus().register(this); ClientRegistry.registerKeyBinding(keyToggleRingOfLoki); ClientRegistry.registerKeyBinding(keyRingOfLokiClear); ClientRegistry.registerKeyBinding(keyRingOfLokiMirror); + ClientRegistry.registerKeyBinding(keyRingOfLokiSaveSchematic); + ClientRegistry.registerKeyBinding(keyRingOfLokiOpenUI); } @SideOnly(Side.CLIENT) @@ -37,16 +46,32 @@ public void key(InputEvent.KeyInputEvent event){ if(keyRingOfLokiMirror.isPressed()){ toggleRingLokiMirroring(); } + if(keyRingOfLokiSaveSchematic.isPressed()){ + ringOfLokiSaveSchematic(); + } + if(keyRingOfLokiOpenUI.isPressed()) { + ringOfLokiOpenUI(); + } } + private static void toggleRingLoki() { PacketHandler.INSTANCE.sendToServer(new PacketLokiToggle()); } - private static void ringOfLokiClear() { PacketHandler.INSTANCE.sendToServer(new PacketLokiClear()); } private static void toggleRingLokiMirroring() { PacketHandler.INSTANCE.sendToServer(new PacketLokiMirror()); } + private static void ringOfLokiSaveSchematic() { + PacketHandler.INSTANCE.sendToServer(new PacketLokiSaveSchematic()); + } + private static void ringOfLokiOpenUI() { + if(ItemLokiRing.isModularUIEnabled) { + ItemStack ring = ItemLokiRing.getLokiRing(Minecraft.getMinecraft().thePlayer); + if(ring != null) + GuiLokiSchematics.open(ring); + } + } } diff --git a/src/main/java/vazkii/botania/client/gui/loki/GuiLokiSchematics.java b/src/main/java/vazkii/botania/client/gui/loki/GuiLokiSchematics.java new file mode 100644 index 0000000000..c2e9aad86b --- /dev/null +++ b/src/main/java/vazkii/botania/client/gui/loki/GuiLokiSchematics.java @@ -0,0 +1,146 @@ +package vazkii.botania.client.gui.loki; + +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.drawable.Rectangle; +import com.cleanroommc.modularui.factory.ClientGUI; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.screen.ModularScreen; +import com.cleanroommc.modularui.screen.RichTooltip; +import com.cleanroommc.modularui.utils.Alignment; +import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.widget.ParentWidget; +import com.cleanroommc.modularui.widget.ScrollWidget; +import com.cleanroommc.modularui.widget.scroll.ScrollArea; +import com.cleanroommc.modularui.widget.scroll.VerticalScrollData; +import com.cleanroommc.modularui.widgets.ButtonWidget; +import com.cleanroommc.modularui.widgets.TextWidget; +import com.cleanroommc.modularui.widgets.layout.Flow; +import com.cleanroommc.modularui.widgets.layout.Row; +import net.minecraft.item.ItemStack; +import net.minecraft.util.StatCollector; +import vazkii.botania.client.gui.mui2.Textures; +import vazkii.botania.common.item.relic.ItemLokiRing; +import vazkii.botania.common.network.PacketHandler; +import vazkii.botania.common.network.PacketLokiChangeSchematic; +import vazkii.botania.common.network.PacketLokiDeleteSchematic; + +import java.util.ArrayList; + +public class GuiLokiSchematics { + + private static final int WINDOW_WIDTH = 350, WINDOW_HEIGHT = 225, SCROLL_AREA_WIDTH = 350, SCROLL_AREA_HEIGHT = 200, SAVED_SCHEMATICS_HEADER_HEIGHT = 25, X_PADDING = 5, Y_PADDING = 5; + private ArrayList schematicNames; + + public static void open(ItemStack ring) { + ClientGUI.open(new ModularScreen(new GuiLokiSchematics().buildUI(ring))); + } + + private String selectedSchematic; + + private GuiLokiSchematics() { + } + + public ModularPanel buildUI(ItemStack itemStack) { + if (! ItemLokiRing.isLokiRing(itemStack)) { + return null; + } + + selectedSchematic = ItemLokiRing.getSelectedSchematic(itemStack); + schematicNames = new ArrayList<>(ItemLokiRing.getSchematicNames(itemStack)); + + final ScrollWidget scrollWidget = new ScrollWidget<>(new VerticalScrollData()); + setScrollArea(scrollWidget.getScrollArea()); + for (int i = 0; i < schematicNames.size(); i++) { + // Final value that can be captured by lambdas + final int rowId = i; + Flow row = new Row(); + row.sizeRel(1f, 0.2f) + .pos(0, rowId * (SCROLL_AREA_HEIGHT / 5 + 1)) + .padding(5, 0, 5, 5) + .setEnabledIf((w) -> rowId < schematicNames.size()) + .background(new Rectangle() + .setColor(i % 2 == 0 ? Color.ORANGE.brighter(3) : Color.ORANGE.brighter(2))) + .child( + new TextWidget(IKey.dynamic(()-> rowId < schematicNames.size() ? schematicNames.get(rowId) : "")) + .widthRel(0.72f)) + .child( + new ParentWidget<>() + .tooltip(new RichTooltip() + .add("Activate Schematic")) + .widthRel(0.083f) + .heightRel(1f) + .setEnabledIf((w) -> rowId < schematicNames.size() && !schematicNames.get(rowId).equals(selectedSchematic)) + .child( + new ButtonWidget<>() + .onMousePressed(ignored -> { + String key = schematicNames.get(rowId); + PacketHandler.INSTANCE.sendToServer(new PacketLokiChangeSchematic(key)); + selectedSchematic = key; + return true; + }) + .background(Textures.CHECK_ICON) + .hoverBackground(Textures.CHECK_ICON) + .size(20, 20) + .center())) + .child( + new ParentWidget<>() + .widthRel(0.083f) + .heightRel(1f) + .child( + new ButtonWidget<>() + .tooltip(new RichTooltip() + .add("Rename Schematic")) + .onMousePressed(ignored -> { + ClientGUI.open(new RenameGui(schematicNames.get(rowId))); + return true; + }) + .background(Textures.RENAME_ICON) + .hoverBackground(Textures.RENAME_ICON) + .size(20, 20) + .center())) + .child( + new ParentWidget<>() + .widthRel(0.083f) + .heightRel(1f) + .child( + new ButtonWidget<>() + .tooltip(new RichTooltip() + .add("Delete Schematic")) + .onMousePressed(ignored -> { + String key = schematicNames.get(rowId); + PacketHandler.INSTANCE.sendToServer(new PacketLokiDeleteSchematic(key)); + schematicNames.remove(rowId); + setScrollArea(scrollWidget.getScrollArea()); + if(key.equals(selectedSchematic)) + selectedSchematic = null; + return true; + }) + .background(Textures.DELETE_ICON) + .hoverBackground(Textures.DELETE_ICON) + .size(20, 20) + .center())); + scrollWidget.child( + row); + } + + return ModularPanel.defaultPanel("lokiSchematics") + .child( + new TextWidget(IKey.dynamic(() -> selectedSchematic == null ? StatCollector.translateToLocal("botaniamisc.select_schematic") : StatCollector.translateToLocal("botaniamisc.selected_schematic") + " " + selectedSchematic)) + .align(Alignment.TopCenter) + .marginTop(8) + .scale(0.5f)) + .child( + scrollWidget + .pos(10, 20) + .widthRel(SCROLL_AREA_WIDTH - 20) + .margin(10, 0) + .height(SCROLL_AREA_HEIGHT - 10)) + .background(Textures.BACKGROUND_TEXTURE) + .size(WINDOW_WIDTH, WINDOW_HEIGHT); + } + + private void setScrollArea(ScrollArea scrollWidget) { + scrollWidget.getScrollY().setScrollSize(schematicNames.size() * (SCROLL_AREA_HEIGHT / 5 + 1)); + } + +} diff --git a/src/main/java/vazkii/botania/client/gui/loki/RenameGui.java b/src/main/java/vazkii/botania/client/gui/loki/RenameGui.java new file mode 100644 index 0000000000..1e80c75243 --- /dev/null +++ b/src/main/java/vazkii/botania/client/gui/loki/RenameGui.java @@ -0,0 +1,80 @@ +package vazkii.botania.client.gui.loki; + +import com.cleanroommc.modularui.api.value.IStringValue; +import com.cleanroommc.modularui.screen.CustomModularScreen; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.screen.viewport.ModularGuiContext; +import com.cleanroommc.modularui.value.sync.InteractionSyncHandler; +import com.cleanroommc.modularui.widgets.TextWidget; +import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; +import vazkii.botania.client.gui.mui2.Textures; +import vazkii.botania.common.network.PacketHandler; +import vazkii.botania.common.network.PacketLokiRenameSchematic; + +class RenameGui extends CustomModularScreen { + + private final String schematicToBeRenamed; + + public RenameGui(String schematicToBeRenamed) { + this.schematicToBeRenamed = schematicToBeRenamed; + } + + private String newValue = ""; + + @Override + public void close() { + close(false); + } + + @Override + public void close(boolean force) { + super.close(force); + this.persist(); + } + + public void persist() { + PacketHandler.INSTANCE.sendToServer(new PacketLokiRenameSchematic(schematicToBeRenamed, newValue)); + } + + @Override + public ModularPanel buildUI(ModularGuiContext context) { + + InteractionSyncHandler handler = new InteractionSyncHandler(); + + handler.setOnKeyPressed((key) -> { + System.out.println(key.character); + }); + + return ModularPanel.defaultPanel("rename") + .child(new TextWidget("Schematic Name:") + .pos(10, 10) + .size(180, 20)) + .child(new TextFieldWidget() + .value(new IStringValue() { + @Override + public String getStringValue() { + return newValue; + } + + @Override + public void setStringValue(String val) { + newValue = val; + } + + @Override + public String getValue() { + return newValue; + } + + @Override + public void setValue(String value) { + newValue = value; + } + }) + .disableHoverBackground() + .size(150, 20) + .pos(25, 40)) + .background(Textures.BACKGROUND_TEXTURE) + .size(200, 100); + } +} diff --git a/src/main/java/vazkii/botania/client/gui/mui2/Textures.java b/src/main/java/vazkii/botania/client/gui/mui2/Textures.java new file mode 100644 index 0000000000..31e3bf9624 --- /dev/null +++ b/src/main/java/vazkii/botania/client/gui/mui2/Textures.java @@ -0,0 +1,28 @@ +package vazkii.botania.client.gui.mui2; + +import com.cleanroommc.modularui.drawable.AdaptableUITexture; +import com.cleanroommc.modularui.drawable.UITexture; + +public class Textures { + public static final UITexture BACKGROUND_TEXTURE = AdaptableUITexture + .builder() + .location("botania:textures/gui/croppedPaper") + .imageSize(330, 252) + .adaptable(12) + .build(); + public static final UITexture CHECK_ICON = UITexture + .builder() + .location("botania:textures/gui/check") + .imageSize(20, 20) + .build(); + public static final UITexture DELETE_ICON = UITexture + .builder() + .location("botania:textures/gui/delete") + .imageSize(20, 20) + .build(); + public static final UITexture RENAME_ICON = UITexture + .builder() + .location("botania:textures/gui/rename") + .imageSize(20, 20) + .build(); +} diff --git a/src/main/java/vazkii/botania/common/item/relic/ItemLokiRing.java b/src/main/java/vazkii/botania/common/item/relic/ItemLokiRing.java index 0608446c24..e909f55ebb 100644 --- a/src/main/java/vazkii/botania/common/item/relic/ItemLokiRing.java +++ b/src/main/java/vazkii/botania/common/item/relic/ItemLokiRing.java @@ -11,10 +11,16 @@ package vazkii.botania.common.item.relic; -import java.awt.Color; -import java.util.ArrayList; -import java.util.List; +import baubles.api.BaubleType; +import baubles.common.container.InventoryBaubles; +import baubles.common.lib.PlayerHandler; +import baubles.common.network.PacketSyncBauble; import com.gtnewhorizon.gtnhlib.GTNHLib; +import cpw.mods.fml.common.Loader; +import cpw.mods.fml.common.Optional; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.client.Minecraft; @@ -27,8 +33,9 @@ import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTTagCompound; - +import net.minecraft.nbt.NBTTagString; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.ChunkCoordinates; import net.minecraft.util.EnumChatFormatting; @@ -52,18 +59,19 @@ import vazkii.botania.common.item.ModItems; import vazkii.botania.common.item.equipment.tool.ToolCommons; import vazkii.botania.common.lib.LibItemNames; -import baubles.api.BaubleType; -import baubles.common.container.InventoryBaubles; -import baubles.common.lib.PlayerHandler; -import baubles.common.network.PacketSyncBauble; -import cpw.mods.fml.common.eventhandler.SubscribeEvent; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; import vazkii.botania.common.network.PacketLokiHudNotificationAck; +import java.awt.Color; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; public class ItemLokiRing extends ItemRelicBauble implements IExtendedWireframeCoordinateListProvider, IManaUsingItem, IInWorldRenderable { + public static final boolean isModularUIEnabled = Loader.isModLoaded("modularui2"); + private static final String TAG_CURSOR_LIST = "cursorList"; private static final String TAG_CURSOR_PREFIX = "cursor"; private static final String TAG_CURSOR_COUNT = "cursorCount"; @@ -73,15 +81,199 @@ public class ItemLokiRing extends ItemRelicBauble implements IExtendedWireframeC private static final String TAG_MODE = "mode"; private static final String TAG_BREAKING_MODE = "breaking"; private static final String TAG_MIRROR_MODE = "mirror"; + private static final String TAG_SAVED_SCHEMATICS = "savedSchematics"; + private static final String TAG_CURRENT_SCHEMATIC = "currentSchematic"; private boolean recursion = false; - public static enum HUD_MESSAGE { - MODE, BREAKING, CLEAR, MIRROR, INSUFFICIENT_MANA + public enum HUD_MESSAGE { + MODE, BREAKING, CLEAR, MIRROR, INSUFFICIENT_MANA, SCHEMATIC_SAVED } public ItemLokiRing() { super(LibItemNames.LOKI_RING); - MinecraftForge.EVENT_BUS.register(new EventHandler()); + MinecraftForge.EVENT_BUS.register(this); + } + + @SubscribeEvent + public void onBlockBreak(BlockEvent.BreakEvent event) { + EntityPlayer player = event.getPlayer(); + int x = event.x; + int y = event.y; + int z = event.z; + int side = event.blockMetadata; + ItemStack stack = player.getCurrentEquippedItem(); + if(stack == null) return; + Item item = player.getCurrentEquippedItem().getItem(); + breakOnAllCursors(player, item, stack, x, y, z, side); + } + + + @SubscribeEvent + public void onPlayerInteract(PlayerInteractEvent event) { + if(recursion) return; + + EntityPlayer player = event.entityPlayer; + ItemStack lokiRing = getLokiRing(player); + if (lokiRing == null || player.worldObj.isRemote) + return; + + ItemStack heldItemStack = player.getCurrentEquippedItem(); + ChunkCoordinates originCoords = getOriginPos(lokiRing); + MovingObjectPosition lookPos = ToolCommons.raytraceFromEntity(player.worldObj, player, true, 10F); + List cursors = getCursorList(lokiRing); + int cursorCount = cursors.size(); + //I don`t think mana for placing should be cruel , so I just made graph with funny line + int cost = (int)(50*Math.sin(0.04* cursorCount)+cursorCount+120+20*Math.cos(0.2*cursorCount)); + + if (heldItemStack == null && event.action == Action.RIGHT_CLICK_BLOCK && player.isSneaking() && isRingEnabled(lokiRing)) { + if(originCoords.posY == -1 && lookPos != null) { + setOriginPos(lokiRing, lookPos.blockX, lookPos.blockY, lookPos.blockZ); + if(player instanceof EntityPlayerMP) + syncLokiRing(player); + } else if(lookPos != null) { + if(originCoords.posX == lookPos.blockX && originCoords.posY == lookPos.blockY && originCoords.posZ == lookPos.blockZ) { + clearMasterCursor(lokiRing); + if(player instanceof EntityPlayerMP) + syncLokiRing(player); + } else { + addCursor : { + int relX = lookPos.blockX - originCoords.posX; + int relY = lookPos.blockY - originCoords.posY; + int relZ = lookPos.blockZ - originCoords.posZ; + + for(LokiCursor cursor : cursors) + if(cursor.getX() == relX && cursor.getY() == relY && cursor.getZ() == relZ) { + cursors.remove(cursor); + setCursorList(lokiRing, cursors); + if(player instanceof EntityPlayerMP) + syncLokiRing(player); + break addCursor; + } + + addCursor(lokiRing, relX, relY, relZ, getRingMirrorMode(lokiRing) ); + if(player instanceof EntityPlayerMP) + syncLokiRing(player); + } + } + } + } else if (heldItemStack != null && event.action == Action.RIGHT_CLICK_BLOCK && lookPos != null && isRingEnabled(lokiRing)) { + if(!ManaItemHandler.requestManaExact(lokiRing, player, cost, true)){ + if(player instanceof EntityPlayerMP){ + vazkii.botania.common.network.PacketHandler.INSTANCE.sendTo(new PacketLokiHudNotificationAck(HUD_MESSAGE.INSUFFICIENT_MANA),(EntityPlayerMP) player); + } + else + { + renderHUDNotification(HUD_MESSAGE.INSUFFICIENT_MANA); + } + return; + } + + recursion = true; + + double oldPosX = player.posX; + double oldPosY = player.posY; + double oldPosZ = player.posZ; + float oldPitch = player.rotationPitch; + float oldYaw = player.rotationYaw; + + int masterOffsetX = originCoords.posY == -1 ? 0 :lookPos.blockX - originCoords.posX; + int masterOffsetY = originCoords.posY == -1 ? 0 :lookPos.blockY - originCoords.posY; + int masterOffsetZ = originCoords.posY == -1 ? 0 :lookPos.blockZ - originCoords.posZ; + + double playerOffsetX = player.posX - originCoords.posX; + double playerOffsetY = player.posY - originCoords.posY; + double playerOffsetZ = player.posZ - originCoords.posZ; + + for(LokiCursor cursor : cursors) { + + int x = lookPos.blockX + cursor.getX(); + int y = lookPos.blockY + cursor.getY(); + int z = lookPos.blockZ + cursor.getZ(); + + if(cursor.isMirrorX()){ + x -= 2*masterOffsetX; + } + if(cursor.isMirrorY()){ + y -= 2*masterOffsetY; + } + if(cursor.isMirrorZ()){ + z -= 2*masterOffsetZ; + } + + if (player.worldObj.isAirBlock(x, y, z) ) { + continue; + } + + player.posX = cursor.getX()+oldPosX; + player.posY = cursor.getY()+oldPosY; + player.posZ = cursor.getZ()+oldPosZ; + player.rotationYaw = oldYaw; + + if(cursor.isMirrorX()){ + player.posX -= 2*playerOffsetX; + player.rotationYaw = player.rotationYaw * (-1); + } + if(cursor.isMirrorY()){ + player.posY -= 2*playerOffsetY; + player.rotationPitch = oldPitch * (-1); + } + if(cursor.isMirrorZ()){ + player.posZ -= 2*playerOffsetZ; + player.rotationYaw = 180 - (Math.abs(player.rotationYaw)); + if(oldYaw < 0){ + player.rotationYaw *= -1; + } + } + + float hitX = (float) (lookPos.hitVec.xCoord - lookPos.blockX); + float hitY = (float) (lookPos.hitVec.yCoord - lookPos.blockY); + float hitZ = (float) (lookPos.hitVec.zCoord - lookPos.blockZ); + if(cursor.isMirrorX()){ + hitX = 1-hitX; + } + if(cursor.isMirrorY()){ + hitY = 1-hitY; + } + if(cursor.isMirrorZ()){ + hitZ = 1-hitZ; + } + + int hitSide = lookPos.sideHit; + if(cursor.isMirrorX() && (hitSide == ForgeDirection.EAST.ordinal() || hitSide == ForgeDirection.WEST.ordinal()) ){ + hitSide = hitSide ^ 1; + } + if(cursor.isMirrorY() && (hitSide == ForgeDirection.DOWN.ordinal() || hitSide == ForgeDirection.UP.ordinal()) ){ + hitSide = hitSide ^ 1; + } + if(cursor.isMirrorZ() && (hitSide == ForgeDirection.NORTH.ordinal() || hitSide == ForgeDirection.SOUTH.ordinal()) ){ + hitSide = hitSide ^ 1; + } + + Item item = heldItemStack.getItem(); + Block markedBlock = player.worldObj.getBlock(x, y, z); + + boolean wasActivated = markedBlock.onBlockActivated(player.worldObj, x, y, z, player, hitSide, hitX,hitY,hitZ); + + if (heldItemStack.stackSize == 0 ) { + event.setCanceled(true); + break; + } + if (!wasActivated) { + item.onItemUse(player.capabilities.isCreativeMode ? heldItemStack.copy() : heldItemStack, player, player.worldObj, x, y, z, hitSide, (float) lookPos.hitVec.xCoord - x, (float) lookPos.hitVec.yCoord - y, (float) lookPos.hitVec.zCoord - z); + if(heldItemStack.stackSize == 0) { + event.setCanceled(true); + break; + } + } + + } + recursion = false; + player.posX = oldPosX; + player.posY = oldPosY; + player.posZ = oldPosZ; + player.rotationPitch = oldPitch; + player.rotationYaw = oldYaw; + } } public static void setMode(ItemStack stack, boolean state) { @@ -96,6 +288,94 @@ public static void setMirrorMode (ItemStack stack, byte state) { stack.stackTagCompound.setByte(TAG_MIRROR_MODE, state); } + public static String getSelectedSchematic(ItemStack itemStack) { + return itemStack.getTagCompound().getString(TAG_CURRENT_SCHEMATIC); + } + + @SuppressWarnings("unchecked") + public static List getSchematicNames(ItemStack stack) { + Set schematicNames = stack.getTagCompound().getCompoundTag(ItemLokiRing.TAG_SAVED_SCHEMATICS).func_150296_c(); + return schematicNames.stream().sorted(Comparator.comparing(Object::toString)).collect(Collectors.toList()); + } + + public static void saveCurrentSelectionAsSchematic(ItemStack stack) { + if(!stack.getTagCompound().tagMap.containsKey(TAG_SAVED_SCHEMATICS)) { + stack.getTagCompound().setTag(TAG_SAVED_SCHEMATICS, new NBTTagCompound()); + } + NBTTagCompound map = (NBTTagCompound) stack.getTagCompound().getTag(TAG_SAVED_SCHEMATICS); + NBTTagCompound currentState = new NBTTagCompound(); + for(String s : new String[]{ + TAG_CURSOR_LIST, + TAG_CURSOR_PREFIX, + TAG_CURSOR_COUNT, + TAG_X_ORIGIN, + TAG_Y_ORIGIN, + TAG_Z_ORIGIN, + TAG_BREAKING_MODE, + TAG_MIRROR_MODE + }) { + if(stack.getTagCompound().getTag(s) != null) + currentState.setTag(s, stack.getTagCompound().getTag(s)); + } + String newSchematicName = "New Schematic"; + int idx = 1; + if(map.hasKey(newSchematicName)) { + do { + newSchematicName = "New Schematic (" + idx + ")"; + idx++; + } while (map.hasKey(newSchematicName)); + } + map.setTag(newSchematicName, currentState); + stack.getTagCompound().setTag(TAG_CURRENT_SCHEMATIC, new NBTTagString(newSchematicName)); + } + + public static void changeSchematic(ItemStack stack, String schematicName) { + if(!stack.getTagCompound().tagMap.containsKey(TAG_SAVED_SCHEMATICS)) { + return; + } + NBTTagCompound map = (NBTTagCompound) stack.getTagCompound().getTag(TAG_SAVED_SCHEMATICS); + if(!map.tagMap.containsKey(schematicName)) { + return; + } + NBTTagCompound schematic = (NBTTagCompound) map.getTag(schematicName); + for(String s : new String[]{ + TAG_CURSOR_LIST, + TAG_CURSOR_PREFIX, + TAG_CURSOR_COUNT, + TAG_X_ORIGIN, + TAG_Y_ORIGIN, + TAG_Z_ORIGIN, + TAG_BREAKING_MODE, + TAG_MIRROR_MODE + }) { + if(schematic.getTag(s) != null) { + stack.getTagCompound().setTag(s, schematic.getTag(s)); + } + } + stack.getTagCompound().setTag(TAG_CURRENT_SCHEMATIC, new NBTTagString(schematicName)); + } + + public static void renameSchematic(ItemStack lokiStack, String schematicToBeRenamed, String newName) { + if (lokiStack.getTagCompound().getString(ItemLokiRing.TAG_CURRENT_SCHEMATIC).equals(schematicToBeRenamed)) { + lokiStack.getTagCompound().setString(ItemLokiRing.TAG_CURRENT_SCHEMATIC, newName); + } + NBTBase nbt = lokiStack.getTagCompound().getCompoundTag(ItemLokiRing.TAG_SAVED_SCHEMATICS).getTag(schematicToBeRenamed.toString()); + lokiStack.getTagCompound().getCompoundTag(ItemLokiRing.TAG_SAVED_SCHEMATICS).removeTag(schematicToBeRenamed.toString()); + lokiStack.getTagCompound().getCompoundTag(ItemLokiRing.TAG_SAVED_SCHEMATICS).setTag(newName, nbt); + } + + @Optional.Method(modid = "modularui2") + public static void deleteSchematic(ItemStack lokiStack, String schematicName) { + NBTTagCompound map = lokiStack.getTagCompound().getCompoundTag(TAG_SAVED_SCHEMATICS); + if(map != null) { + if(map.hasKey(schematicName)) { + map.removeTag(schematicName); + } + } + if(schematicName.equals(lokiStack.getTagCompound().getString(TAG_CURRENT_SCHEMATIC))) { + lokiStack.getTagCompound().removeTag(TAG_CURRENT_SCHEMATIC); + } + } @SideOnly(Side.CLIENT) public static void renderHUDNotification(HUD_MESSAGE type){ @@ -109,7 +389,7 @@ public static void renderHUDNotification(HUD_MESSAGE type){ text = getLokiBreakingModeText(getLokiRing(mc.thePlayer)); break; case CLEAR: - text = getLokiCearText(getLokiRing(mc.thePlayer)); + text = getLokiClearText(); break; case MIRROR: text = getLokiMirrorText(getLokiRing(mc.thePlayer)); @@ -117,6 +397,9 @@ public static void renderHUDNotification(HUD_MESSAGE type){ case INSUFFICIENT_MANA: text = EnumChatFormatting.RED + StatCollector.translateToLocal("botaniamisc.insufficient_mana"); break; + case SCHEMATIC_SAVED: + text = EnumChatFormatting.GREEN + StatCollector.translateToLocal("botaniamisc.schematic_saved"); + break; default: return; @@ -147,7 +430,7 @@ public static String getLokiMirrorText(ItemStack stack){ getAxisString(getRingMirrorMode(stack)); } - public static String getLokiCearText(ItemStack stack){ + public static String getLokiClearText(){ return EnumChatFormatting.GOLD + StatCollector.translateToLocal("botaniamisc.lokiClear"); } @@ -263,7 +546,7 @@ public void addInformation(ItemStack stack, EntityPlayer player, List list, bool addStringToTooltip(StatCollector.translateToLocal("botaniamisc.lokiMirror") + getAxisString(getRingMirrorMode(stack)), list); addStringToTooltip("", list); addStringToTooltip(StatCollector.translateToLocal("botaniamisc.lokiToggleDescription") + " " + getOnOffString(true) + EnumChatFormatting.RESET + "/"+ getOnOffString(false), list); - addStringToTooltip(StatCollector.translateToLocal("botaniamisc.lokiBreakingDescription") + " " + getOnOffString(true) + EnumChatFormatting.RESET+"/" + getOnOffString(false), list); + addStringToTooltip(StatCollector.translateToLocal("botaniamisc.lokiBreakingDescription") + " " + getOnOffString(true) + EnumChatFormatting.RESET+"/" + getOnOffString(false), list); super.addInformation(stack, player, list, adv); } @@ -334,7 +617,7 @@ public static void syncLokiRing(EntityPlayer player){ baubles.common.network.PacketHandler.INSTANCE.sendTo(new PacketSyncBauble(player, getLokiRingSlot(player)), (EntityPlayerMP) player); } - private static boolean isLokiRing(ItemStack stack) { + public static boolean isLokiRing(ItemStack stack) { return stack != null && (stack.getItem() == ModItems.lokiRing || stack.getItem() == ModItems.aesirRing); } diff --git a/src/main/java/vazkii/botania/common/network/GuiHandler.java b/src/main/java/vazkii/botania/common/network/GuiHandler.java index 1d08bad859..d292e8c3a5 100644 --- a/src/main/java/vazkii/botania/common/network/GuiHandler.java +++ b/src/main/java/vazkii/botania/common/network/GuiHandler.java @@ -45,17 +45,17 @@ public Object getServerGuiElement(int ID, EntityPlayer player, World world, int @Override public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { switch(ID) { - case LibGuiIDs.LEXICON : - GuiLexicon lex = GuiLexicon.currentOpenLexicon; - return lex; - case LibGuiIDs.CRAFTING_HALO : - return new GuiCraftingHalo(player.inventory, world); - case LibGuiIDs.FLOWER_BAG : - return new GuiFlowerBag(player); - case LibGuiIDs.SHROOM_BAG: - return new GuiShroomBag(player); - case LibGuiIDs.BAUBLE_BOX : - return new GuiBaubleBox(player); + case LibGuiIDs.LEXICON : + GuiLexicon lex = GuiLexicon.currentOpenLexicon; + return lex; + case LibGuiIDs.CRAFTING_HALO : + return new GuiCraftingHalo(player.inventory, world); + case LibGuiIDs.FLOWER_BAG : + return new GuiFlowerBag(player); + case LibGuiIDs.SHROOM_BAG: + return new GuiShroomBag(player); + case LibGuiIDs.BAUBLE_BOX : + return new GuiBaubleBox(player); } return null; diff --git a/src/main/java/vazkii/botania/common/network/PacketHandler.java b/src/main/java/vazkii/botania/common/network/PacketHandler.java index 9352cb8b13..23344a2432 100644 --- a/src/main/java/vazkii/botania/common/network/PacketHandler.java +++ b/src/main/java/vazkii/botania/common/network/PacketHandler.java @@ -1,9 +1,9 @@ package vazkii.botania.common.network; -import vazkii.botania.common.lib.LibMisc; import cpw.mods.fml.common.network.NetworkRegistry; import cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper; import cpw.mods.fml.relauncher.Side; +import vazkii.botania.common.lib.LibMisc; public class PacketHandler { @@ -16,6 +16,10 @@ public static void initPackets() { INSTANCE.registerMessage(PacketLokiToggle.class, PacketLokiToggle.class, 1, Side.SERVER); INSTANCE.registerMessage(PacketLokiClear.class, PacketLokiClear.class, 2, Side.SERVER); INSTANCE.registerMessage(PacketLokiMirror.class, PacketLokiMirror.class, 3, Side.SERVER); - INSTANCE.registerMessage(PacketLokiHudNotificationAck.class, PacketLokiHudNotificationAck.class, 4, Side.CLIENT); + INSTANCE.registerMessage(PacketLokiSaveSchematic.class, PacketLokiSaveSchematic.class, 4, Side.SERVER); + INSTANCE.registerMessage(PacketLokiChangeSchematic.class, PacketLokiChangeSchematic.class, 5, Side.SERVER); + INSTANCE.registerMessage(PacketLokiDeleteSchematic.class, PacketLokiDeleteSchematic.class, 6, Side.SERVER); + INSTANCE.registerMessage(PacketLokiRenameSchematic.class, PacketLokiRenameSchematic.class, 7, Side.SERVER); + INSTANCE.registerMessage(PacketLokiHudNotificationAck.class, PacketLokiHudNotificationAck.class, 8, Side.CLIENT); } } diff --git a/src/main/java/vazkii/botania/common/network/PacketLokiChangeSchematic.java b/src/main/java/vazkii/botania/common/network/PacketLokiChangeSchematic.java new file mode 100644 index 0000000000..b19f0e3d1f --- /dev/null +++ b/src/main/java/vazkii/botania/common/network/PacketLokiChangeSchematic.java @@ -0,0 +1,48 @@ +package vazkii.botania.common.network; + +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; +import cpw.mods.fml.common.network.simpleimpl.MessageContext; +import io.netty.buffer.ByteBuf; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import vazkii.botania.common.item.relic.ItemLokiRing; + +public class PacketLokiChangeSchematic implements IMessage, IMessageHandler { + + private String schematicName; + + public PacketLokiChangeSchematic() { + } + + public PacketLokiChangeSchematic(String schematicName) { + this.schematicName = schematicName; + } + + @Override + public void fromBytes(ByteBuf buf) { + int schematicNameLength = buf.readInt(); + this.schematicName = new String(buf.readBytes(schematicNameLength).array()); + if(schematicName.equals("null")) { + schematicName = null; + } + } + + @Override + public void toBytes(ByteBuf buf) { + schematicName = schematicName == null ? "null" : schematicName; + buf.writeInt(schematicName.length()); + buf.writeBytes(schematicName.getBytes()); + } + + @Override + public IMessage onMessage(PacketLokiChangeSchematic message, MessageContext ctx) { + EntityPlayerMP player = ctx.getServerHandler().playerEntity; + ItemStack lokiStack = ItemLokiRing.getLokiRing(player); + if(lokiStack != null && lokiStack.getItem() instanceof ItemLokiRing) { + ItemLokiRing.changeSchematic(lokiStack, message.schematicName); + ItemLokiRing.syncLokiRing(player); + } + return null; + } +} diff --git a/src/main/java/vazkii/botania/common/network/PacketLokiDeleteSchematic.java b/src/main/java/vazkii/botania/common/network/PacketLokiDeleteSchematic.java new file mode 100644 index 0000000000..864653d815 --- /dev/null +++ b/src/main/java/vazkii/botania/common/network/PacketLokiDeleteSchematic.java @@ -0,0 +1,49 @@ +package vazkii.botania.common.network; + +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; +import cpw.mods.fml.common.network.simpleimpl.MessageContext; +import io.netty.buffer.ByteBuf; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import vazkii.botania.common.item.relic.ItemLokiRing; + +public class PacketLokiDeleteSchematic implements IMessage, IMessageHandler { + + private String schematicName; + + public PacketLokiDeleteSchematic() { + + } + + public PacketLokiDeleteSchematic(String schematicName) { + this.schematicName = schematicName; + } + + @Override + public void fromBytes(ByteBuf buf) { + int schematicNameLength = buf.readInt(); + this.schematicName = new String(buf.readBytes(schematicNameLength).array()); + if(schematicName.equals("null")) { + schematicName = null; + } + } + + @Override + public void toBytes(ByteBuf buf) { + schematicName = schematicName == null ? "null" : schematicName; + buf.writeInt(schematicName.length()); + buf.writeBytes(schematicName.getBytes()); + } + + @Override + public IMessage onMessage(PacketLokiDeleteSchematic message, MessageContext ctx) { + EntityPlayerMP player = ctx.getServerHandler().playerEntity; + ItemStack lokiStack = ItemLokiRing.getLokiRing(player); + if(lokiStack != null && lokiStack.getItem() instanceof ItemLokiRing) { + ItemLokiRing.deleteSchematic(lokiStack, message.schematicName); + ItemLokiRing.syncLokiRing(player); + } + return null; + } +} diff --git a/src/main/java/vazkii/botania/common/network/PacketLokiRenameSchematic.java b/src/main/java/vazkii/botania/common/network/PacketLokiRenameSchematic.java new file mode 100644 index 0000000000..91dac9608a --- /dev/null +++ b/src/main/java/vazkii/botania/common/network/PacketLokiRenameSchematic.java @@ -0,0 +1,59 @@ +package vazkii.botania.common.network; + +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; +import cpw.mods.fml.common.network.simpleimpl.MessageContext; +import io.netty.buffer.ByteBuf; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import vazkii.botania.common.item.relic.ItemLokiRing; + +public class PacketLokiRenameSchematic implements IMessage, IMessageHandler { + + private String schematicToBeRenamed; + private String newName; + + public PacketLokiRenameSchematic() { + } + + public PacketLokiRenameSchematic(String schematicToBeRenamed, String newValue) { + this.schematicToBeRenamed = schematicToBeRenamed; + this.newName = newValue; + } + + @Override + public void fromBytes(ByteBuf buf) { + int schematicToBeRenamedLength = buf.readInt(); + this.schematicToBeRenamed = new String(buf.readBytes(schematicToBeRenamedLength).array()); + if(schematicToBeRenamed.equals("null")) { + this.schematicToBeRenamed = null; + } + int newNameLength = buf.readInt(); + this.newName = new String(buf.readBytes(newNameLength).array()); + if(newName.equals("null")) { + this.newName = null; + } + } + + @Override + public void toBytes(ByteBuf buf) { + schematicToBeRenamed = schematicToBeRenamed == null ? "null" : schematicToBeRenamed; + buf.writeInt(schematicToBeRenamed.length()); + buf.writeBytes(schematicToBeRenamed.getBytes()); + newName = newName == null ? "null" : newName; + buf.writeInt(newName.length()); + buf.writeBytes(newName.getBytes()); + } + + + @Override + public IMessage onMessage(PacketLokiRenameSchematic message, MessageContext ctx) { + EntityPlayerMP player = ctx.getServerHandler().playerEntity; + ItemStack lokiStack = ItemLokiRing.getLokiRing(player); + if(lokiStack != null && lokiStack.getItem() instanceof ItemLokiRing) { + ItemLokiRing.renameSchematic(lokiStack, message.schematicToBeRenamed, message.newName); + ItemLokiRing.syncLokiRing(player); + } + return null; + } +} diff --git a/src/main/java/vazkii/botania/common/network/PacketLokiSaveSchematic.java b/src/main/java/vazkii/botania/common/network/PacketLokiSaveSchematic.java new file mode 100644 index 0000000000..6241582dac --- /dev/null +++ b/src/main/java/vazkii/botania/common/network/PacketLokiSaveSchematic.java @@ -0,0 +1,33 @@ +package vazkii.botania.common.network; + +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; +import cpw.mods.fml.common.network.simpleimpl.MessageContext; +import io.netty.buffer.ByteBuf; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import vazkii.botania.common.item.relic.ItemLokiRing; + +public class PacketLokiSaveSchematic implements IMessage, IMessageHandler { + @Override + public void fromBytes(ByteBuf buf) { + + } + + @Override + public void toBytes(ByteBuf buf) { + + } + + @Override + public IMessage onMessage(PacketLokiSaveSchematic message, MessageContext ctx) { + EntityPlayerMP player = ctx.getServerHandler().playerEntity; + final ItemStack aRing = ItemLokiRing.getLokiRing(player); + if (aRing != null) { + ItemLokiRing.saveCurrentSelectionAsSchematic(aRing); + ItemLokiRing.syncLokiRing(player); + PacketHandler.INSTANCE.sendTo(new PacketLokiHudNotificationAck(ItemLokiRing.HUD_MESSAGE.SCHEMATIC_SAVED), player); + } + return null; + } +} diff --git a/src/main/resources/assets/botania/lang/en_US.lang b/src/main/resources/assets/botania/lang/en_US.lang index 9fbb4ff72a..1d00350d0c 100644 --- a/src/main/resources/assets/botania/lang/en_US.lang +++ b/src/main/resources/assets/botania/lang/en_US.lang @@ -160,6 +160,8 @@ botaniamisc.keyCategory=Botania #LOKI botaniamisc.toggleLoki=Ring of Loki Switch Key botaniamisc.ringOfLokiClear=Clear Ring of Loki Selection +botaniamisc.ringOfLokiSaveSchematic=Save Ring of Loki Schematic +botaniamisc.ringOfLokiOpenUI=Open Ring of Loki Schematic GUI botaniamisc.lokiOn=On botaniamisc.lokiOff=Off botaniamisc.breaking=Breaking @@ -172,6 +174,12 @@ botaniamisc.lokiCurrent=Current botaniamisc.lokiState=Ring botaniamisc.lokiMirror=Current mirror: botaniamisc.insufficient_mana=Not enough mana! +botaniamisc.schematic_saved=Schematic successfully saved! + +#LOKI UI +botaniamisc.saved_schematics=Saved Schematics +botaniamisc.select_schematic=Select a Schematic! +botaniamisc.selected_schematic=Currently selected schematic: # NEI INTEGRATION botania.nei.brewery=Botanical Brewery diff --git a/src/main/resources/assets/botania/textures/gui/check.png b/src/main/resources/assets/botania/textures/gui/check.png new file mode 100644 index 0000000000..5e1216cf8a Binary files /dev/null and b/src/main/resources/assets/botania/textures/gui/check.png differ diff --git a/src/main/resources/assets/botania/textures/gui/croppedPaper.png b/src/main/resources/assets/botania/textures/gui/croppedPaper.png new file mode 100644 index 0000000000..21c6f0c7fe Binary files /dev/null and b/src/main/resources/assets/botania/textures/gui/croppedPaper.png differ diff --git a/src/main/resources/assets/botania/textures/gui/delete.png b/src/main/resources/assets/botania/textures/gui/delete.png new file mode 100644 index 0000000000..c6601c46d6 Binary files /dev/null and b/src/main/resources/assets/botania/textures/gui/delete.png differ diff --git a/src/main/resources/assets/botania/textures/gui/rename.png b/src/main/resources/assets/botania/textures/gui/rename.png new file mode 100644 index 0000000000..3e0991164d Binary files /dev/null and b/src/main/resources/assets/botania/textures/gui/rename.png differ