diff --git a/src/main/java/gregtech/api/capability/GregtechDataCodes.java b/src/main/java/gregtech/api/capability/GregtechDataCodes.java index 27556168e60..0c695d6b653 100644 --- a/src/main/java/gregtech/api/capability/GregtechDataCodes.java +++ b/src/main/java/gregtech/api/capability/GregtechDataCodes.java @@ -32,6 +32,7 @@ public class GregtechDataCodes { public static final int UPDATE_UI = 0; public static final int CREATE_FAKE_UI = 1; public static final int MOUSE_POSITION = 2; + public static final int DETECT_UPDATE_RECEIVED = 3; // Pump public static final int PUMP_HEAD_LEVEL = 200; @@ -69,4 +70,30 @@ public class GregtechDataCodes { public static final int DEFORM_TANK = 2; public static final int SYNC_FLUID_CHANGE = 3; public static final int SYNC_TANK_SHAPE = 4; + + // Central Monitor + public static final int UPDATE_ALL = 1; + public static final int UPDATE_COVERS = 2; + public static final int UPDATE_HEIGHT = 3; + public static final int UPDATE_ACTIVE = 4; + public static final int UPDATE_PLUGIN_ITEM = 3; + + // Central Monitor Plugin + public static final int UPDATE_PLUGIN_DATA = 2; + public static final int UPDATE_PLUGIN_CONFIG = 0; + public static final int ACTION_PLUGIN_CONFIG = 0; + public static final int UPDATE_PLUGIN_CLICK = -2; + public static final int UPDATE_ADVANCED_VALID_POS = 1; + public static final int UPDATE_FAKE_GUI = 1; + public static final int ACTION_FAKE_GUI = 1; + public static final int UPDATE_FAKE_GUI_DETECT = -1; + + // Digital Interface + public static final int UPDATE_MODE = 1; + public static final int UPDATE_FLUID = 2; + public static final int UPDATE_ITEM = 3; + public static final int UPDATE_ENERGY = 4; + public static final int UPDATE_ENERGY_PER = 5; + public static final int UPDATE_MACHINE = 6; + } diff --git a/src/main/java/gregtech/api/capability/IEnergyContainer.java b/src/main/java/gregtech/api/capability/IEnergyContainer.java index 71050a78a1c..72df6268142 100644 --- a/src/main/java/gregtech/api/capability/IEnergyContainer.java +++ b/src/main/java/gregtech/api/capability/IEnergyContainer.java @@ -98,6 +98,16 @@ default long getOutputVoltage() { */ long getInputVoltage(); + /** + * @return input eu/s + */ + default long getInputPerSec() {return 0L;} + + /** + * @return output eu/s + */ + default long getOutputPerSec() {return 0L;} + /** * @return true if information like energy capacity should be hidden from TOP. * Useful for cables @@ -106,4 +116,40 @@ default boolean isOneProbeHidden() { return false; } + IEnergyContainer DEFAULT = new IEnergyContainer() { + @Override + public long acceptEnergyFromNetwork(EnumFacing enumFacing, long l, long l1) { + return 0; + } + + @Override + public boolean inputsEnergy(EnumFacing enumFacing) { + return false; + } + + @Override + public long changeEnergy(long l) { + return 0; + } + + @Override + public long getEnergyStored() { + return 0; + } + + @Override + public long getEnergyCapacity() { + return 0; + } + + @Override + public long getInputAmperage() { + return 0; + } + + @Override + public long getInputVoltage() { + return 0; + } + }; } diff --git a/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java index a280d01fcec..af12cb472db 100644 --- a/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/AbstractRecipeLogic.java @@ -67,6 +67,8 @@ public AbstractRecipeLogic(MetaTileEntity tileEntity, RecipeMap recipeMap, bo this.hasPerfectOC = hasPerfectOC; } + protected abstract long getEnergyInputPerSecond(); + protected abstract long getEnergyStored(); protected abstract long getEnergyCapacity(); @@ -174,6 +176,9 @@ protected void updateRecipeProgress() { if (++progressTime > maxProgressTime) { completeRecipe(); } + if (this.hasNotEnoughEnergy && getEnergyInputPerSecond() > 19 * recipeEUt) { + this.hasNotEnoughEnergy = false; + } } else if (recipeEUt > 0) { //only set hasNotEnoughEnergy if this recipe is consuming recipe //generators always have enough energy diff --git a/src/main/java/gregtech/api/capability/impl/EnergyContainerBatteryBuffer.java b/src/main/java/gregtech/api/capability/impl/EnergyContainerBatteryBuffer.java index f50a6e67bba..9d8e17215f4 100644 --- a/src/main/java/gregtech/api/capability/impl/EnergyContainerBatteryBuffer.java +++ b/src/main/java/gregtech/api/capability/impl/EnergyContainerBatteryBuffer.java @@ -24,6 +24,10 @@ public class EnergyContainerBatteryBuffer extends MTETrait implements IEnergyCon private final BitSet batterySlotsUsedThisTick = new BitSet(); private final int tier; private long amps = 0; + private long lastEnergyInputPerSec = 0; + private long lastEnergyOutputPerSec = 0; + private long energyInputPerSec = 0; + private long energyOutputPerSec = 0; public EnergyContainerBatteryBuffer(MetaTileEntity metaTileEntity, int tier) { super(metaTileEntity); @@ -59,9 +63,20 @@ public long acceptEnergyFromNetwork(EnumFacing side, long voltage, long amperage notifyEnergyListener(false); } amps += usedAmps; + energyInputPerSec += voltage * usedAmps; return usedAmps; } + @Override + public long getInputPerSec() { + return lastEnergyInputPerSec; + } + + @Override + public long getOutputPerSec() { + return lastEnergyOutputPerSec; + } + private static boolean chargeItemWithVoltage(IElectricItem electricItem, long voltage, int tier, boolean simulate) { long charged = electricItem.charge(voltage, tier, false, simulate); return charged > 0; @@ -79,6 +94,12 @@ private static long chargeItem(IElectricItem electricItem, long amount, int tier public void update() { amps = 0; if (!metaTileEntity.getWorld().isRemote) { + if (metaTileEntity.getOffsetTimer() % 20 == 0) { + lastEnergyInputPerSec = energyInputPerSec; + lastEnergyOutputPerSec = energyOutputPerSec; + energyInputPerSec = 0; + energyOutputPerSec = 0; + } this.batterySlotsUsedThisTick.clear(); EnumFacing outFacing = metaTileEntity.getFrontFacing(); TileEntity tileEntity = metaTileEntity.getWorld().getTileEntity(metaTileEntity.getPos().offset(outFacing)); @@ -106,6 +127,7 @@ public void update() { if (maxAmperage == 0) return; long amperageUsed = energyContainer.acceptEnergyFromNetwork(outFacing.getOpposite(), voltage, maxAmperage); if (amperageUsed == 0) return; + energyOutputPerSec += amperageUsed * voltage; for (int i : slotsList.toArray()) { ItemStack batteryStack = inventory.getStackInSlot(i); IElectricItem electricItem = getBatteryContainer(batteryStack); @@ -183,6 +205,7 @@ public long changeEnergy(long energyToAdd) { if (energyAdded > 0L) { notifyEnergyListener(false); } + energyInputPerSec += energyAdded; return energyAdded; } diff --git a/src/main/java/gregtech/api/capability/impl/EnergyContainerHandler.java b/src/main/java/gregtech/api/capability/impl/EnergyContainerHandler.java index 666b8442ccf..8c959067602 100644 --- a/src/main/java/gregtech/api/capability/impl/EnergyContainerHandler.java +++ b/src/main/java/gregtech/api/capability/impl/EnergyContainerHandler.java @@ -26,6 +26,11 @@ public class EnergyContainerHandler extends MTETrait implements IEnergyContainer private final long maxOutputVoltage; private final long maxOutputAmperage; + private long lastEnergyInputPerSec = 0; + private long lastEnergyOutputPerSec = 0; + private long energyInputPerSec = 0; + private long energyOutputPerSec = 0; + private Predicate sideInputCondition; private Predicate sideOutputCondition; @@ -56,6 +61,16 @@ public static EnergyContainerHandler receiverContainer(MetaTileEntity tileEntity return new EnergyContainerHandler(tileEntity, maxCapacity, maxInputVoltage, maxInputAmperage, 0L, 0L); } + @Override + public long getInputPerSec() { + return lastEnergyInputPerSec; + } + + @Override + public long getOutputPerSec() { + return lastEnergyOutputPerSec; + } + @Override public String getName() { return "EnergyContainer"; @@ -93,6 +108,11 @@ public long getEnergyStored() { } public void setEnergyStored(long energyStored) { + if (energyStored > this.energyStored) { + energyInputPerSec += energyStored - this.energyStored; + } else { + energyOutputPerSec += this.energyStored - energyStored; + } this.energyStored = energyStored; if (!metaTileEntity.getWorld().isRemote) { metaTileEntity.markDirty(); @@ -138,6 +158,12 @@ public void update() { amps = 0; if (getMetaTileEntity().getWorld().isRemote) return; + if (metaTileEntity.getOffsetTimer() % 20 == 0) { + lastEnergyOutputPerSec = energyOutputPerSec; + lastEnergyInputPerSec = energyInputPerSec; + energyOutputPerSec = 0; + energyInputPerSec = 0; + } if (getEnergyStored() >= getOutputVoltage() && getOutputVoltage() > 0 && getOutputAmperage() > 0) { long outputVoltage = getOutputVoltage(); long outputAmperes = Math.min(getEnergyStored() / outputVoltage, getOutputAmperage()); diff --git a/src/main/java/gregtech/api/capability/impl/EnergyContainerList.java b/src/main/java/gregtech/api/capability/impl/EnergyContainerList.java index 04de92b43fb..7f0e23a2ca0 100644 --- a/src/main/java/gregtech/api/capability/impl/EnergyContainerList.java +++ b/src/main/java/gregtech/api/capability/impl/EnergyContainerList.java @@ -13,6 +13,24 @@ public EnergyContainerList(List energyContainerList) { this.energyContainerList = energyContainerList; } + @Override + public long getInputPerSec() { + long sum = 0; + for (IEnergyContainer energyContainer : energyContainerList) { + sum += energyContainer.getInputPerSec(); + } + return sum; + } + + @Override + public long getOutputPerSec() { + long sum = 0; + for (IEnergyContainer energyContainer : energyContainerList) { + sum += energyContainer.getOutputPerSec(); + } + return sum; + } + @Override public long acceptEnergyFromNetwork(EnumFacing side, long voltage, long amperage) { long amperesUsed = 0L; diff --git a/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java index b5a707a6319..9c8726429a8 100644 --- a/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/MultiblockRecipeLogic.java @@ -219,6 +219,11 @@ protected void completeRecipe() { super.completeRecipe(); } + @Override + protected long getEnergyInputPerSecond() { + return getEnergyContainer().getInputPerSec(); + } + @Override protected long getEnergyStored() { return getEnergyContainer().getEnergyStored(); diff --git a/src/main/java/gregtech/api/capability/impl/PrimitiveRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/PrimitiveRecipeLogic.java index 76568261c2e..9f5c2bf6804 100644 --- a/src/main/java/gregtech/api/capability/impl/PrimitiveRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/PrimitiveRecipeLogic.java @@ -13,6 +13,11 @@ public PrimitiveRecipeLogic(RecipeMapPrimitiveMultiblockController tileEntity, R super(tileEntity, recipeMap); } + @Override + protected long getEnergyInputPerSecond() { + return Integer.MAX_VALUE; + } + @Override protected long getEnergyStored() { return Integer.MAX_VALUE; diff --git a/src/main/java/gregtech/api/capability/impl/RecipeLogicEnergy.java b/src/main/java/gregtech/api/capability/impl/RecipeLogicEnergy.java index e89f3d1e78d..94d8ce6a74c 100644 --- a/src/main/java/gregtech/api/capability/impl/RecipeLogicEnergy.java +++ b/src/main/java/gregtech/api/capability/impl/RecipeLogicEnergy.java @@ -15,6 +15,11 @@ public RecipeLogicEnergy(MetaTileEntity tileEntity, RecipeMap recipeMap, Supp this.energyContainer = energyContainer; } + @Override + protected long getEnergyInputPerSecond() { + return energyContainer.get().getInputPerSec(); + } + @Override protected long getEnergyStored() { return energyContainer.get().getEnergyStored(); diff --git a/src/main/java/gregtech/api/capability/impl/RecipeLogicSteam.java b/src/main/java/gregtech/api/capability/impl/RecipeLogicSteam.java index 13e26c83811..36d9d02d784 100644 --- a/src/main/java/gregtech/api/capability/impl/RecipeLogicSteam.java +++ b/src/main/java/gregtech/api/capability/impl/RecipeLogicSteam.java @@ -175,6 +175,11 @@ protected int[] calculateOverclock(int EUt, long voltage, int duration) { }; } + @Override + protected long getEnergyInputPerSecond() { + return 0; + } + @Override protected long getEnergyStored() { return (long) Math.ceil(steamFluidTank.getFluidAmount() * conversionRate); diff --git a/src/main/java/gregtech/api/capability/impl/SteamMultiblockRecipeLogic.java b/src/main/java/gregtech/api/capability/impl/SteamMultiblockRecipeLogic.java index aff3c943b5f..06b535791d3 100644 --- a/src/main/java/gregtech/api/capability/impl/SteamMultiblockRecipeLogic.java +++ b/src/main/java/gregtech/api/capability/impl/SteamMultiblockRecipeLogic.java @@ -80,6 +80,11 @@ public void update() { super.update(); } + @Override + protected long getEnergyInputPerSecond() { + return 0; + } + @Override protected long getEnergyStored() { combineSteamTanks(); diff --git a/src/main/java/gregtech/api/gui/impl/FakeModularGui.java b/src/main/java/gregtech/api/gui/impl/FakeModularGui.java index cbf46e40368..001f87ed97e 100644 --- a/src/main/java/gregtech/api/gui/impl/FakeModularGui.java +++ b/src/main/java/gregtech/api/gui/impl/FakeModularGui.java @@ -3,32 +3,31 @@ import gregtech.api.gui.IRenderContext; import gregtech.api.gui.ModularUI; import gregtech.api.gui.Widget; -import gregtech.common.gui.impl.FakeModularUIContainerClipboard; import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.gui.FontRenderer; -import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.*; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.util.ITooltipFlag; import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; import net.minecraft.network.PacketBuffer; +import net.minecraft.util.math.MathHelper; import net.minecraft.util.text.TextFormatting; import net.minecraftforge.fml.client.config.GuiUtils; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import java.util.List; -import java.util.Optional; - -import static gregtech.api.gui.impl.ModularUIGui.*; @SideOnly(Side.CLIENT) public class FakeModularGui implements IRenderContext { public final ModularUI modularUI; - public FakeModularUIContainerClipboard container; + public FakeModularGuiContainer container; protected Minecraft mc; protected FontRenderer fr; - public FakeModularGui(ModularUI modularUI, FakeModularUIContainerClipboard fakeModularUIContainer){ + public FakeModularGui(ModularUI modularUI, FakeModularGuiContainer fakeModularUIContainer){ this.modularUI = modularUI; this.container = fakeModularUIContainer; this.modularUI.updateScreenSize(this.modularUI.getWidth(), this.modularUI.getHeight()); @@ -42,7 +41,7 @@ public void updateScreen() { public void handleWidgetUpdate(int windowId, int widgetId, PacketBuffer updateData) { if (windowId == container.windowId) { - Widget widget = modularUI.guiWidgets.get(Optional.of(widgetId)); + Widget widget = modularUI.guiWidgets.get(widgetId); int updateId = updateData.readVarInt(); if (widget != null) { widget.readUpdateInfo(updateId, updateData); @@ -56,22 +55,24 @@ public void drawScreen(double x, double y, float partialTicks) { float scale = 0.5f / Math.max(halfW, halfH); int mouseX = (int) ((x / scale) + (halfW > halfH? 0: (halfW - halfH))); int mouseY = (int) ((y / scale) + (halfH > halfW? 0: (halfH - halfW))); - - GlStateManager.translate(-scale * halfW, -scale * halfH, 0.01); + GlStateManager.translate(-scale * halfW, -scale * halfH, 0); GlStateManager.scale(scale, scale, 1); modularUI.backgroundPath.draw(0, 0, modularUI.getWidth(), modularUI.getHeight()); - GlStateManager.translate(0, 0, -0.01); + GlStateManager.translate(0, 0, 0.001); GlStateManager.depthMask(false); drawGuiContainerBackgroundLayer(partialTicks, mouseX, mouseY); + for (int i = 0; i < this.container.inventorySlots.size(); ++i) { + renderSlot(this.container.inventorySlots.get(i), fr); + } + GlStateManager.scale(1, 1, 0); drawGuiContainerForegroundLayer(mouseX, mouseY); for (int i = 0; i < this.container.inventorySlots.size(); ++i) { Slot slot = this.container.inventorySlots.get(i); if (!slot.getStack().isEmpty() && slot.xPos < mouseX && mouseX < slot.xPos + 18 && slot.yPos < mouseY && mouseY < slot.yPos + 18) { - Widget.drawSolidRect(slot.xPos, slot.yPos, 18, 18, 0X8fffffff); renderToolTip(slot.getStack(), slot.xPos, slot.yPos); } } @@ -81,6 +82,80 @@ public void drawScreen(double x, double y, float partialTicks) { GlStateManager.disableLighting(); } + public static void renderSlot(Slot slot, FontRenderer fr) { + ItemStack stack = slot.getStack(); + if (!stack.isEmpty() && slot.isEnabled()) { + GlStateManager.disableRescaleNormal(); + RenderHelper.enableStandardItemLighting(); + GlStateManager.pushMatrix(); + GlStateManager.scale(1, 1, 0.00001); + GlStateManager.translate(slot.xPos, slot.yPos, 0); + RenderItem renderItem = Minecraft.getMinecraft().getRenderItem(); + renderItem.renderItemAndEffectIntoGUI(stack, 0, 0); + renderItem.renderItemOverlayIntoGUI(Minecraft.getMinecraft().fontRenderer, stack, 0, 0, null); + String text = stack.getCount() > 1? Integer.toString(stack.getCount()) : null; + + if (!stack.isEmpty()) + { + if (stack.getCount() != 1) + { + String s = text == null ? String.valueOf(stack.getCount()) : text; + GlStateManager.disableLighting(); + GlStateManager.disableBlend(); + fr.drawStringWithShadow(s, (float)(17 - fr.getStringWidth(s)), (float)9, 16777215); + GlStateManager.enableLighting(); + GlStateManager.enableBlend(); + } + + if (stack.getItem().showDurabilityBar(stack)) + { + GlStateManager.disableLighting(); + GlStateManager.disableTexture2D(); + GlStateManager.disableAlpha(); + GlStateManager.disableBlend(); + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder bufferbuilder = tessellator.getBuffer(); + double health = stack.getItem().getDurabilityForDisplay(stack); + int rgbfordisplay = stack.getItem().getRGBDurabilityForDisplay(stack); + int i = Math.round(13.0F - (float)health * 13.0F); + draw(bufferbuilder, 2, 13, 13, 2, 0, 0, 0, 255); + draw(bufferbuilder, 2, 13, i, 1, rgbfordisplay >> 16 & 255, rgbfordisplay >> 8 & 255, rgbfordisplay & 255, 255); + GlStateManager.enableBlend(); + GlStateManager.enableAlpha(); + GlStateManager.enableTexture2D(); + GlStateManager.enableLighting(); + } + + EntityPlayerSP entityplayersp = Minecraft.getMinecraft().player; + float f3 = entityplayersp == null ? 0.0F : entityplayersp.getCooldownTracker().getCooldown(stack.getItem(), Minecraft.getMinecraft().getRenderPartialTicks()); + + if (f3 > 0.0F) + { + GlStateManager.disableLighting(); + GlStateManager.disableTexture2D(); + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder bufferBuilder = tessellator.getBuffer(); + draw(bufferBuilder, 0, MathHelper.floor(16.0F * (1.0F - f3)), 16, MathHelper.ceil(16.0F * f3), 255, 255, 255, 127); + GlStateManager.enableTexture2D(); + GlStateManager.enableLighting(); + } + } + + GlStateManager.popMatrix(); + net.minecraft.client.renderer.RenderHelper.disableStandardItemLighting(); + } + } + + private static void draw(BufferBuilder renderer, int x, int y, int width, int height, int red, int green, int blue, int alpha) + { + renderer.begin(7, DefaultVertexFormats.POSITION_COLOR); + renderer.pos(x, y, 0.0D).color(red, green, blue, alpha).endVertex(); + renderer.pos((x), y + height, 0.0D).color(red, green, blue, alpha).endVertex(); + renderer.pos((x + width), y + height, 0.0D).color(red, green, blue, alpha).endVertex(); + renderer.pos((x + width), y, 0.0D).color(red, green, blue, alpha).endVertex(); + Tessellator.getInstance().draw(); + } + protected void renderToolTip(ItemStack stack, int x, int y) { FontRenderer font = stack.getItem().getFontRenderer(stack); GuiUtils.preItemToolTip(stack); @@ -98,8 +173,7 @@ protected List getItemToolTip(ItemStack itemStack) { } public void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) { - GlStateManager.color(rColorForOverlay, gColorForOverlay, bColorForOverlay, 1.0F); - modularUI.backgroundPath.draw(0, 0, modularUI.getWidth(), modularUI.getHeight()); + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); for (Widget widget : modularUI.guiWidgets.values()) { GlStateManager.pushMatrix(); GlStateManager.color(1.0f, 1.0f, 1.0f); diff --git a/src/main/java/gregtech/api/gui/impl/FakeModularGuiContainer.java b/src/main/java/gregtech/api/gui/impl/FakeModularGuiContainer.java new file mode 100644 index 00000000000..9c5c2d702c0 --- /dev/null +++ b/src/main/java/gregtech/api/gui/impl/FakeModularGuiContainer.java @@ -0,0 +1,89 @@ +package gregtech.api.gui.impl; + +import com.google.common.collect.Lists; +import gregtech.api.gui.INativeWidget; +import gregtech.api.gui.ModularUI; +import gregtech.api.gui.Widget; +import gregtech.api.gui.widgets.WidgetUIAccess; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.NonNullList; + +import java.util.List; +import java.util.function.Consumer; + +public abstract class FakeModularGuiContainer implements WidgetUIAccess { + protected final NonNullList inventoryItemStacks = NonNullList.create(); + public final List inventorySlots = Lists.newArrayList(); + public final ModularUI modularUI; + protected int windowId; + + public FakeModularGuiContainer(ModularUI modularUI) { + this.modularUI = modularUI; + modularUI.initWidgets(); + modularUI.guiWidgets.values().forEach(widget -> widget.setUiAccess(this)); + modularUI.guiWidgets.values().stream().flatMap(widget -> widget.getNativeWidgets().stream()).forEach(nativeWidget -> addSlotToContainer(nativeWidget.getHandle())); + modularUI.triggerOpenListeners(); + } + + protected void addSlotToContainer(Slot slotIn) { + slotIn.slotNumber = this.inventorySlots.size(); + this.inventorySlots.add(slotIn); + this.inventoryItemStacks.add(ItemStack.EMPTY); + } + + public void handleSlotUpdate(PacketBuffer updateData) { + try { + int size = updateData.readVarInt(); + for (int i = 0; i < size; i++) { + inventorySlots.get(updateData.readVarInt()).putStack(updateData.readItemStack()); + } + } catch (Exception ignored){ + + } + } + + public void handleClientAction(PacketBuffer buffer) { + if (detectSyncedPacket(buffer)) { + Widget widget = modularUI.guiWidgets.get(buffer.readVarInt()); + if (widget != null) { + widget.handleClientAction(buffer.readVarInt(), buffer); + } + } + } + + // Detects if a client action is germane to a container. THIS MAY MODIFY THE CONTAINER. + public abstract boolean detectSyncedPacket(PacketBuffer buffer); + + public abstract void detectAndSendChanges(); + + @Override + public void notifySizeChange() { + + } + + @Override + public void notifyWidgetChange() { + + } + + @Override + public boolean attemptMergeStack(ItemStack itemStack, boolean b, boolean b1) { + return false; + } + + @Override + public void sendSlotUpdate(INativeWidget iNativeWidget) { + } + + @Override + public void sendHeldItemUpdate() { + } + + @Override + public abstract void writeClientAction(Widget widget, int updateId, Consumer payloadWriter); + + @Override + public abstract void writeUpdateInfo(Widget widget, int updateId, Consumer payloadWriter); +} diff --git a/src/main/java/gregtech/api/gui/resources/RenderUtil.java b/src/main/java/gregtech/api/gui/resources/RenderUtil.java deleted file mode 100644 index 8be9d45d006..00000000000 --- a/src/main/java/gregtech/api/gui/resources/RenderUtil.java +++ /dev/null @@ -1,105 +0,0 @@ -package gregtech.api.gui.resources; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.BufferBuilder; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.renderer.texture.TextureMap; -import net.minecraft.client.renderer.vertex.DefaultVertexFormats; -import net.minecraft.util.ResourceLocation; -import net.minecraftforge.fluids.Fluid; -import net.minecraftforge.fluids.FluidRegistry; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -@SideOnly(Side.CLIENT) -public class RenderUtil { - - public static int packColor(int red, int green, int blue, int alpha) { - return (red & 0xFF) << 24 | (green & 0xFF) << 16 | (blue & 0xFF) << 8 | (alpha & 0xFF); - } - - public static void setGlColorFromInt(int colorValue, int opacity) { - int i = (colorValue & 16711680) >> 16; - int j = (colorValue & 65280) >> 8; - int k = (colorValue & 255); - GlStateManager.color(i / 255.0f, j / 255.0f, k / 255.0f, opacity / 255.0f); - } - - public static void setGlClearColorFromInt(int colorValue, int opacity) { - int i = (colorValue & 16711680) >> 16; - int j = (colorValue & 65280) >> 8; - int k = (colorValue & 255); - GlStateManager.clearColor(i / 255.0f, j / 255.0f, k / 255.0f, opacity / 255.0f); - } - - public static int getFluidColor(FluidStack fluidStack) { - if (fluidStack.getFluid() == FluidRegistry.WATER) - return 0x3094CF; - else if (fluidStack.getFluid() == FluidRegistry.LAVA) - return 0xFFD700; - return fluidStack.getFluid().getColor(fluidStack); - } - - public static void drawFluidForGui(FluidStack contents, int tankCapacity, int startX, int startY, int widthT, int heightT) { - widthT--; - heightT--; - Fluid fluid = contents.getFluid(); - ResourceLocation fluidStill = fluid.getStill(); - TextureAtlasSprite fluidStillSprite = Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(fluidStill.toString()); - int fluidColor = fluid.getColor(contents); - int scaledAmount = contents.amount * heightT / tankCapacity; - if (contents.amount > 0 && scaledAmount < 1) { - scaledAmount = 1; - } - if (scaledAmount > heightT || contents.amount == tankCapacity) { - scaledAmount = heightT; - } - GlStateManager.enableBlend(); - Minecraft.getMinecraft().renderEngine.bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); - setGlColorFromInt(fluidColor, 200); - - final int xTileCount = widthT / 16; - final int xRemainder = widthT - xTileCount * 16; - final int yTileCount = scaledAmount / 16; - final int yRemainder = scaledAmount - yTileCount * 16; - - final int yStart = startY + heightT; - - for (int xTile = 0; xTile <= xTileCount; xTile++) { - for (int yTile = 0; yTile <= yTileCount; yTile++) { - int width = xTile == xTileCount ? xRemainder : 16; - int height = yTile == yTileCount ? yRemainder : 16; - int x = startX + xTile * 16; - int y = yStart - (yTile + 1) * 16; - if (width > 0 && height > 0) { - int maskTop = 16 - height; - int maskRight = 16 - width; - - drawFluidTexture(x, y, fluidStillSprite, maskTop, maskRight, 0.0); - } - } - } - GlStateManager.disableBlend(); - } - - private static void drawFluidTexture(double xCoord, double yCoord, TextureAtlasSprite textureSprite, int maskTop, int maskRight, double zLevel) { - double uMin = textureSprite.getMinU(); - double uMax = textureSprite.getMaxU(); - double vMin = textureSprite.getMinV(); - double vMax = textureSprite.getMaxV(); - uMax = uMax - maskRight / 16.0 * (uMax - uMin); - vMax = vMax - maskTop / 16.0 * (vMax - vMin); - - Tessellator tessellator = Tessellator.getInstance(); - BufferBuilder buffer = tessellator.getBuffer(); - buffer.begin(7, DefaultVertexFormats.POSITION_TEX); - buffer.pos(xCoord, yCoord + 16, zLevel).tex(uMin, vMax).endVertex(); - buffer.pos(xCoord + 16 - maskRight, yCoord + 16, zLevel).tex(uMax, vMax).endVertex(); - buffer.pos(xCoord + 16 - maskRight, yCoord + maskTop, zLevel).tex(uMax, vMin).endVertex(); - buffer.pos(xCoord, yCoord + maskTop, zLevel).tex(uMin, vMin).endVertex(); - tessellator.draw(); - } -} diff --git a/src/main/java/gregtech/api/gui/resources/utils/DownloadThread.java b/src/main/java/gregtech/api/gui/resources/utils/DownloadThread.java index e44562021d1..e9685bbf694 100644 --- a/src/main/java/gregtech/api/gui/resources/utils/DownloadThread.java +++ b/src/main/java/gregtech/api/gui/resources/utils/DownloadThread.java @@ -1,14 +1,13 @@ package gregtech.api.gui.resources.utils; -import gregtech.GregTechMod; import gregtech.api.gui.resources.picturetexture.AnimatedPictureTexture; import gregtech.api.gui.resources.picturetexture.OrdinaryTexture; import gregtech.api.gui.resources.picturetexture.PictureTexture; import gregtech.api.gui.resources.picturetexture.VideoTexture; +import gregtech.api.util.GTLog; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import org.apache.commons.compress.utils.IOUtils; -import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import javax.imageio.ImageIO; @@ -20,11 +19,14 @@ import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.*; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; @SideOnly(Side.CLIENT) public class DownloadThread extends Thread { - public static final Logger LOGGER = LogManager.getLogger(GregTechMod.class); + public static final Logger LOGGER = GTLog.logger; public static final TextureCache TEXTURE_CACHE = new TextureCache(); public static final DateFormat FORMAT = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z"); diff --git a/src/main/java/gregtech/api/gui/widgets/PhantomFluidWidget.java b/src/main/java/gregtech/api/gui/widgets/PhantomFluidWidget.java index b1429bc4e27..9d9146eced1 100644 --- a/src/main/java/gregtech/api/gui/widgets/PhantomFluidWidget.java +++ b/src/main/java/gregtech/api/gui/widgets/PhantomFluidWidget.java @@ -7,8 +7,8 @@ import gregtech.api.gui.ingredient.IGhostIngredientTarget; import gregtech.api.gui.ingredient.IIngredientSlot; import gregtech.api.gui.resources.IGuiTexture; -import gregtech.api.gui.resources.RenderUtil; import gregtech.api.util.Position; +import gregtech.api.util.RenderUtil; import gregtech.api.util.Size; import gregtech.api.util.TextFormattingUtil; import mezz.jei.api.gui.IGhostIngredientHandler.Target; diff --git a/src/main/java/gregtech/api/gui/widgets/SlotWidget.java b/src/main/java/gregtech/api/gui/widgets/SlotWidget.java index d6cc67dd442..e35939925c5 100644 --- a/src/main/java/gregtech/api/gui/widgets/SlotWidget.java +++ b/src/main/java/gregtech/api/gui/widgets/SlotWidget.java @@ -82,8 +82,7 @@ public void drawInBackground(int mouseX, int mouseY, IRenderContext context) { } } GlStateManager.disableRescaleNormal(); - GlStateManager.disableLighting(); - RenderHelper.disableStandardItemLighting(); + RenderHelper.enableStandardItemLighting(); RenderHelper.enableGUIStandardItemLighting(); GlStateManager.pushMatrix(); RenderItem itemRender = Minecraft.getMinecraft().getRenderItem(); diff --git a/src/main/java/gregtech/api/gui/widgets/TankWidget.java b/src/main/java/gregtech/api/gui/widgets/TankWidget.java index b2999aab102..5385420934d 100644 --- a/src/main/java/gregtech/api/gui/widgets/TankWidget.java +++ b/src/main/java/gregtech/api/gui/widgets/TankWidget.java @@ -5,11 +5,7 @@ import gregtech.api.gui.Widget; import gregtech.api.gui.ingredient.IIngredientSlot; import gregtech.api.gui.resources.IGuiTexture; -import gregtech.api.gui.resources.RenderUtil; -import gregtech.api.util.FluidTooltipUtil; -import gregtech.api.util.Position; -import gregtech.api.util.Size; -import gregtech.api.util.TextFormattingUtil; +import gregtech.api.util.*; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.renderer.GlStateManager; diff --git a/src/main/java/gregtech/api/items/behavior/MonitorPluginBaseBehavior.java b/src/main/java/gregtech/api/items/behavior/MonitorPluginBaseBehavior.java new file mode 100644 index 00000000000..348dc74fca1 --- /dev/null +++ b/src/main/java/gregtech/api/items/behavior/MonitorPluginBaseBehavior.java @@ -0,0 +1,235 @@ +package gregtech.api.items.behavior; + +import gregtech.api.capability.GregtechDataCodes; +import gregtech.api.gui.GuiTextures; +import gregtech.api.gui.IUIHolder; +import gregtech.api.gui.ModularUI; +import gregtech.api.items.gui.ItemUIFactory; +import gregtech.api.items.gui.PlayerInventoryHolder; +import gregtech.api.items.metaitem.MetaItem; +import gregtech.api.items.metaitem.stats.IItemBehaviour; +import gregtech.api.net.CPacketPluginSynced; +import gregtech.api.net.NetworkHandler; +import gregtech.api.util.IDirtyNotifiable; +import gregtech.common.gui.widget.monitor.WidgetPluginConfig; +import gregtech.common.metatileentities.multi.electric.centralmonitor.MetaTileEntityMonitorScreen; +import net.minecraft.client.resources.I18n; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import javax.annotation.Nonnull; +import java.util.List; +import java.util.function.Consumer; + +public abstract class MonitorPluginBaseBehavior implements IItemBehaviour, ItemUIFactory, IDirtyNotifiable { + protected MetaTileEntityMonitorScreen screen; + private NBTTagCompound nbtTagCompound; + + public static MonitorPluginBaseBehavior getBehavior(ItemStack itemStack) { + if (itemStack.getItem() instanceof MetaItem) { + MetaItem item = (MetaItem) itemStack.getItem(); + for (IItemBehaviour behaviour : item.getBehaviours(itemStack)) { + if (behaviour instanceof MonitorPluginBaseBehavior) { + return (MonitorPluginBaseBehavior) behaviour; + } + } + } + return null; + } + + public MetaTileEntityMonitorScreen getScreen() { + return screen; + } + + abstract public MonitorPluginBaseBehavior createPlugin(); + + /*** + * Do not override createUI below. + * @param holder It should be one of PlayerInventoryHolder or MetaTileEntityHolder. + * @param entityPlayer Player + * @return WidgetGroup back + */ + public WidgetPluginConfig customUI(WidgetPluginConfig widgetGroup, IUIHolder holder, EntityPlayer entityPlayer) { + return widgetGroup; + } + + /*** + * Can player using item (right-click) to open the customUI. + */ + public boolean hasUI() { + return false; + } + + /*** + * Server / Client. Itemstack will be synced to client when init so... yeah normally you don't need to consider nbt init. + * this will be called when you markDirty. + * @param data nbtTag + */ + public void writeToNBT(NBTTagCompound data) { + } + + /*** + * Server / Client. Initialization of Server and Client. + * @param data nbtTag + */ + public void readFromNBT(NBTTagCompound data) { + this.nbtTagCompound = data; + } + + /*** + * Server. Same as writeCustomData in MetaTileEntity. + * @param id PacketID + * @param buf PacketBuffer + */ + public final void writePluginData(int id, @Nonnull Consumer buf) { + if (screen != null && this.screen.getWorld() != null && !this.screen.getWorld().isRemote) { + screen.writeCustomData(GregtechDataCodes.UPDATE_PLUGIN_DATA, packetBuffer -> { + packetBuffer.writeVarInt(id); + buf.accept(packetBuffer); + }); + } + } + + /*** + * Client. Same as receiveCustomData in MetaTileEntity. + * @param id PacketID + * @param buf PacketBuffer + */ + public void readPluginData(int id, PacketBuffer buf) { + + } + + /*** + * Client. Send data to Server. + * @param id PacketID + * @param buf PacketBuffer + */ + public final void writePluginAction(int id, @Nonnull Consumer buf) { + NetworkHandler.channel.sendToServer(new CPacketPluginSynced(this, id, buf).toFMLPacket()); + } + + /*** + * Server. receive data from client + * @param player player + * @param id PacketID + * @param buf PacketBuffer + */ + public void readPluginAction(EntityPlayerMP player, int id, PacketBuffer buf) { + + } + + /*** + * Server. Same as writeInitialSyncData in MetaTileEntity. + * @param buf PacketBuffer + */ + public void writeInitialSyncData(PacketBuffer buf) { + + } + + /*** + * Client. Same as receiveInitialSyncData in MetaTileEntity. + * @param buf PacketBuffer + */ + public void receiveInitialSyncData(PacketBuffer buf) { + + } + + /*** + * Server / Client (deprecated). Should be called when need to write persistence data to NBT + */ + public void markAsDirty() { + if (screen != null) { + screen.pluginDirty(); + } else if (nbtTagCompound != null) { + writeToNBT(nbtTagCompound); + } + } + + /*** Server / Client. Called when player touch the screen. + * @param playerIn Player + * @param hand Hand + * @param facing Facing + * @param isRight is Right Click + * @param x xPos of the screen (0 ~ 1.0) + * @param y yPos of the screen (0 ~ 1.0) + * @return trigger result + */ + public boolean onClickLogic(EntityPlayer playerIn, EnumHand hand, EnumFacing facing, boolean isRight, double x, double y) { + return false; + } + + /*** + * Server / Client. Called per tick when structure formed. + */ + public void update() { + + } + + /*** + * Client. Write rendering here + */ + @SideOnly(Side.CLIENT) + public void renderPlugin(float partialTicks, RayTraceResult rayTraceResult) { + + } + + /*** + * Server / Client. Called when plugin is added or removed from the screen. + * @param screen + * @param valid + */ + public void onMonitorValid(MetaTileEntityMonitorScreen screen, boolean valid) { + if (valid) { + this.screen = screen; + } else { + this.screen = null; + } + } + + @Override + public ActionResult onItemRightClick(World world, EntityPlayer player, EnumHand hand) { + if (!world.isRemote) { + if (hand != EnumHand.MAIN_HAND) + return ActionResult.newResult(EnumActionResult.PASS, player.getHeldItem(hand)); + ItemStack itemStack = player.getHeldItem(hand); + MonitorPluginBaseBehavior behavior = getBehavior(itemStack); + if (behavior != null && behavior.hasUI()) { + PlayerInventoryHolder holder = new PlayerInventoryHolder(player, hand); + holder.openUI(); + return ActionResult.newResult(EnumActionResult.SUCCESS, itemStack); + } + } + return ActionResult.newResult(EnumActionResult.PASS, player.getHeldItem(hand)); + } + + @Override + public final ModularUI createUI(PlayerInventoryHolder playerInventoryHolder, EntityPlayer entityPlayer) { + ItemStack itemStack = playerInventoryHolder.getCurrentItem(); + MonitorPluginBaseBehavior behavior = MonitorPluginBaseBehavior.getBehavior(itemStack); + if (behavior != null) { + behavior = behavior.createPlugin(); + behavior.readFromNBT(itemStack.getOrCreateSubCompound("monitor_plugin")); + return ModularUI.builder(GuiTextures.BOXED_BACKGROUND, 260, 210) + .widget(behavior.customUI(new WidgetPluginConfig().setBackGround(GuiTextures.BACKGROUND), playerInventoryHolder, entityPlayer)) + .bindCloseListener(this::markAsDirty) + .build(playerInventoryHolder, entityPlayer); + } + return null; + } + + @Override + public void addInformation(ItemStack itemStack, List lines) { + lines.add(I18n.format("metaitem.plugin.tooltips.1")); + } +} diff --git a/src/main/java/gregtech/api/items/behavior/ProxyHolderPluginBehavior.java b/src/main/java/gregtech/api/items/behavior/ProxyHolderPluginBehavior.java new file mode 100644 index 00000000000..8c1703bce20 --- /dev/null +++ b/src/main/java/gregtech/api/items/behavior/ProxyHolderPluginBehavior.java @@ -0,0 +1,44 @@ +package gregtech.api.items.behavior; + +import gregtech.api.metatileentity.MetaTileEntityHolder; +import net.minecraft.client.resources.I18n; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.BlockPos; + +import java.util.List; +import java.util.Objects; + +public abstract class ProxyHolderPluginBehavior extends MonitorPluginBaseBehavior { + protected MetaTileEntityHolder holder; + private BlockPos pos; + + @Override + public void update() { + if (pos != null && holder == null) { + holder = this.screen.getHolderFromPos(pos); + if (holder != null) { + onHolderChanged(null); + } + } + } + + @Override + public void addInformation(ItemStack itemStack, List lines) { + super.addInformation(itemStack, lines); + lines.add(I18n.format("metaitem.plugin.proxy.tooltips.1")); + } + + public void onHolderPosUpdated(BlockPos pos) { + if (Objects.equals(this.pos, pos)) return; + this.pos = pos; + MetaTileEntityHolder lastHolder = holder; + holder = this.screen.getHolderFromPos(pos); + if (!Objects.equals(lastHolder, holder)) onHolderChanged(lastHolder); + } + + protected abstract void onHolderChanged(MetaTileEntityHolder lastHolder); + + public MetaTileEntityHolder getHolder() { + return holder; + } +} diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java index 9052427edcd..29450958c41 100644 --- a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java @@ -495,10 +495,6 @@ public final void dropAllCovers() { } public boolean canPlaceCoverOnSide(EnumFacing side) { - if (hasFrontFacing() && side == getFrontFacing()) { - //covers cannot be placed on this side - return false; - } ArrayList collisionList = new ArrayList<>(); addCollisionBoundingBox(collisionList); //noinspection RedundantIfStatement diff --git a/src/main/java/gregtech/api/multiblock/BlockPattern.java b/src/main/java/gregtech/api/multiblock/BlockPattern.java index ef874671bb2..f5f0b46f407 100644 --- a/src/main/java/gregtech/api/multiblock/BlockPattern.java +++ b/src/main/java/gregtech/api/multiblock/BlockPattern.java @@ -13,9 +13,9 @@ import net.minecraft.world.World; import org.apache.commons.lang3.tuple.Pair; -import java.util.ArrayList; import java.util.LinkedList; import java.util.List; +import java.util.Set; import java.util.function.Predicate; public class BlockPattern { @@ -102,7 +102,7 @@ public PatternMatchContext checkPatternAt(World world, BlockPos centerPos, EnumF return checkPatternAt(world, centerPos, facing, null); } - public PatternMatchContext checkPatternAt(World world, BlockPos centerPos, EnumFacing facing, List validPos) { + public PatternMatchContext checkPatternAt(World world, BlockPos centerPos, EnumFacing facing, Set validPos) { int[] countMatchesCache = new int[countMatches.length]; boolean findFirstAisle = false; int minZ = -centerOffset[4]; diff --git a/src/main/java/gregtech/api/net/CPacketPluginSynced.java b/src/main/java/gregtech/api/net/CPacketPluginSynced.java new file mode 100644 index 00000000000..f2692693192 --- /dev/null +++ b/src/main/java/gregtech/api/net/CPacketPluginSynced.java @@ -0,0 +1,65 @@ +package gregtech.api.net; + +import gregtech.api.items.behavior.MonitorPluginBaseBehavior; +import gregtech.common.metatileentities.multi.electric.centralmonitor.MetaTileEntityMonitorScreen; +import gregtech.api.metatileentity.MetaTileEntityHolder; +import net.minecraft.network.PacketBuffer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraftforge.fml.common.FMLCommonHandler; + +import java.util.function.Consumer; + +public class CPacketPluginSynced implements NetworkHandler.Packet { + public MonitorPluginBaseBehavior plugin; + public int id; + public Consumer payloadWriter; + public PacketBuffer buf; + + + public CPacketPluginSynced(MonitorPluginBaseBehavior plugin, int id, Consumer payloadWriter) { + this.plugin = plugin; + this.id = id; + this.payloadWriter = payloadWriter; + } + + CPacketPluginSynced(MonitorPluginBaseBehavior plugin, PacketBuffer buf) { + this(plugin, buf.readVarInt(), null); + this.buf = buf; + } + + public static void registerPacket(int packetId) { + NetworkHandler.registerPacket(packetId, CPacketPluginSynced.class, new NetworkHandler.PacketCodec<>( + (packet, buf) -> { + MetaTileEntityMonitorScreen screen = packet.plugin.getScreen(); + buf.writeVarInt(screen.getWorld().provider.getDimension()); + buf.writeBlockPos(screen.getPos()); + buf.writeVarInt(packet.id); + if(packet.payloadWriter != null) { + packet.payloadWriter.accept(buf); + } + }, + (buf) -> { + int dim = buf.readVarInt(); + BlockPos pos = buf.readBlockPos(); + TileEntity te = FMLCommonHandler.instance().getMinecraftServerInstance().getWorld(dim).getTileEntity(pos); + if(te instanceof MetaTileEntityHolder && ((MetaTileEntityHolder) te).getMetaTileEntity() instanceof MetaTileEntityMonitorScreen) { + MonitorPluginBaseBehavior pluginBaseBehavior = ((MetaTileEntityMonitorScreen) ((MetaTileEntityHolder) te).getMetaTileEntity()).plugin; + if (pluginBaseBehavior != null) { + return new CPacketPluginSynced(pluginBaseBehavior, buf); + } + } + return new CPacketPluginSynced(null, buf); + } + )); + } + + public static void registerExecutor() { + NetworkHandler.registerServerExecutor(CPacketPluginSynced.class, (packet, handler) -> { + if (packet.plugin != null) { + packet.plugin.readPluginAction(handler.player, packet.id, packet.buf); + } + }); + } + +} diff --git a/src/main/java/gregtech/api/net/NetworkHandler.java b/src/main/java/gregtech/api/net/NetworkHandler.java index 0c09c899ee4..ff228c4e253 100755 --- a/src/main/java/gregtech/api/net/NetworkHandler.java +++ b/src/main/java/gregtech/api/net/NetworkHandler.java @@ -8,10 +8,12 @@ import gregtech.api.gui.UIFactory; import gregtech.api.gui.impl.ModularUIContainer; import gregtech.api.gui.impl.ModularUIGui; +import gregtech.api.items.behavior.MonitorPluginBaseBehavior; import gregtech.api.metatileentity.MetaTileEntityHolder; import gregtech.api.util.ClipboardUtil; import gregtech.api.util.GTLog; import gregtech.common.metatileentities.MetaTileEntityClipboard; +import gregtech.common.metatileentities.multi.electric.centralmonitor.MetaTileEntityMonitorScreen; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import net.minecraft.block.state.IBlockState; @@ -221,6 +223,29 @@ public static void init() { } )); + registerPacket(7, CPacketPluginSynced.class, new NetworkHandler.PacketCodec<>( + (packet, buf) -> { + MetaTileEntityMonitorScreen screen = packet.plugin.getScreen(); + buf.writeVarInt(screen.getWorld().provider.getDimension()); + buf.writeBlockPos(screen.getPos()); + buf.writeVarInt(packet.id); + if(packet.payloadWriter != null) { + packet.payloadWriter.accept(buf); + } + }, + (buf) -> { + int dim = buf.readVarInt(); + BlockPos pos = buf.readBlockPos(); + TileEntity te = FMLCommonHandler.instance().getMinecraftServerInstance().getWorld(dim).getTileEntity(pos); + if(te instanceof MetaTileEntityHolder && ((MetaTileEntityHolder) te).getMetaTileEntity() instanceof MetaTileEntityMonitorScreen) { + MonitorPluginBaseBehavior pluginBaseBehavior = ((MetaTileEntityMonitorScreen) ((MetaTileEntityHolder) te).getMetaTileEntity()).plugin; + if (pluginBaseBehavior != null) { + return new CPacketPluginSynced(pluginBaseBehavior, buf); + } + } + return new CPacketPluginSynced(null, buf); + } + )); registerServerExecutor(PacketUIClientAction.class, (packet, handler) -> { Container openContainer = handler.player.openContainer; @@ -232,12 +257,18 @@ public static void init() { } }); - NetworkHandler.registerServerExecutor(PacketClipboardUIWidgetUpdate.class, (packet, handler) -> { + registerServerExecutor(PacketClipboardUIWidgetUpdate.class, (packet, handler) -> { if (packet.clipboard != null) { packet.clipboard.readUIAction(handler.player, packet.id, packet.buf); } }); + registerServerExecutor(CPacketPluginSynced.class, (packet, handler) -> { + if (packet.plugin != null) { + packet.plugin.readPluginAction(handler.player, packet.id, packet.buf); + } + }); + if (FMLCommonHandler.instance().getSide().isClient()) { initClient(); } diff --git a/src/main/java/gregtech/api/pipenet/tile/PipeCoverableImplementation.java b/src/main/java/gregtech/api/pipenet/tile/PipeCoverableImplementation.java index 399a911ac00..1b28cb3674b 100644 --- a/src/main/java/gregtech/api/pipenet/tile/PipeCoverableImplementation.java +++ b/src/main/java/gregtech/api/pipenet/tile/PipeCoverableImplementation.java @@ -157,7 +157,10 @@ public void notifyBlockUpdate() { @Override public void scheduleRenderUpdate() { - holder.markAsDirty(); + BlockPos pos = getPos(); + getWorld().markBlockRangeForRenderUpdate( + pos.getX() - 1, pos.getY() - 1, pos.getZ() - 1, + pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1); } @Override diff --git a/src/main/java/gregtech/api/render/ClipboardRenderer.java b/src/main/java/gregtech/api/render/ClipboardRenderer.java index 19ac999ff7d..69bed9eadc0 100644 --- a/src/main/java/gregtech/api/render/ClipboardRenderer.java +++ b/src/main/java/gregtech/api/render/ClipboardRenderer.java @@ -75,6 +75,7 @@ public void renderBoard(CCRenderState renderState, Matrix4 translation, IVertexO @SideOnly(Side.CLIENT) public void renderGUI(double x, double y, double z, EnumFacing rotation, MetaTileEntityClipboard clipboard, float partialTicks) { + GlStateManager.color(1,1,1,1); GlStateManager.pushMatrix(); float lastBrightnessX = OpenGlHelper.lastBrightnessX; float lastBrightnessY = OpenGlHelper.lastBrightnessY; @@ -92,6 +93,8 @@ public void renderGUI(double x, double y, double z, EnumFacing rotation, MetaTil if (clipboard.guiCache != null) { Pair result = clipboard.checkLookingAt(Minecraft.getMinecraft().player); + GlStateManager.translate(0, 0, 0.01); + GlStateManager.scale(1, 1, -1); if (result == null) { clipboard.guiCache.drawScreen(0, 0, partialTicks); } else { diff --git a/src/main/java/gregtech/api/render/Textures.java b/src/main/java/gregtech/api/render/Textures.java index f216d1a366a..73921d35886 100644 --- a/src/main/java/gregtech/api/render/Textures.java +++ b/src/main/java/gregtech/api/render/Textures.java @@ -10,6 +10,7 @@ import codechicken.lib.vec.uv.IconTransformation; import codechicken.lib.vec.uv.UVTransformationList; import gregtech.api.GTValues; +import gregtech.api.gui.resources.TextureArea; import gregtech.api.util.GTLog; import gregtech.core.hooks.BloomRenderLayerHooks; import gregtech.common.render.CrateRenderer; @@ -214,6 +215,23 @@ public class Textures { public static final SimpleOverlayRenderer CHUNK_MINER_OVERLAY = new SimpleOverlayRenderer("overlay/machine/overlay_chunk_miner"); public static final SimpleOverlayRenderer BLANK_SCREEN = new SimpleOverlayRenderer("overlay/machine/overlay_blank_screen"); + public static SimpleOverlayRenderer COVER_INTERFACE_FLUID = new SimpleOverlayRenderer("cover/cover_interface_fluid"); + public static SimpleOverlayRenderer COVER_INTERFACE_FLUID_GLASS = new SimpleOverlayRenderer("cover/cover_interface_fluid_glass"); + public static SimpleOverlayRenderer COVER_INTERFACE_ITEM = new SimpleOverlayRenderer("cover/cover_interface_item"); + public static SimpleOverlayRenderer COVER_INTERFACE_ENERGY = new SimpleOverlayRenderer("cover/cover_interface_energy"); + public static SimpleOverlayRenderer COVER_INTERFACE_MACHINE_ON = new SimpleOverlayRenderer("cover/cover_interface_machine_on"); + public static SimpleOverlayRenderer COVER_INTERFACE_MACHINE_OFF = new SimpleOverlayRenderer("cover/cover_interface_machine_off"); + public static SimpleOverlayRenderer COVER_INTERFACE_PROXY = new SimpleOverlayRenderer("cover/cover_interface_proxy"); + public static SimpleOverlayRenderer COVER_INTERFACE_WIRELESS = new SimpleOverlayRenderer("cover/cover_interface_wireless"); + public static TextureArea BUTTON_FLUID = TextureArea.fullImage("textures/blocks/cover/cover_interface_fluid_button.png"); + public static TextureArea BUTTON_ITEM = TextureArea.fullImage("textures/blocks/cover/cover_interface_item_button.png"); + public static TextureArea BUTTON_ENERGY = TextureArea.fullImage("textures/blocks/cover/cover_interface_energy_button.png"); + public static TextureArea BUTTON_MACHINE = TextureArea.fullImage("textures/blocks/cover/cover_interface_machine_button.png"); + public static TextureArea BUTTON_INTERFACE = TextureArea.fullImage("textures/blocks/cover/cover_interface_computer_button.png"); + public static TextureArea COVER_INTERFACE_MACHINE_ON_PROXY = TextureArea.fullImage("textures/blocks/cover/cover_interface_machine_on_proxy.png"); + public static TextureArea COVER_INTERFACE_MACHINE_OFF_PROXY = TextureArea.fullImage("textures/blocks/cover/cover_interface_machine_off_proxy.png"); + + static { for (int i = 0; i < VOLTAGE_CASINGS.length; i++) { String voltageName = GTValues.VN[i].toLowerCase(); diff --git a/src/main/java/gregtech/api/render/scene/FBOWorldSceneRenderer.java b/src/main/java/gregtech/api/render/scene/FBOWorldSceneRenderer.java index f6e485c2c31..410c61998e5 100644 --- a/src/main/java/gregtech/api/render/scene/FBOWorldSceneRenderer.java +++ b/src/main/java/gregtech/api/render/scene/FBOWorldSceneRenderer.java @@ -39,6 +39,11 @@ public FBOWorldSceneRenderer(World world, int resolutionWidth, int resolutionHei setFBOSize(resolutionWidth, resolutionHeight); } + public FBOWorldSceneRenderer(World world, Framebuffer fbo) { + super(world); + this.fbo = fbo; + } + public int getResolutionWidth() { return resolutionWidth; } @@ -75,12 +80,10 @@ public Vector3f blockPos2ScreenPos(BlockPos pos, boolean depth){ return winPos; } - public void render(float x, float y, float width, float height, int mouseX, int mouseY) { - mouseX = (int) (this.resolutionWidth * mouseX / width); - mouseY = (int) (this.resolutionHeight * (1 - mouseY / height)); + public void render(float x, float y, float width, float height, float mouseX, float mouseY) { // bind to FBO int lastID = bindFBO(); - super.render(0, 0, this.resolutionWidth, this.resolutionHeight, mouseX, mouseY); + super.render(0, 0, this.resolutionWidth, this.resolutionHeight, (int) (this.resolutionWidth * mouseX / width), (int) (this.resolutionHeight * (1 - mouseY / height))); // unbind FBO unbindFBO(lastID); @@ -105,6 +108,10 @@ public void render(float x, float y, float width, float height, int mouseX, int GlStateManager.bindTexture(lastID); } + public void render(float x, float y, float width, float height, int mouseX, int mouseY) { + render(x, y, width, height, (float) mouseX, (float) mouseY); + } + private int bindFBO(){ int lastID = GL11.glGetInteger(EXTFramebufferObject.GL_FRAMEBUFFER_BINDING_EXT); fbo.setFramebufferColor(0.0F, 0.0F, 0.0F, 0.0F); diff --git a/src/main/java/gregtech/api/render/scene/TrackedDummyWorld.java b/src/main/java/gregtech/api/render/scene/TrackedDummyWorld.java index e91f4057887..edeeba395d9 100644 --- a/src/main/java/gregtech/api/render/scene/TrackedDummyWorld.java +++ b/src/main/java/gregtech/api/render/scene/TrackedDummyWorld.java @@ -6,6 +6,7 @@ import net.minecraft.init.Blocks; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; import javax.annotation.Nonnull; import javax.vecmath.Vector3f; @@ -24,6 +25,7 @@ public class TrackedDummyWorld extends DummyWorld { public final Set renderedBlocks = new HashSet<>(); private Predicate renderFilter; + private final World proxyWorld; private final Vector3f minPos = new Vector3f(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE); private final Vector3f maxPos = new Vector3f(Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE); @@ -32,6 +34,14 @@ public void setRenderFilter(Predicate renderFilter) { this.renderFilter = renderFilter; } + public TrackedDummyWorld(){ + proxyWorld = null; + } + + public TrackedDummyWorld(World world){ + proxyWorld = world; + } + public void addBlocks(Map renderedBlocks) { renderedBlocks.forEach(this::addBlock); } @@ -47,7 +57,7 @@ public void addBlock(BlockPos pos, BlockInfo blockInfo) { public TileEntity getTileEntity(@Nonnull BlockPos pos) { if (renderFilter != null && !renderFilter.test(pos)) return null; - return super.getTileEntity(pos); + return proxyWorld != null ? proxyWorld.getTileEntity(pos) : super.getTileEntity(pos); } @Nonnull @@ -55,7 +65,7 @@ public TileEntity getTileEntity(@Nonnull BlockPos pos) { public IBlockState getBlockState(@Nonnull BlockPos pos) { if (renderFilter != null && !renderFilter.test(pos)) return Blocks.AIR.getDefaultState(); //return air if not rendering this block - return super.getBlockState(pos); + return proxyWorld != null ? proxyWorld.getBlockState(pos) : super.getBlockState(pos); } @Override diff --git a/src/main/java/gregtech/api/render/scene/WorldSceneRenderer.java b/src/main/java/gregtech/api/render/scene/WorldSceneRenderer.java index 2e10582d1bc..e838b0b587f 100644 --- a/src/main/java/gregtech/api/render/scene/WorldSceneRenderer.java +++ b/src/main/java/gregtech/api/render/scene/WorldSceneRenderer.java @@ -1,23 +1,20 @@ package gregtech.api.render.scene; import codechicken.lib.vec.Vector3; -import gregtech.api.gui.resources.RenderUtil; import gregtech.api.util.Position; import gregtech.api.util.PositionedRect; +import gregtech.api.util.RenderUtil; import gregtech.api.util.Size; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.*; -import net.minecraft.client.renderer.block.model.IBakedModel; import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.init.Blocks; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.BlockRenderLayer; -import net.minecraft.util.EnumBlockRenderType; -import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.Vec3d; @@ -27,13 +24,14 @@ import org.lwjgl.opengl.GL11; import org.lwjgl.util.glu.GLU; -import javax.annotation.Nullable; import javax.vecmath.Vector3f; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.nio.IntBuffer; -import java.util.*; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.Map; import java.util.function.Consumer; /** @@ -99,6 +97,9 @@ public RayTraceResult getLastTraceResult() { public void render(float x, float y, float width, float height, int mouseX, int mouseY) { // setupCamera PositionedRect positionedRect = getPositionedRect((int)x, (int)y, (int)width, (int)height); + PositionedRect mouse = getPositionedRect(mouseX, mouseY, 0, 0); + mouseX = mouse.position.x; + mouseY = mouse.position.y; setupCamera(positionedRect); // render TrackedDummyWorld drawWorld(); @@ -426,20 +427,4 @@ protected Vector3f blockPos2ScreenPos(BlockPos pos, boolean depth, int x, int y, return winPos; } - public static class BlockPosFace extends BlockPos { - public final EnumFacing facing; - - public BlockPosFace(BlockPos pos, EnumFacing facing) { - super(pos); - this.facing = facing; - } - - @Override - public boolean equals(@Nullable Object bp) { - if (bp instanceof BlockPosFace) { - return super.equals(bp) && ((BlockPosFace) bp).facing == facing; - } - return false; - } - } } diff --git a/src/main/java/gregtech/api/terminal/gui/widgets/MachineSceneWidget.java b/src/main/java/gregtech/api/terminal/gui/widgets/MachineSceneWidget.java index 0bcefed026b..fa2ffe92a92 100644 --- a/src/main/java/gregtech/api/terminal/gui/widgets/MachineSceneWidget.java +++ b/src/main/java/gregtech/api/terminal/gui/widgets/MachineSceneWidget.java @@ -12,6 +12,7 @@ import gregtech.api.render.scene.FBOWorldSceneRenderer; import gregtech.api.render.scene.WorldSceneRenderer; import gregtech.api.terminal.os.TerminalTheme; +import gregtech.api.util.BlockPosFace; import gregtech.api.util.RenderUtil; import net.minecraft.block.state.IBlockState; import net.minecraft.client.renderer.GlStateManager; @@ -20,7 +21,10 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.EnumFacing; -import net.minecraft.util.math.*; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -28,9 +32,7 @@ import org.lwjgl.opengl.GL14; import javax.vecmath.Vector3f; -import java.util.ArrayList; import java.util.HashSet; -import java.util.List; import java.util.Set; import java.util.function.BiConsumer; @@ -57,8 +59,8 @@ public class MachineSceneWidget extends WidgetGroup { private boolean blendColor = true; private Set cores; private Set around; - private WorldSceneRenderer.BlockPosFace hoverPosFace; - private WorldSceneRenderer.BlockPosFace selectedPosFace; + private BlockPosFace hoverPosFace; + private BlockPosFace selectedPosFace; private BiConsumer onSelected; protected MetaTileEntity mte; @@ -135,7 +137,7 @@ private void renderBlockOverLay(WorldSceneRenderer renderer) { double dist = eyePos.distanceTo(new Vec3d(hit.getBlockPos())); if (dist < min) { min = dist; - hoverPosFace = new WorldSceneRenderer.BlockPosFace(hit.getBlockPos(), hit.sideHit); + hoverPosFace = new BlockPosFace(hit.getBlockPos(), hit.sideHit); } } } @@ -158,9 +160,9 @@ private void renderBlockOverLay(WorldSceneRenderer renderer) { GlStateManager.tryBlendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO); } - private void drawFacingBorder(WorldSceneRenderer.BlockPosFace posFace, int color) { + private void drawFacingBorder(BlockPosFace posFace, int color) { GlStateManager.pushMatrix(); - RenderUtil.moveToFace(posFace.getX(), posFace.getY(), posFace.getZ(), posFace.facing); + RenderUtil.moveToFace(posFace.pos.getX(), posFace.pos.getY(), posFace.pos.getZ(), posFace.facing); RenderUtil.rotateToFace(posFace.facing, null); GlStateManager.scale(1f / 16, 1f / 16, 0); GlStateManager.translate(-8, -8, 0); @@ -197,7 +199,7 @@ private void updateScene() { around = new HashSet<>(); cores.add(pos); if (mte instanceof MultiblockControllerBase) { - List validPos = new ArrayList<>(); + Set validPos = new HashSet<>(); PatternMatchContext context = ((MultiblockControllerBase) mte).structurePattern .checkPatternAt(world, pos, mte.getFrontFacing().getOpposite(), validPos); if (context != null) { @@ -270,7 +272,7 @@ public boolean mouseClicked(int mouseX, int mouseY, int button) { if (hoverPosFace != null && !hoverPosFace.equals(selectedPosFace)) { selectedPosFace = hoverPosFace; if (onSelected != null) { - onSelected.accept(selectedPosFace, selectedPosFace.facing); + onSelected.accept(selectedPosFace.pos, selectedPosFace.facing); } } return true; diff --git a/src/main/java/gregtech/api/util/BlockPosFace.java b/src/main/java/gregtech/api/util/BlockPosFace.java new file mode 100644 index 00000000000..f47f3e071d8 --- /dev/null +++ b/src/main/java/gregtech/api/util/BlockPosFace.java @@ -0,0 +1,29 @@ +package gregtech.api.util; + +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; + +import javax.annotation.Nullable; + +public class BlockPosFace { + public final EnumFacing facing; + public final BlockPos pos; + + public BlockPosFace(BlockPos pos, EnumFacing facing) { + this.pos = pos; + this.facing = facing; + } + + @Override + public boolean equals(@Nullable Object bp) { + if (bp instanceof BlockPosFace) { + return pos == ((BlockPosFace) bp).pos && ((BlockPosFace) bp).facing == facing; + } + return super.equals(bp); + } + + @Override + public int hashCode() { + return pos.hashCode() + facing.hashCode(); + } +} diff --git a/src/main/java/gregtech/api/util/ParticleHandlerUtil.java b/src/main/java/gregtech/api/util/ParticleHandlerUtil.java index 0b793fe97c1..0f352c05310 100644 --- a/src/main/java/gregtech/api/util/ParticleHandlerUtil.java +++ b/src/main/java/gregtech/api/util/ParticleHandlerUtil.java @@ -23,6 +23,7 @@ public class ParticleHandlerUtil { public static void addBlockRunningEffects(World worldObj, Entity entity, TextureAtlasSprite atlasSprite, int spriteColor) { + if (atlasSprite == null) return; Random rand = new Random(); double posX = entity.posX + (rand.nextFloat() - 0.5) * entity.width; double posY = entity.getEntityBoundingBox().minY + 0.1; @@ -39,6 +40,7 @@ public static void addBlockRunningEffects(World worldObj, Entity entity, Texture } public static void addBlockLandingEffects(World worldObj, Vector3 entityPos, TextureAtlasSprite atlasSprite, int spriteColor, ParticleManager manager, int numParticles) { + if (atlasSprite == null) return; Vector3 start = entityPos.copy(); Vector3 end = start.copy().add(Vector3.down.copy().multiply(4)); RayTraceResult traceResult = worldObj.rayTraceBlocks(start.vec3(), end.vec3(), true, false, true); @@ -90,6 +92,7 @@ private static Cuboid6 getBoundingBox(IBlockState blockState, World world, RayTr //Straight copied from CustomParticleHandler with color parameter added public static void addBlockHitEffects(World world, Cuboid6 bounds, EnumFacing side, TextureAtlasSprite icon, int spriteColor, ParticleManager particleManager) { + if (icon == null) return; float border = 0.1F; Vector3 diff = bounds.max.copy().subtract(bounds.min).add(-2 * border); diff.x *= world.rand.nextDouble(); @@ -128,6 +131,7 @@ public static void addBlockHitEffects(World world, Cuboid6 bounds, EnumFacing si } public static void addBlockDestroyEffects(World world, Cuboid6 bounds, TextureAtlasSprite icon, int spriteColor, ParticleManager particleManager) { + if (icon == null) return; Vector3 diff = bounds.max.copy().subtract(bounds.min); Vector3 center = bounds.min.copy().add(bounds.max).multiply(0.5); Vector3 density = diff.copy().multiply(4).ceil(); diff --git a/src/main/java/gregtech/api/util/RenderBufferHelper.java b/src/main/java/gregtech/api/util/RenderBufferHelper.java index 12e5e50f28d..144ff7eb6be 100644 --- a/src/main/java/gregtech/api/util/RenderBufferHelper.java +++ b/src/main/java/gregtech/api/util/RenderBufferHelper.java @@ -124,20 +124,7 @@ public static void renderRing(BufferBuilder buffer, double x, double y, double z sinTheta = sinTheta1; } -// for (int i = 0; i < segments; i++) { -// double dx = r * MathHelper.cos((float) (2 * Math.PI * i / segments)); -// double dy = r * MathHelper.sin((float) (2 * Math.PI * i / segments)); -// switch (axis) { -// case Y: -// buffer.pos(x + dx, y, z + dy).color(red, green, blue, alpha).endVertex(); -// break; -// case X: -// buffer.pos(x, y + dx, z + dy).color(red, green, blue, alpha).endVertex(); -// break; -// case Z: -// buffer.pos(x + dx, y + dy, z).color(red, green, blue, alpha).endVertex(); -// break; -// } -// } } + + } diff --git a/src/main/java/gregtech/api/util/RenderUtil.java b/src/main/java/gregtech/api/util/RenderUtil.java index 2c9befe75d5..06a5bf5a381 100644 --- a/src/main/java/gregtech/api/util/RenderUtil.java +++ b/src/main/java/gregtech/api/util/RenderUtil.java @@ -1,14 +1,25 @@ package gregtech.api.util; +import codechicken.lib.texture.TextureUtils; +import codechicken.lib.vec.Matrix4; +import gregtech.api.gui.Widget; +import gregtech.api.gui.resources.TextureArea; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.ScaledResolution; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.renderer.*; import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.client.renderer.texture.TextureUtil; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.item.ItemStack; import net.minecraft.client.shader.Framebuffer; import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; import net.minecraftforge.client.GuiIngameForge; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidRegistry; +import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import org.lwjgl.opengl.GL11; @@ -17,6 +28,7 @@ import javax.annotation.Nullable; import java.awt.image.BufferedImage; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Stack; @@ -229,6 +241,320 @@ public static void bindTextureAtlasSprite(TextureAtlasSprite textureAtlasSprite) } } + /*** + * avoid z-fighting. not familiar with the CCL, its a trick. + * //TODO could DisableDepthMask in the CCL? + * @param translation origin + * @param side facing + * @param layer level + * @return adjust + */ + public static Matrix4 adjustTrans(Matrix4 translation, EnumFacing side, int layer) { + Matrix4 trans = translation.copy(); + switch (side){ + case DOWN: + trans.translate(0 , -0.001D * layer,0); + break; + case UP: + trans.translate(0 , 0.001D * layer,0); + break; + case NORTH: + trans.translate(0 , 0,-0.001D * layer); + break; + case SOUTH: + trans.translate(0 , 0,0.001D * layer); + break; + case EAST: + trans.translate(0.001D * layer, 0,0); + break; + case WEST: + trans.translate(-0.001D * layer, 0,0); + break; + } + return trans; + } + + public static void renderRect(float x, float y, float width, float height, float z, int color) { + float f3 = (float)(color >> 24 & 255) / 255.0F; + float f = (float)(color >> 16 & 255) / 255.0F; + float f1 = (float)(color >> 8 & 255) / 255.0F; + float f2 = (float)(color & 255) / 255.0F; + GlStateManager.enableBlend(); + GlStateManager.disableTexture2D(); + GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GlStateManager.color(f, f1, f2, f3); + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder buffer = tessellator.getBuffer(); + buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION); + buffer.pos(x + width, y, z).endVertex(); + buffer.pos(x, y, z).endVertex(); + buffer.pos(x, y + height, z).endVertex(); + buffer.pos(x + width, y + height, z).endVertex(); + tessellator.draw(); + GlStateManager.disableBlend(); + GlStateManager.enableTexture2D(); + GlStateManager.color(1,1,1,1); + } + + public static void renderGradientRect(float x, float y, float width, float height, float z, int startColor, int endColor, boolean horizontal) { + float startAlpha = (float) (startColor >> 24 & 255) / 255.0F; + float startRed = (float) (startColor >> 16 & 255) / 255.0F; + float startGreen = (float) (startColor >> 8 & 255) / 255.0F; + float startBlue = (float) (startColor & 255) / 255.0F; + float endAlpha = (float) (endColor >> 24 & 255) / 255.0F; + float endRed = (float) (endColor >> 16 & 255) / 255.0F; + float endGreen = (float) (endColor >> 8 & 255) / 255.0F; + float endBlue = (float) (endColor & 255) / 255.0F; + GlStateManager.disableTexture2D(); + GlStateManager.enableBlend(); + GlStateManager.disableAlpha(); + GlStateManager.tryBlendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO); + GlStateManager.shadeModel(GL11.GL_SMOOTH); + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder buffer = tessellator.getBuffer(); + buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR); + if (horizontal) { + buffer.pos(x + width, y, z).color(endRed, endGreen, endBlue, endAlpha).endVertex(); + buffer.pos(x, y, z).color(startRed, startGreen, startBlue, startAlpha).endVertex(); + buffer.pos(x, y + height, z).color(startRed, startGreen, startBlue, startAlpha).endVertex(); + buffer.pos(x + width, y + height, z).color(endRed, endGreen, endBlue, endAlpha).endVertex(); + tessellator.draw(); + } else { + buffer.pos(x + width, y, z).color(startRed, startGreen, startBlue, startAlpha).endVertex(); + buffer.pos(x, y, z).color(startRed, startGreen, startBlue, startAlpha).endVertex(); + buffer.pos(x, y + height, z).color(endRed, endGreen, endBlue, endAlpha).endVertex(); + buffer.pos(x + width, y + height, z).color(endRed, endGreen, endBlue, endAlpha).endVertex(); + tessellator.draw(); + } + GlStateManager.shadeModel(GL11.GL_FLAT); + GlStateManager.disableBlend(); + GlStateManager.enableAlpha(); + GlStateManager.enableTexture2D(); + } + + public static void renderText(float x, float y, float z, float scale, int color, final String renderedText, boolean centered) { + GlStateManager.pushMatrix(); + final FontRenderer fr = Minecraft.getMinecraft().fontRenderer; + final int width = fr.getStringWidth( renderedText ); + GlStateManager.translate(x, y - scale * 4, z); + GlStateManager.scale(scale, scale, scale); + GlStateManager.translate(-0.5f * (centered? 1:0)*width, 0.0f, 0.5f ); + + fr.drawString(renderedText, 0, 0, color); + GlStateManager.popMatrix(); + } + + public static void renderItemOverLay(float x, float y, float z, float scale, ItemStack itemStack) { + net.minecraft.client.renderer.RenderHelper.enableStandardItemLighting(); + GlStateManager.pushMatrix(); + GlStateManager.scale(scale, scale, 0.0001f); + GlStateManager.translate(x * 16, y * 16, z * 16); + RenderItem renderItem = Minecraft.getMinecraft().getRenderItem(); + renderItem.renderItemAndEffectIntoGUI(itemStack, 0, 0 ); + GlStateManager.popMatrix(); + net.minecraft.client.renderer.RenderHelper.disableStandardItemLighting(); + } + + public static void renderFluidOverLay(float x, float y, float width, float height, float z, FluidStack fluidStack, float alpha) { + if (fluidStack != null) { + int color = fluidStack.getFluid().getColor(fluidStack); + float r = (color >> 16 & 255) / 255.0f; + float g = (color >> 8 & 255) / 255.0f; + float b = (color & 255) / 255.0f; + TextureAtlasSprite sprite = TextureUtils.getTexture(fluidStack.getFluid().getStill(fluidStack)); + GlStateManager.enableBlend(); + GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); + GlStateManager.disableAlpha(); + //GlStateManager.disableLighting(); + Minecraft.getMinecraft().getTextureManager().bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); + Tessellator tess = Tessellator.getInstance(); + BufferBuilder buf = tess.getBuffer(); + + buf.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR); + double uMin = sprite.getInterpolatedU(16D - width * 16D), uMax = sprite.getInterpolatedU(width * 16D); + double vMin = sprite.getMinV(), vMax = sprite.getInterpolatedV(height * 16D); + buf.pos(x, y, z).tex(uMin, vMin).color(r, g, b, alpha).endVertex(); + buf.pos(x, y + height, z).tex(uMin, vMax).color(r, g, b, alpha).endVertex(); + buf.pos(x + width, y + height, z).tex(uMax, vMax).color(r, g, b, alpha).endVertex(); + buf.pos(x + width, y, z).tex(uMax, vMin).color(r, g, b, alpha).endVertex(); + tess.draw(); + + //GlStateManager.enableLighting(); + GlStateManager.enableAlpha(); + GlStateManager.disableBlend(); + GlStateManager.color(1F, 1F, 1F, 1F); + } + } + + public static void renderTextureArea(TextureArea textureArea, float x, float y, float width, float height, float z) { + double imageU = textureArea.offsetX; + double imageV = textureArea.offsetY; + double imageWidth = textureArea.imageWidth; + double imageHeight = textureArea.imageHeight; + Minecraft.getMinecraft().renderEngine.bindTexture(textureArea.imageLocation); + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder bufferbuilder = tessellator.getBuffer(); + bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX); + bufferbuilder.pos(x, y + height, z).tex(imageU, imageV + imageHeight).endVertex(); + bufferbuilder.pos(x + width, y + height, z).tex(imageU + imageWidth, imageV + imageHeight).endVertex(); + bufferbuilder.pos(x + width, y, z).tex(imageU + imageWidth, imageV).endVertex(); + bufferbuilder.pos(x, y, z).tex(imageU, imageV).endVertex(); + tessellator.draw(); + } + + public static void renderLineChart(List data, long max, float x, float y, float width, float height, float lineWidth, int color) { + float durX = data.size() > 1 ? width / (data.size() - 1) : 0; + float hY = max > 0 ? height / max : 0; + + GlStateManager.disableTexture2D(); + GlStateManager.enableBlend(); + GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_DST_ALPHA); + GlStateManager.color(((color >> 16) & 0xFF) / 255f, ((color >> 8) & 0xFF) / 255f, (color & 0xFF) / 255f, ((color >> 24) & 0xFF) / 255f); + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder bufferbuilder = tessellator.getBuffer(); + bufferbuilder.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION); + float last_x = x + 0 * durX; + float last_y = y - data.get(0) * hY; + for (int i = 0; i < data.size(); i++) { + float _x = x + i * durX; + float _y = y - data.get(i) * hY; + // draw lines + if (i != 0) { + bufferbuilder.pos(last_x, last_y - lineWidth, 0.01D).endVertex(); + bufferbuilder.pos(last_x, last_y + lineWidth, 0.01D).endVertex(); + bufferbuilder.pos(_x, _y + lineWidth, 0.01D).endVertex(); + bufferbuilder.pos(_x, _y - lineWidth, 0.01D).endVertex(); + last_x = _x; + last_y = _y; + } + // draw points + bufferbuilder.pos(_x - 3 * lineWidth, _y, 0.01D).endVertex(); + bufferbuilder.pos(_x, _y + 3 * lineWidth, 0.01D).endVertex(); + bufferbuilder.pos(_x + 3 * lineWidth, _y, 0.01D).endVertex(); + bufferbuilder.pos(_x, _y - 3 * lineWidth, 0.01D).endVertex(); + } + tessellator.draw(); + + GlStateManager.disableBlend(); + GlStateManager.enableTexture2D(); + } + + public static void renderLine(float x1, float y1, float x2, float y2, float lineWidth, int color) { + float hypo = (float) Math.sqrt((y1 - y2) * (y1 - y2) + (x1 - x2) * (x1 - x2)); + float w = (x2 - x1) / hypo * lineWidth; + float h = (y1 - y2) / hypo * lineWidth; + + GlStateManager.disableTexture2D(); + GlStateManager.enableBlend(); + GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_DST_ALPHA); + GlStateManager.color(((color >> 16) & 0xFF) / 255f, ((color >> 8) & 0xFF) / 255f, (color & 0xFF) / 255f, ((color >> 24) & 0xFF) / 255f); + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder bufferbuilder = tessellator.getBuffer(); + bufferbuilder.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION); + if (w * h > 0) { + bufferbuilder.pos(x1 - w, y1 - h, 0.01D).endVertex(); + bufferbuilder.pos(x1 + w, y1 + h, 0.01D).endVertex(); + bufferbuilder.pos(x2 + w, y2 + h, 0.01D).endVertex(); + bufferbuilder.pos(x2 - w, y2 - h, 0.01D).endVertex(); + } else { + h = (y2 - y1) / hypo * lineWidth; + bufferbuilder.pos(x1 + w, y1 - h, 0.01D).endVertex(); + bufferbuilder.pos(x1 - w, y1 + h, 0.01D).endVertex(); + bufferbuilder.pos(x2 - w, y2 + h, 0.01D).endVertex(); + bufferbuilder.pos(x2 + w, y2 - h, 0.01D).endVertex(); + } + tessellator.draw(); + GlStateManager.disableBlend(); + GlStateManager.enableTexture2D(); + GlStateManager.color(1,1,1,1); + } + + public static void drawFluidTexture(double xCoord, double yCoord, TextureAtlasSprite textureSprite, int maskTop, int maskRight, double zLevel) { + double uMin = textureSprite.getMinU(); + double uMax = textureSprite.getMaxU(); + double vMin = textureSprite.getMinV(); + double vMax = textureSprite.getMaxV(); + uMax = uMax - maskRight / 16.0 * (uMax - uMin); + vMax = vMax - maskTop / 16.0 * (vMax - vMin); + + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder buffer = tessellator.getBuffer(); + buffer.begin(7, DefaultVertexFormats.POSITION_TEX); + buffer.pos(xCoord, yCoord + 16, zLevel).tex(uMin, vMax).endVertex(); + buffer.pos(xCoord + 16 - maskRight, yCoord + 16, zLevel).tex(uMax, vMax).endVertex(); + buffer.pos(xCoord + 16 - maskRight, yCoord + maskTop, zLevel).tex(uMax, vMin).endVertex(); + buffer.pos(xCoord, yCoord + maskTop, zLevel).tex(uMin, vMin).endVertex(); + tessellator.draw(); + } + + public static void drawFluidForGui(FluidStack contents, int tankCapacity, int startX, int startY, int widthT, int heightT) { + widthT--; + heightT--; + Fluid fluid = contents.getFluid(); + ResourceLocation fluidStill = fluid.getStill(); + TextureAtlasSprite fluidStillSprite = Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(fluidStill.toString()); + int fluidColor = fluid.getColor(contents); + int scaledAmount = contents.amount * heightT / tankCapacity; + if (contents.amount > 0 && scaledAmount < 1) { + scaledAmount = 1; + } + if (scaledAmount > heightT || contents.amount == tankCapacity) { + scaledAmount = heightT; + } + GlStateManager.enableBlend(); + Minecraft.getMinecraft().renderEngine.bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); + setGlColorFromInt(fluidColor, 200); + + final int xTileCount = widthT / 16; + final int xRemainder = widthT - xTileCount * 16; + final int yTileCount = scaledAmount / 16; + final int yRemainder = scaledAmount - yTileCount * 16; + + final int yStart = startY + heightT; + + for (int xTile = 0; xTile <= xTileCount; xTile++) { + for (int yTile = 0; yTile <= yTileCount; yTile++) { + int width = xTile == xTileCount ? xRemainder : 16; + int height = yTile == yTileCount ? yRemainder : 16; + int x = startX + xTile * 16; + int y = yStart - (yTile + 1) * 16; + if (width > 0 && height > 0) { + int maskTop = 16 - height; + int maskRight = 16 - width; + + drawFluidTexture(x, y, fluidStillSprite, maskTop, maskRight, 0.0); + } + } + } + GlStateManager.disableBlend(); + } + + public static int packColor(int red, int green, int blue, int alpha) { + return (red & 0xFF) << 24 | (green & 0xFF) << 16 | (blue & 0xFF) << 8 | (alpha & 0xFF); + } + + public static void setGlColorFromInt(int colorValue, int opacity) { + int i = (colorValue & 16711680) >> 16; + int j = (colorValue & 65280) >> 8; + int k = (colorValue & 255); + GlStateManager.color(i / 255.0f, j / 255.0f, k / 255.0f, opacity / 255.0f); + } + + public static void setGlClearColorFromInt(int colorValue, int opacity) { + int i = (colorValue & 16711680) >> 16; + int j = (colorValue & 65280) >> 8; + int k = (colorValue & 255); + GlStateManager.clearColor(i / 255.0f, j / 255.0f, k / 255.0f, opacity / 255.0f); + } + + public static int getFluidColor(FluidStack fluidStack) { + if (fluidStack.getFluid() == FluidRegistry.WATER) + return 0x3094CF; + else if (fluidStack.getFluid() == FluidRegistry.LAVA) + return 0xFFD700; + return fluidStack.getFluid().getColor(fluidStack); + } + public static boolean updateFBOSize(Framebuffer fbo, int width, int height) { if (fbo.framebufferWidth != width || fbo.framebufferHeight != height) { fbo.createBindFramebuffer(width, height); diff --git a/src/main/java/gregtech/common/ConfigHolder.java b/src/main/java/gregtech/common/ConfigHolder.java index 465d8c6d624..61914e6fa31 100644 --- a/src/main/java/gregtech/common/ConfigHolder.java +++ b/src/main/java/gregtech/common/ConfigHolder.java @@ -99,6 +99,13 @@ public class ConfigHolder { @Config.RequiresMcRestart public static int gasTurbineBonusOutput = 6144; + @Config.Comment("The EU drain per tick for each screen.") + @Config.Name("CentralMonitor cost") + @Config.RangeInt(min = 0) + @Config.RequiresMcRestart + public static int centralMonitorEuCost = 50; + + public static class VanillaRecipes { @Config.Comment("Whether to make glass related recipes harder. Default: true") @@ -268,7 +275,7 @@ public static class EnergyCompatibility { } public static class ClientConfig { - + @Config.Comment("Terminal root path. Default: (config/)gregtech/terminal") public String terminalRootPath = "gregtech/terminal"; diff --git a/src/main/java/gregtech/common/covers/CoverBehaviors.java b/src/main/java/gregtech/common/covers/CoverBehaviors.java index 514beac72c2..a8203f076cf 100644 --- a/src/main/java/gregtech/common/covers/CoverBehaviors.java +++ b/src/main/java/gregtech/common/covers/CoverBehaviors.java @@ -16,6 +16,7 @@ import gregtech.common.covers.filter.SimpleItemFilter; import gregtech.common.covers.filter.SmartItemFilter; import gregtech.common.items.MetaItems; +import gregtech.common.items.behaviors.CoverDigitalInterfaceWirelessPlaceBehaviour; import gregtech.common.items.behaviors.CoverPlaceBehavior; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; @@ -74,6 +75,11 @@ public static void init() { registerBehavior(53, new ResourceLocation(GTValues.MODID, "crafting_table"), MetaItems.COVER_CRAFTING, CoverCraftingTable::new); registerBehavior(54, new ResourceLocation(GTValues.MODID, "infinite_water"), MetaItems.COVER_INFINITE_WATER, CoverInfiniteWater::new); registerBehavior(55, new ResourceLocation(GTValues.MODID, "ender_fluid_link"), MetaItems.COVER_ENDER_FLUID_LINK, CoverEnderFluidLink::new); + registerBehavior(56, new ResourceLocation(GTValues.MODID, "cover.digital"), MetaItems.COVER_DIGITAL_INTERFACE, CoverDigitalInterface::new); + + // Custom cover behaviour + MetaItems.COVER_DIGITAL_INTERFACE_WIRELESS.addComponents(new CoverDigitalInterfaceWirelessPlaceBehaviour(registerCover(57, new ResourceLocation(GTValues.MODID, "cover.digital.wireless"), MetaItems.COVER_DIGITAL_INTERFACE_WIRELESS, CoverDigitalInterfaceWireless::new))); + for (int i = 0; i < COVERS_PER_ITEM; i++) { int throughput = (int) (Math.pow(4, i) * 1280); @@ -89,8 +95,12 @@ public static void init() { } public static void registerBehavior(int coverNetworkId, ResourceLocation coverId, MetaValueItem placerItem, BiFunction behaviorCreator) { - CoverDefinition coverDefinition = new CoverDefinition(coverId, behaviorCreator, placerItem.getStackForm()); + placerItem.addComponents(new CoverPlaceBehavior(registerCover(coverNetworkId, coverId, placerItem, behaviorCreator))); + } + + public static CoverDefinition registerCover(int coverNetworkId, ResourceLocation coverId, MetaValueItem itemStack, BiFunction behaviorCreator) { + CoverDefinition coverDefinition = new CoverDefinition(coverId, behaviorCreator, itemStack.getStackForm()); GregTechAPI.COVER_REGISTRY.register(coverNetworkId, coverId, coverDefinition); - placerItem.addComponents(new CoverPlaceBehavior(coverDefinition)); + return coverDefinition; } } diff --git a/src/main/java/gregtech/common/covers/CoverDigitalInterface.java b/src/main/java/gregtech/common/covers/CoverDigitalInterface.java new file mode 100644 index 00000000000..73744b51791 --- /dev/null +++ b/src/main/java/gregtech/common/covers/CoverDigitalInterface.java @@ -0,0 +1,1049 @@ +package gregtech.common.covers; + +import codechicken.lib.raytracer.CuboidRayTraceResult; +import codechicken.lib.render.CCRenderState; +import codechicken.lib.render.pipeline.IVertexOperation; +import codechicken.lib.vec.Cuboid6; +import codechicken.lib.vec.Matrix4; +import codechicken.lib.vec.Rotation; +import gregtech.api.capability.*; +import gregtech.api.capability.impl.*; +import gregtech.api.cover.CoverBehavior; +import gregtech.api.cover.CoverWithUI; +import gregtech.api.cover.ICoverable; +import gregtech.api.gui.GuiTextures; +import gregtech.api.gui.ModularUI; +import gregtech.api.gui.widgets.*; +import gregtech.api.metatileentity.IFastRenderMetaTileEntity; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.MetaTileEntityHolder; +import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; +import gregtech.api.render.Textures; +import gregtech.api.util.Position; +import gregtech.api.util.RenderUtil; +import gregtech.common.ConfigHolder; +import gregtech.common.terminal.app.prospector.widget.WidgetOreList; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.*; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.Vec3d; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.energy.CapabilityEnergy; +import net.minecraftforge.energy.IEnergyStorage; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidUtil; +import net.minecraftforge.fluids.IFluidTank; +import net.minecraftforge.fluids.capability.CapabilityFluidHandler; +import net.minecraftforge.fluids.capability.FluidTankProperties; +import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.fluids.capability.IFluidTankProperties; +import net.minecraftforge.fml.common.ObfuscationReflectionHelper; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import net.minecraftforge.items.CapabilityItemHandler; +import net.minecraftforge.items.IItemHandler; +import net.minecraftforge.items.IItemHandlerModifiable; +import org.apache.commons.lang3.ArrayUtils; + +import java.io.IOException; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.UUID; + +public class CoverDigitalInterface extends CoverBehavior implements IFastRenderMetaTileEntity, ITickable, CoverWithUI { + + public enum MODE { + FLUID, + ITEM, + ENERGY, + MACHINE, + PROXY; + public static MODE[] VALUES; + + static { + VALUES = MODE.values(); + } + } + + // run-time data + private FluidTankProperties[] fluids = new FluidTankProperties[0]; + private ItemStack[] items = new ItemStack[0]; + private int maxItemCapability = 0; + private long energyStored = 0; + private long energyCapability = 0; + private long energyInputPerDur = 0; + private long energyOutputPerDur = 0; + private final List inputEnergyList = new LinkedList<>(); + private final List outputEnergyList = new LinkedList<>(); + private int progress = 0; + private int maxProgress = 0; + private boolean isActive = true; + private boolean isWorkingEnabled = false; + private long lastClickTime; + private UUID lastClickUUID; + // persistent data + protected int slot = 0; + protected MODE mode = MODE.PROXY; + protected EnumFacing spin = EnumFacing.NORTH; + protected final int[] proxyMode = new int[]{0, 0, 0, 0}; // server-only + + + public CoverDigitalInterface(ICoverable coverHolder, EnumFacing attachedSide) { + super(coverHolder, attachedSide); + } + + public MODE getMode() { + return mode; + } + + public boolean isProxy() { + return mode == MODE.PROXY; + } + + public void setMode(MODE mode, int slot, EnumFacing spin) { + if (this.mode == mode && (this.slot == slot || slot < 0) && this.spin == spin) return; + if (!isRemote()) { + if (this.mode != MODE.PROXY && mode == MODE.PROXY) { + proxyMode[0] = 0; + proxyMode[1] = 0; + proxyMode[2] = 0; + proxyMode[3] = 0; + } + this.mode = mode; + this.slot = slot; + this.spin = spin; + writeUpdateData(GregtechDataCodes.UPDATE_MODE, packetBuffer -> { + packetBuffer.writeByte(mode.ordinal()); + packetBuffer.writeInt(slot); + packetBuffer.writeByte(spin.getIndex()); + }); + if (this.coverHolder != null) { + this.coverHolder.notifyBlockUpdate(); + this.coverHolder.markDirty(); + } + } else { + if ((this.mode != mode || this.spin != spin) && this.coverHolder != null) { + this.coverHolder.scheduleRenderUpdate(); + } + this.mode = mode; + this.slot = slot; + this.spin = spin; + } + } + + public void setMode(EnumFacing spin) { + this.setMode(this.mode, this.slot, spin); + } + + public void setMode(int slot) { + this.setMode(this.mode, slot, this.spin); + } + + public void setMode(MODE mode) { + this.setMode(mode, this.slot, this.spin); + } + + public boolean subProxyMode(MODE mode) { + if (this.mode == MODE.PROXY) { + proxyMode[mode.ordinal()]++; + this.markAsDirty(); + return true; + } + return false; + } + + public boolean unSubProxyMode(MODE mode) { + if (this.mode == MODE.PROXY) { + if (proxyMode[mode.ordinal()] > 0) { + proxyMode[mode.ordinal()]--; + this.markAsDirty(); + return true; + } + } + return false; + } + + public TileEntity getCoveredTE() { + if (this.coverHolder instanceof MetaTileEntity){ + return ((MetaTileEntity) this.coverHolder).getHolder(); + } + return null; + } + + public EnumFacing getCoveredFacing() { + return this.attachedSide; + } + + @Override + public void writeToNBT(NBTTagCompound tagCompound) { + super.writeToNBT(tagCompound); + tagCompound.setByte("cdiMode", (byte) this.mode.ordinal()); + tagCompound.setByte("cdiSpin", (byte) this.spin.ordinal()); + tagCompound.setInteger("cdiSlot", this.slot); + tagCompound.setInteger("cdi0", this.proxyMode[0]); + tagCompound.setInteger("cdi1", this.proxyMode[1]); + tagCompound.setInteger("cdi2", this.proxyMode[2]); + tagCompound.setInteger("cdi3", this.proxyMode[3]); + } + + @Override + public void readFromNBT(NBTTagCompound tagCompound) { + super.readFromNBT(tagCompound); + this.mode = tagCompound.hasKey("cdiMode") ? MODE.VALUES[tagCompound.getByte("cdiMode")] : MODE.PROXY; + this.spin = tagCompound.hasKey("cdiSpin") ? EnumFacing.byIndex(tagCompound.getByte("cdiSpin")) : EnumFacing.NORTH; + this.slot = tagCompound.hasKey("cdiSlot") ? tagCompound.getInteger("cdiSlot") : 0; + this.proxyMode[0] = tagCompound.hasKey("cdi0") ? tagCompound.getInteger("cdi0") : 0; + this.proxyMode[1] = tagCompound.hasKey("cdi1") ? tagCompound.getInteger("cdi1") : 0; + this.proxyMode[2] = tagCompound.hasKey("cdi2") ? tagCompound.getInteger("cdi2") : 0; + this.proxyMode[3] = tagCompound.hasKey("cdi3") ? tagCompound.getInteger("cdi3") : 0; + } + + @Override + public void onAttached(ItemStack itemStack) { // called when cover placed. + if (getFluidCapability() != null) { + fluids = new FluidTankProperties[getFluidCapability().getTankProperties().length]; + this.mode = MODE.FLUID; + } else if (getItemCapability() != null) { + items = new ItemStack[getItemCapability().getSlots()]; + this.mode = MODE.ITEM; + } else if (getEnergyCapability() != null) { + this.mode = MODE.ENERGY; + } else if (getMachineCapability() != null) { + this.mode = MODE.MACHINE; + } + } + + @Override + public void writeInitialSyncData(PacketBuffer packetBuffer) { + super.writeInitialSyncData(packetBuffer); + packetBuffer.writeEnumValue(mode); + packetBuffer.writeEnumValue(spin); + packetBuffer.writeInt(slot); + syncAllInfo(); + writeAllFluids(packetBuffer); + writeAllItems(packetBuffer); + packetBuffer.writeInt(maxItemCapability); + packetBuffer.writeLong(energyStored); + packetBuffer.writeLong(energyCapability); + packetBuffer.writeInt(inputEnergyList.size()); + for (Long aLong : inputEnergyList) { + packetBuffer.writeLong(aLong); + } + for (Long aLong : outputEnergyList) { + packetBuffer.writeLong(aLong); + } + packetBuffer.writeInt(progress); + packetBuffer.writeInt(maxProgress); + packetBuffer.writeBoolean(isActive); + packetBuffer.writeBoolean(isWorkingEnabled); + } + + @Override + public void readInitialSyncData(PacketBuffer packetBuffer) { + super.readInitialSyncData(packetBuffer); + this.mode = packetBuffer.readEnumValue(MODE.class); + this.spin = packetBuffer.readEnumValue(EnumFacing.class); + this.slot = packetBuffer.readInt(); + readFluids(packetBuffer); + readItems(packetBuffer); + maxItemCapability = packetBuffer.readInt(); + energyStored = packetBuffer.readLong(); + energyCapability = packetBuffer.readLong(); + int size = packetBuffer.readInt(); + inputEnergyList.clear(); + outputEnergyList.clear(); + for (int i = 0; i < size; i++) { + inputEnergyList.add(packetBuffer.readLong()); + } + for (int i = 0; i < size; i++) { + outputEnergyList.add(packetBuffer.readLong()); + } + progress = packetBuffer.readInt(); + maxProgress = packetBuffer.readInt(); + isActive = packetBuffer.readBoolean(); + isWorkingEnabled = packetBuffer.readBoolean(); + } + + @Override + public void update() { + if (!isRemote() && coverHolder.getOffsetTimer() % 2 ==0) { + syncAllInfo(); + } + } + + @Override + public EnumActionResult onScrewdriverClick(EntityPlayer playerIn, EnumHand hand, CuboidRayTraceResult hitResult) { + if (!this.coverHolder.getWorld().isRemote) { + this.openUI((EntityPlayerMP) playerIn); + } + return EnumActionResult.SUCCESS; + } + + @Override + public EnumActionResult onRightClick(EntityPlayer playerIn, EnumHand hand, CuboidRayTraceResult rayTraceResult) { + if (!isRemote()) { + if (this.coverHolder.getWorld().getTotalWorldTime() - lastClickTime < 2 && playerIn.getPersistentID().equals(lastClickUUID)) { + return EnumActionResult.SUCCESS; + } + lastClickTime = this.coverHolder.getWorld().getTotalWorldTime(); + lastClickUUID = playerIn.getPersistentID(); + if (playerIn.isSneaking() && playerIn.getHeldItemMainhand().isEmpty()) { + if (rayTraceResult != null && rayTraceResult.typeOfHit == RayTraceResult.Type.BLOCK) { + double x = 0; + double y = 1 - rayTraceResult.hitVec.y + rayTraceResult.getBlockPos().getY(); + if (rayTraceResult.sideHit == EnumFacing.EAST) { + x = 1 - rayTraceResult.hitVec.z + rayTraceResult.getBlockPos().getZ(); + } else if (rayTraceResult.sideHit == EnumFacing.SOUTH) { + x = rayTraceResult.hitVec.x - rayTraceResult.getBlockPos().getX(); + } else if (rayTraceResult.sideHit == EnumFacing.WEST) { + x = rayTraceResult.hitVec.z - rayTraceResult.getBlockPos().getZ(); + } else if (rayTraceResult.sideHit == EnumFacing.NORTH) { + x = 1 - rayTraceResult.hitVec.x + rayTraceResult.getBlockPos().getX(); + } + if (1f / 16 < x && x < 4f / 16 && 1f / 16 < y && y < 4f / 16) { + this.setMode(this.slot - 1); + return EnumActionResult.SUCCESS; + } else if (12f / 16 < x && x < 15f / 16 && 1f / 16 < y && y < 4f / 16) { + this.setMode(this.slot + 1); + return EnumActionResult.SUCCESS; + } + } + } + return modeRightClick(playerIn, hand, this.mode, this.slot); + } + return EnumActionResult.PASS; + } + + @Override + public boolean onLeftClick(EntityPlayer entityPlayer, CuboidRayTraceResult hitResult) { + if (!isRemote()) { + if (this.coverHolder.getWorld().getTotalWorldTime() - lastClickTime < 2 && entityPlayer.getPersistentID().equals(lastClickUUID)) { + return true; + } + lastClickTime = this.coverHolder.getWorld().getTotalWorldTime(); + lastClickUUID = entityPlayer.getPersistentID(); + return modeLeftClick(entityPlayer, this.mode, this.slot); + } + return false; + } + + public EnumActionResult modeRightClick(EntityPlayer playerIn, EnumHand hand, MODE mode, int slot) { + IFluidHandler fluidHandler = this.getFluidCapability(); + if (mode == MODE.FLUID && fluidHandler != null) { + if (!FluidUtil.interactWithFluidHandler(playerIn, hand, fluidHandler)) { + if (fluidHandler instanceof FluidHandlerProxy && FluidUtil.interactWithFluidHandler(playerIn, hand, ((FluidHandlerProxy) fluidHandler).input)) { + return EnumActionResult.SUCCESS; + } + return EnumActionResult.PASS; + } + return EnumActionResult.SUCCESS; + } + IItemHandler itemHandler = this.getItemCapability(); + if (mode == MODE.ITEM && itemHandler != null) { + if (itemHandler.getSlots() > slot && slot >= 0) { + ItemStack hold = playerIn.getHeldItemMainhand(); + if (!hold.isEmpty()) { + ItemStack origin = hold.copy(); + boolean flag = false; + if (playerIn.isSneaking()) { + int size = playerIn.getHeldItemMainhand().getCount(); + playerIn.setHeldItem(EnumHand.MAIN_HAND, itemHandler.insertItem(slot, hold, false)); + flag = playerIn.getHeldItemMainhand().getCount() != size; + } else { + ItemStack itemStack = hold.copy(); + itemStack.setCount(1); + if (itemHandler.insertItem(slot, itemStack, false).isEmpty()) { + hold.setCount(hold.getCount() - 1); + flag = true; + } + } + if (playerIn.getHeldItemMainhand().isEmpty()) { + for (ItemStack itemStack : playerIn.inventory.mainInventory) { + if (origin.isItemEqual(itemStack)) { + playerIn.setHeldItem(EnumHand.MAIN_HAND, itemStack.copy()); + itemStack.setCount(0); + break; + } + } + } + return flag ? EnumActionResult.SUCCESS : EnumActionResult.PASS; + } + } + return EnumActionResult.PASS; + } + IWorkable workable = this.getMachineCapability(); + if (mode == MODE.MACHINE && workable != null) { + if (playerIn.isSneaking()) { + workable.setWorkingEnabled(!isWorkingEnabled); + return EnumActionResult.SUCCESS; + } + } + return EnumActionResult.PASS; + } + + public boolean modeLeftClick(EntityPlayer entityPlayer, MODE mode, int slot) { + IItemHandler itemHandler = this.getItemCapability(); + if (mode == MODE.ITEM && itemHandler != null) { + if (itemHandler.getSlots() > slot && slot >= 0) { + ItemStack itemStack; + if (entityPlayer.isSneaking()) { + itemStack = itemHandler.extractItem(slot, 64, false); + } else { + itemStack = itemHandler.extractItem(slot, 1, false); + } + if (itemStack.isEmpty() && itemHandler instanceof ItemHandlerProxy) { + IItemHandler insertHandler = ObfuscationReflectionHelper.getPrivateValue(ItemHandlerProxy.class, (ItemHandlerProxy) itemHandler, "insertHandler"); + if (slot < insertHandler.getSlots()) { + if (entityPlayer.isSneaking()) { + itemStack = insertHandler.extractItem(slot, 64, false); + } else { + itemStack = insertHandler.extractItem(slot, 1, false); + } + } + } + if (!itemStack.isEmpty()) { + EntityItem entity = new EntityItem(entityPlayer.world, entityPlayer.posX + .5f, entityPlayer.posY + .3f, entityPlayer.posZ + .5f, itemStack); + entity.addVelocity(-entity.motionX, -entity.motionY, -entity.motionZ); + entityPlayer.world.spawnEntity(entity); + } + } + return true; + } + return false; + } + + @Override + public ModularUI createUI(EntityPlayer player) { + WidgetGroup primaryGroup = new WidgetGroup(new Position(0, 10)); + primaryGroup.addWidget(new LabelWidget(10, 5, "metaitem.cover.digital.name", 0)); + ToggleButtonWidget[] buttons = new ToggleButtonWidget[5]; + buttons[0] = new ToggleButtonWidget(40, 20, 20, 20, Textures.BUTTON_FLUID, () -> this.mode == MODE.FLUID, (pressed) -> { + if (pressed) setMode(MODE.FLUID); + }).setTooltipText("metaitem.cover.digital.mode.fluid"); + buttons[1] = new ToggleButtonWidget(60, 20, 20, 20, Textures.BUTTON_ITEM, () -> this.mode == MODE.ITEM, (pressed) -> { + if (pressed) setMode(MODE.ITEM); + }).setTooltipText("metaitem.cover.digital.mode.item"); + buttons[2] = new ToggleButtonWidget(80, 20, 20, 20, Textures.BUTTON_ENERGY, () -> this.mode == MODE.ENERGY, (pressed) -> { + if (pressed) setMode(MODE.ENERGY); + }).setTooltipText("metaitem.cover.digital.mode.energy"); + buttons[3] = new ToggleButtonWidget(100, 20, 20, 20, Textures.BUTTON_MACHINE, () -> this.mode == MODE.MACHINE, (pressed) -> { + if (pressed) setMode(MODE.MACHINE); + }).setTooltipText("metaitem.cover.digital.mode.machine"); + buttons[4] = new ToggleButtonWidget(140, 20, 20, 20, Textures.BUTTON_INTERFACE, () -> this.mode == MODE.PROXY, (pressed) -> { + if (pressed) setMode(MODE.PROXY); + }).setTooltipText("metaitem.cover.digital.mode.proxy"); + primaryGroup.addWidget(new LabelWidget(10, 25, "metaitem.cover.digital.title.mode", 0)); + primaryGroup.addWidget(buttons[0]); + primaryGroup.addWidget(buttons[1]); + primaryGroup.addWidget(buttons[2]); + primaryGroup.addWidget(buttons[3]); + primaryGroup.addWidget(buttons[4]); + + primaryGroup.addWidget(new LabelWidget(10, 50, "monitor.gui.title.slot", 0)); + primaryGroup.addWidget(new ClickButtonWidget(40, 45, 20, 20, "-1", (data) -> setMode(slot - (data.isShiftClick ? 10 : 1)))); + primaryGroup.addWidget(new ClickButtonWidget(140, 45, 20, 20, "+1", (data) -> setMode(slot + (data.isShiftClick ? 10 : 1)))); + primaryGroup.addWidget(new ImageWidget(60, 45, 80, 20, GuiTextures.DISPLAY)); + primaryGroup.addWidget(new SimpleTextWidget(100, 55, "", 16777215, () -> Integer.toString(this.slot))); + + primaryGroup.addWidget(new LabelWidget(10, 75, "metaitem.cover.digital.title.spin", 0)); + primaryGroup.addWidget(new ClickButtonWidget(40, 70, 20, 20, "R", (data) -> setMode(this.spin.rotateY()))); + primaryGroup.addWidget(new ImageWidget(60, 70, 80, 20, GuiTextures.DISPLAY)); + primaryGroup.addWidget(new SimpleTextWidget(100, 80, "", 16777215, () -> this.spin.toString())); + ModularUI.Builder builder = ModularUI.builder(GuiTextures.BACKGROUND, 176, 202).widget(primaryGroup).bindPlayerInventory(player.inventory, GuiTextures.SLOT, 8, 120); + return builder.build(this, player); + } + + private void syncAllInfo() { + if (mode == MODE.FLUID || (mode == MODE.PROXY && proxyMode[0] > 0)) { + boolean syncFlag = false; + IFluidHandler fluidHandler = this.getFluidCapability(); + if (fluidHandler != null) { + IFluidTankProperties[] fluidTankProperties = fluidHandler.getTankProperties(); + if (fluidTankProperties.length != fluids.length) { + fluids = new FluidTankProperties[fluidTankProperties.length]; + syncFlag = true; + } + List toUpdate = new ArrayList<>(); + for (int i = 0; i < fluidTankProperties.length; i++) { + FluidStack content = fluidTankProperties[i].getContents(); + if (fluids[i] == null || (content == null && fluids[i].getContents() != null) || (content != null && fluids[i].getContents() == null) || + fluidTankProperties[i].getCapacity() != fluids[i].getCapacity() || + fluidTankProperties[i].canDrain() != fluids[i].canDrain() || + fluidTankProperties[i].canFill() != fluids[i].canFill()) { + syncFlag = true; + fluids[i] = new FluidTankProperties(content, fluidTankProperties[i].getCapacity(), fluidTankProperties[i].canFill(), fluidTankProperties[i].canDrain()); + toUpdate.add(i); + } else if(content != null && (content.amount != fluids[i].getContents().amount || !content.isFluidEqual(fluids[i].getContents()))) { + syncFlag = true; + fluids[i] = new FluidTankProperties(content, fluidTankProperties[i].getCapacity(), fluidTankProperties[i].canFill(), fluidTankProperties[i].canDrain()); + toUpdate.add(i); + } + } + if (syncFlag) writeUpdateData(GregtechDataCodes.UPDATE_FLUID, packetBuffer->{ + packetBuffer.writeVarInt(fluids.length); + packetBuffer.writeVarInt(toUpdate.size()); + for (Integer index : toUpdate) { + writeFluid(packetBuffer, index); + } + }); + } + } + if (mode == MODE.ITEM || (mode == MODE.PROXY && proxyMode[1] > 0)) { + boolean syncFlag = false; + IItemHandler itemHandler = this.getItemCapability(); + if(itemHandler != null) { + int size = itemHandler.getSlots(); + if (this.slot < size) { + int maxStoredItems = itemHandler.getSlotLimit(this.slot); + if (maxStoredItems != maxItemCapability) { + maxItemCapability = maxStoredItems; + syncFlag = true; + } + } + List toUpdate = new ArrayList<>(); + if (items.length != size) { + items = new ItemStack[size]; + syncFlag = true; + } + for (int i = 0; i < size; i++) { + if (items[i] == null) { + items[i] = ItemStack.EMPTY; + } + ItemStack content = itemHandler.getStackInSlot(i); + if (!ItemStack.areItemStacksEqual(items[i], content)) { + syncFlag = true; + items[i] = content.copy(); + toUpdate.add(i); + } + } + if (syncFlag) writeUpdateData(GregtechDataCodes.UPDATE_ITEM, packetBuffer -> { + packetBuffer.writeVarInt(maxItemCapability); + packetBuffer.writeVarInt(items.length); + packetBuffer.writeVarInt(toUpdate.size()); + for (Integer index : toUpdate) { + packetBuffer.writeVarInt(index); + packetBuffer.writeCompoundTag(fixItemStackSer(items[index])); + } + }); + } + } + if (this.mode == MODE.ENERGY || (mode == MODE.PROXY && proxyMode[2] > 0)) { + IEnergyContainer energyContainer = this.getEnergyCapability(); + if (energyContainer != null) { + if (energyStored != energyContainer.getEnergyStored() || energyCapability != energyContainer.getEnergyCapacity()) { + energyStored = energyContainer.getEnergyStored(); + energyCapability = energyContainer.getEnergyCapacity(); + writeUpdateData(GregtechDataCodes.UPDATE_ENERGY, packetBuffer -> { + packetBuffer.writeLong(energyStored); + packetBuffer.writeLong(energyCapability); + }); + } + if (this.coverHolder.getOffsetTimer() % 20 == 0) { //per second + writeUpdateData(GregtechDataCodes.UPDATE_ENERGY_PER, packetBuffer -> { + packetBuffer.writeLong(energyContainer.getInputPerSec()); + packetBuffer.writeLong(energyContainer.getOutputPerSec()); + inputEnergyList.add(energyInputPerDur); + outputEnergyList.add(energyOutputPerDur); + if (inputEnergyList.size() > 13) { + inputEnergyList.remove(0); + outputEnergyList.remove(0); + } + }); + } + } + } + if (this.mode == MODE.MACHINE || (mode == MODE.PROXY && proxyMode[3] > 0)) { + IWorkable workable = this.getMachineCapability(); + if (workable != null) { + int progress = workable.getProgress(); + int maxProgress = workable.getMaxProgress(); + boolean isActive = workable.isActive(); + boolean isWorkingEnable = workable.isWorkingEnabled(); + if (isActive != this.isActive || isWorkingEnable != this.isWorkingEnabled || this.progress != progress || this.maxProgress != maxProgress) { + this.progress = progress; + this.maxProgress = maxProgress; + this.isWorkingEnabled = isWorkingEnable; + this.isActive = isActive; + writeUpdateData(GregtechDataCodes.UPDATE_MACHINE, packetBuffer -> { + packetBuffer.writeInt(progress); + packetBuffer.writeInt(maxProgress); + packetBuffer.writeBoolean(isActive); + packetBuffer.writeBoolean(isWorkingEnable); + }); + } + if (this.coverHolder.getOffsetTimer() % 20 == 0) { + IEnergyContainer energyContainer = this.getEnergyCapability(); + if (energyContainer != null) { + if (energyStored != energyContainer.getEnergyStored() || energyCapability != energyContainer.getEnergyCapacity()) { + energyStored = energyContainer.getEnergyStored(); + energyCapability = energyContainer.getEnergyCapacity(); + writeUpdateData(GregtechDataCodes.UPDATE_ENERGY, packetBuffer -> { + packetBuffer.writeLong(energyStored); + packetBuffer.writeLong(energyCapability); + }); + } + } + } + } + } + } + + private void writeAllFluids(PacketBuffer packetBuffer) { + packetBuffer.writeVarInt(fluids.length); + packetBuffer.writeVarInt(fluids.length); + for (int i = 0; i < fluids.length; i++) { + writeFluid(packetBuffer, i); + } + } + + private void writeFluid(PacketBuffer packetBuffer, int i) { + packetBuffer.writeVarInt(i); + NBTTagCompound nbt = new NBTTagCompound(); + nbt.setInteger("Capacity", fluids[i].getCapacity()); + FluidStack fluidStack = fluids[i].getContents(); + if (fluidStack != null) { + fluidStack.writeToNBT(nbt); + } + packetBuffer.writeCompoundTag(nbt); + } + + private void readFluids(PacketBuffer packetBuffer) { + int size = packetBuffer.readVarInt(); + if (fluids == null || fluids.length != size) { + fluids = new FluidTankProperties[size]; + } + size = packetBuffer.readVarInt(); + try { + for (int i = 0; i < size; i++) { + int index = packetBuffer.readVarInt(); + NBTTagCompound nbt = packetBuffer.readCompoundTag(); + if (nbt != null) { + fluids[index] = new FluidTankProperties(FluidStack.loadFluidStackFromNBT(nbt), nbt.getInteger("Capacity")); + } + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void writeAllItems(PacketBuffer packetBuffer) { + packetBuffer.writeVarInt(maxItemCapability); + packetBuffer.writeVarInt(items.length); + packetBuffer.writeVarInt(items.length); + for (int i = 0; i < items.length; i++) { + packetBuffer.writeVarInt(i); + packetBuffer.writeCompoundTag(fixItemStackSer(items[i])); + } + } + + private void readItems(PacketBuffer packetBuffer) { + maxItemCapability = packetBuffer.readVarInt(); + int size = packetBuffer.readVarInt(); + if(items == null || items.length != size) { + items = new ItemStack[size]; + } + size = packetBuffer.readVarInt(); + try { + for (int i = 0; i < size; i++) { + int index = packetBuffer.readVarInt(); + NBTTagCompound nbt = packetBuffer.readCompoundTag(); + if (nbt != null) { + items[index] = new ItemStack(nbt); + items[index].setCount(nbt.getInteger("count")); + } else { + items [index] = ItemStack.EMPTY; + } + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static NBTTagCompound fixItemStackSer(ItemStack itemStack) { + NBTTagCompound nbt = itemStack.serializeNBT(); + nbt.setInteger("count", itemStack.getCount()); + return nbt; + } + + public IFluidHandler getFluidCapability() { + TileEntity te = getCoveredTE(); + IFluidHandler capability = te == null ? null : te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, getCoveredFacing()); + if (capability == null && this.coverHolder instanceof MultiblockControllerBase) { + List input = ((MultiblockControllerBase) this.coverHolder).getAbilities(MultiblockAbility.IMPORT_FLUIDS); + List output = ((MultiblockControllerBase) this.coverHolder).getAbilities(MultiblockAbility.EXPORT_FLUIDS); + List list = new ArrayList<>(); + if (input.size() > 0) { + list.addAll(input); + } + if (output.size() > 0) { + list.addAll(output); + } + capability = new FluidTankList(true, list); + } + return capability; + } + + public IItemHandler getItemCapability() { + TileEntity te = getCoveredTE(); + IItemHandler capability = te == null ? null : te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, getCoveredFacing()); + if (capability == null && this.coverHolder instanceof MultiblockControllerBase) { + List input = ((MultiblockControllerBase) this.coverHolder).getAbilities(MultiblockAbility.IMPORT_ITEMS); + List output = ((MultiblockControllerBase) this.coverHolder).getAbilities(MultiblockAbility.EXPORT_ITEMS); + List list = new ArrayList<>(); + if (input.size() > 0) { + list.addAll(input); + } + if (output.size() > 0) { + list.addAll(output); + } + capability = new ItemHandlerList(list); + } + return capability; + } + + public IEnergyContainer getEnergyCapability() { + TileEntity te = getCoveredTE(); + IEnergyContainer capability = te == null ? null : te.getCapability(GregtechCapabilities.CAPABILITY_ENERGY_CONTAINER, getCoveredFacing()); + if (capability == null && this.coverHolder instanceof MultiblockControllerBase) { + List input = ((MultiblockControllerBase) this.coverHolder).getAbilities(MultiblockAbility.INPUT_ENERGY); + List output = ((MultiblockControllerBase) this.coverHolder).getAbilities(MultiblockAbility.OUTPUT_ENERGY); + List list = new ArrayList<>(); + if (input.size() > 0) { + list.addAll(input); + } + if (output.size() > 0) { + list.addAll(output); + } + capability = new EnergyContainerList(list); + } else if (capability == null && te != null) { + IEnergyStorage fe = te.getCapability(CapabilityEnergy.ENERGY, getCoveredFacing()); + if(fe != null) { + return new IEnergyContainer() { + public long acceptEnergyFromNetwork(EnumFacing enumFacing, long l, long l1) { + return 0; + } + public boolean inputsEnergy(EnumFacing enumFacing) { + return false; + } + public long changeEnergy(long l) { + return 0; + } + public long getEnergyStored() { + return (long) (fe.getEnergyStored() / ConfigHolder.U.energyOptions.rfRatio); + } + public long getEnergyCapacity() { + return (long) (fe.getMaxEnergyStored() / ConfigHolder.U.energyOptions.rfRatio); + } + public long getInputAmperage() { + return 0; + } + public long getInputVoltage() { + return 0; + } + }; + } + } + return capability; + } + + public IWorkable getMachineCapability() { + TileEntity te = getCoveredTE(); + return te == null ? null : te.getCapability(GregtechTileCapabilities.CAPABILITY_WORKABLE, getCoveredFacing()); + } + + + @Override + public void readUpdateData(int id, PacketBuffer packetBuffer) { + super.readUpdateData(id, packetBuffer); + if (id == GregtechDataCodes.UPDATE_MODE) { // set mode + setMode(MODE.VALUES[packetBuffer.readByte()], packetBuffer.readInt(), EnumFacing.byIndex(packetBuffer.readByte())); + } else if (id == GregtechDataCodes.UPDATE_FLUID) { // sync fluids + readFluids(packetBuffer); + } else if (id == GregtechDataCodes.UPDATE_ITEM) { + readItems(packetBuffer); + } else if (id == GregtechDataCodes.UPDATE_ENERGY) { + energyStored = packetBuffer.readLong(); + energyCapability = packetBuffer.readLong(); + } else if (id == GregtechDataCodes.UPDATE_ENERGY_PER) { + energyInputPerDur = packetBuffer.readLong(); + energyOutputPerDur = packetBuffer.readLong(); + inputEnergyList.add(energyInputPerDur); + outputEnergyList.add(energyOutputPerDur); + if (inputEnergyList.size() > 13) { + inputEnergyList.remove(0); + outputEnergyList.remove(0); + } + } else if (id == GregtechDataCodes.UPDATE_MACHINE) { + this.progress = packetBuffer.readInt(); + this.maxProgress = packetBuffer.readInt(); + this.isActive = packetBuffer.readBoolean(); + boolean isWorkingEnable = packetBuffer.readBoolean(); + if (this.isWorkingEnabled != isWorkingEnable && this.mode == MODE.MACHINE) { + this.isWorkingEnabled = isWorkingEnable; + this.coverHolder.scheduleRenderUpdate(); + } + this.isWorkingEnabled = isWorkingEnable; + } + } + + @Override + public boolean canPipePassThrough() { + return true; + } + + @Override + public boolean canAttach() { + return canCapabilityAttach(); + } + + public boolean canCapabilityAttach() { + return getFluidCapability() != null || + getItemCapability() != null || + getEnergyCapability() != null || + getMachineCapability() != null; + } + + @Override + public T getCapability(Capability capability, T defaultValue) { + if (this.mode == MODE.PROXY) { + if (capability == GregtechCapabilities.CAPABILITY_ENERGY_CONTAINER && defaultValue == null) { + return GregtechCapabilities.CAPABILITY_ENERGY_CONTAINER.cast(IEnergyContainer.DEFAULT); + } + } + return defaultValue; + } + + @Override + public void renderCover(CCRenderState ccRenderState, Matrix4 translation, IVertexOperation[] ops, Cuboid6 cuboid6, BlockRenderLayer blockRenderLayer) { + codechicken.lib.vec.Rotation rotation = new codechicken.lib.vec.Rotation(0, 0, 1, 0); + if (this.attachedSide == EnumFacing.UP || this.attachedSide == EnumFacing.DOWN) { + if (this.spin == EnumFacing.WEST) { + translation.translate(0, 0, 1); + rotation = new codechicken.lib.vec.Rotation(Math.PI / 2, 0, 1, 0); + } else if (this.spin == EnumFacing.EAST) { + translation.translate(1, 0, 0); + rotation = new codechicken.lib.vec.Rotation(-Math.PI / 2, 0, 1, 0); + } else if (this.spin == EnumFacing.SOUTH) { + translation.translate(1, 0, 1); + rotation = new Rotation(Math.PI, 0, 1, 0); + } + translation.apply(rotation); + } + if (mode == MODE.PROXY) { + Textures.COVER_INTERFACE_PROXY.renderSided(this.attachedSide, cuboid6, ccRenderState, ops, RenderUtil.adjustTrans(translation, this.attachedSide, 1)); + } else if (mode == MODE.FLUID) { + Textures.COVER_INTERFACE_FLUID.renderSided(this.attachedSide, cuboid6, ccRenderState, ArrayUtils.addAll(ops, rotation), RenderUtil.adjustTrans(translation, this.attachedSide, 1)); + Textures.COVER_INTERFACE_FLUID_GLASS.renderSided(this.attachedSide, cuboid6, ccRenderState, ArrayUtils.addAll(ops, rotation), RenderUtil.adjustTrans(translation, this.attachedSide, 3)); + } else if (mode == MODE.ITEM) { + Textures.COVER_INTERFACE_ITEM.renderSided(this.attachedSide, cuboid6, ccRenderState, ArrayUtils.addAll(ops, rotation), RenderUtil.adjustTrans(translation, this.attachedSide, 1)); + } else if (mode == MODE.ENERGY) { + Textures.COVER_INTERFACE_ENERGY.renderSided(this.attachedSide, cuboid6, ccRenderState, ArrayUtils.addAll(ops, rotation), RenderUtil.adjustTrans(translation, this.attachedSide, 1)); + } else if (mode == MODE.MACHINE) { + if (isWorkingEnabled) { + Textures.COVER_INTERFACE_MACHINE_ON.renderSided(this.attachedSide, cuboid6, ccRenderState, ArrayUtils.addAll(ops, rotation), RenderUtil.adjustTrans(translation, this.attachedSide, 1)); + } else { + Textures.COVER_INTERFACE_MACHINE_OFF.renderSided(this.attachedSide, cuboid6, ccRenderState, ArrayUtils.addAll(ops, rotation), RenderUtil.adjustTrans(translation, this.attachedSide, 1)); + } + } + } + + @SideOnly(Side.CLIENT) + @Override + public void renderMetaTileEntityFast(CCRenderState renderState, Matrix4 translation, float partialTicks) { + + } + + @SideOnly(Side.CLIENT) + @Override + public void renderMetaTileEntity(double x, double y, double z, float partialTicks) { + GlStateManager.pushMatrix(); + /* hack the lightmap */ + net.minecraft.client.renderer.RenderHelper.disableStandardItemLighting(); + float lastBrightnessX = OpenGlHelper.lastBrightnessX; + float lastBrightnessY = OpenGlHelper.lastBrightnessY; + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240.0F, 240.0F); + + RenderUtil.moveToFace(x, y, z, this.attachedSide); + RenderUtil.rotateToFace(this.attachedSide, this.attachedSide.getAxis() == EnumFacing.Axis.Y ? this.spin : EnumFacing.NORTH); + + if (!renderSneakingLookAt(this.coverHolder.getPos(), this.attachedSide, this.slot, partialTicks)) { + renderMode(this.mode, this.slot, partialTicks); + } + + /* restore the lightmap */ + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, lastBrightnessX, lastBrightnessY); + net.minecraft.client.renderer.RenderHelper.enableStandardItemLighting(); + GlStateManager.popMatrix(); + } + + @Override + public boolean shouldRenderInPass(int pass) { + return pass == 0 && this.mode != MODE.PROXY; + } + + @Override + public AxisAlignedBB getRenderBoundingBox() { + return null; + } + + @SideOnly(Side.CLIENT) + public boolean renderSneakingLookAt(BlockPos blockPos, EnumFacing side, int slot, float partialTicks) { + EntityPlayer player = Minecraft.getMinecraft().player; + if (player != null && player.isSneaking() && player.getHeldItemMainhand().isEmpty()) { + RayTraceResult rayTraceResult = player.rayTrace(Minecraft.getMinecraft().playerController.getBlockReachDistance(), partialTicks); + if (rayTraceResult != null && rayTraceResult.typeOfHit == RayTraceResult.Type.BLOCK && rayTraceResult.sideHit == side && rayTraceResult.getBlockPos().equals(blockPos)) { + RenderUtil.renderRect(-7f / 16, -7f / 16, 3f / 16, 3f / 16, 0.002f, 0XFF838583); + RenderUtil.renderRect(4f / 16, -7f / 16, 3f / 16, 3f / 16, 0.002f, 0XFF838583); + RenderUtil.renderText(-5.5f / 16, -5.5F / 16, 0, 1.0f / 70, 0XFFFFFFFF, "<", true); + RenderUtil.renderText(5.7f / 16, -5.5F / 16, 0, 1.0f / 70, 0XFFFFFFFF, ">", true); + RenderUtil.renderText(0, -5.5F / 16, 0, 1.0f / 120, 0XFFFFFFFF, "Slot: " + slot, true); + TileEntity te = getCoveredTE(); + if (te != null) { + ItemStack itemStack; + if (te instanceof MetaTileEntityHolder) { + itemStack = ((MetaTileEntityHolder) te).getMetaTileEntity().getStackForm(); + } else { + BlockPos pos = te.getPos(); + itemStack = te.getBlockType().getPickBlock(te.getWorld().getBlockState(pos), new RayTraceResult(new Vec3d(0.5, 0.5, 0.5), getCoveredFacing(), pos), te.getWorld(), pos, Minecraft.getMinecraft().player); + } + String name = itemStack.getDisplayName(); + RenderUtil.renderRect(-7f / 16, -4f / 16, 14f / 16, 1f / 16, 0.002f, 0XFF000000); + RenderUtil.renderText(0, -3.5F / 16, 0, 1.0f / 200, 0XFFFFFFFF, name, true); + RenderUtil.renderItemOverLay(-8f / 16, -5f / 16, 0.002f, 1f / 32, itemStack); + } + return true; + } + } + return false; + } + + @SideOnly(Side.CLIENT) + public void renderMode(MODE mode, int slot, float partialTicks) { + if (mode == MODE.FLUID && fluids.length > slot && slot >= 0 && fluids[slot] != null && fluids[slot].getContents() != null) { + renderFluidMode(slot); + } else if (mode == MODE.ITEM && items.length > slot && slot >= 0 && items[slot] != null) { + renderItemMode(slot); + } else if (mode == MODE.ENERGY) { + renderEnergyMode(); + } else if (mode == MODE.MACHINE) { + renderMachineMode(partialTicks); + } + } + + @SideOnly(Side.CLIENT) + private void renderMachineMode(float partialTicks) { + int color = energyCapability > 10 * energyStored ? 0XFFFF2F39 : isWorkingEnabled ? 0XFF00FF00 : 0XFFFF662E; + if (isActive && maxProgress != 0) { + float offset = ((this.coverHolder.getOffsetTimer() % 20 + partialTicks) * 0.875f / 20); + float start = Math.max(-0.4375f, -0.875f + 2 * offset); + float width = Math.min(0.4375f, -0.4375f + 2 * offset) - start; + int startAlpha = 0X00; + int endAlpha = 0XFF; + if (offset < 0.4375f) { + startAlpha = (int) (255 - 255 / 0.4375 * offset); + } else if (start > 0.4375) { + endAlpha = (int) (510 - 255 / 0.4375 * offset); + } + RenderUtil.renderRect(-7f / 16, -7f / 16, progress * 14f / (maxProgress * 16), 3f / 16, 0.002f, 0XFFFF5F44); + RenderUtil.renderText(0, -5.5F / 16, 0, 1.0f / (isProxy() ? 110 : 70), 0XFFFFFFFF, readAmountOrCountOrEnergy(progress * 100 / maxProgress, MODE.MACHINE), true); + RenderUtil.renderGradientRect(start, -4f / 16, width, 1f / 16, 0.002f, (color & 0X00FFFFFF) | (startAlpha << 24), (color & 0X00FFFFFF) | (endAlpha << 24), true); + } else { + RenderUtil.renderRect(-7f / 16, -4f / 16, 14f / 16, 1f / 16, 0.002f, color); + } + if (this.isProxy()) { + if (isWorkingEnabled) { + RenderUtil.renderTextureArea(Textures.COVER_INTERFACE_MACHINE_ON_PROXY, -7f / 16, 1f / 16, 14f / 16, 3f / 16, 0.002f); + } else { + RenderUtil.renderTextureArea(Textures.COVER_INTERFACE_MACHINE_OFF_PROXY, -7f / 16, -1f / 16, 14f / 16, 5f / 16, 0.002f); + } + } + } + + @SideOnly(Side.CLIENT) + private void renderEnergyMode() { + if (inputEnergyList.isEmpty()) return; + long max = Long.MIN_VALUE; + for (long d : inputEnergyList) { + max = Math.max(max, d); + } + for (long d : outputEnergyList) { + max = Math.max(max, d); + } + RenderUtil.renderLineChart(inputEnergyList, max, -5.5f / 16, 5.5f / 16, 12f / 16, 6f / 16, 0.005f, 0XFF03FF00); + RenderUtil.renderLineChart(outputEnergyList, max, -5.5f / 16, 5.5f / 16, 12f / 16, 6f / 16, 0.005f, 0XFFFF2F39); + RenderUtil.renderText(-5.7f / 16, -2.3f / 16, 0, 1.0f / 270, 0XFF03FF00, "EU I: " + energyInputPerDur + "EU/s", false); + RenderUtil.renderText(-5.7f / 16, -1.6f / 16, 0, 1.0f / 270, 0XFFFF0000, "EU O: " + energyOutputPerDur + "EU/s", false); + RenderUtil.renderRect(-7f / 16, -7f / 16, energyStored * 14f / (energyCapability * 16), 3f / 16, 0.002f, 0XFFFFD817); + RenderUtil.renderText(0, -5.5F / 16, 0, 1.0f / (isProxy() ? 110 : 70), 0XFFFFFFFF, readAmountOrCountOrEnergy(energyStored, MODE.ENERGY), true); + } + + @SideOnly(Side.CLIENT) + private void renderItemMode(int slot) { + ItemStack itemStack = items[slot]; + if (!itemStack.isEmpty()) { + RenderUtil.renderItemOverLay(-8f / 16, -5f / 16, 0, 1f / 32, itemStack); + if (maxItemCapability != 0) { + RenderUtil.renderRect(-7f / 16, -7f / 16, Math.max(itemStack.getCount() * 14f / (maxItemCapability * 16), 0.001f), 3f / 16, 0.002f, 0XFF25B9FF); + } else { + RenderUtil.renderRect(-7f / 16, -7f / 16, Math.max(itemStack.getCount() * 14f / (itemStack.getMaxStackSize() * 16), 0.001f), 3f / 16, 0.002f, 0XFF25B9FF); + } + RenderUtil.renderText(0, -5.5F / 16, 0, 1.0f / (isProxy() ? 110 : 70), 0XFFFFFFFF, readAmountOrCountOrEnergy(itemStack.getCount(), MODE.ITEM), true); + + } + } + + @SideOnly(Side.CLIENT) + private void renderFluidMode(int slot) { + FluidStack fluidStack = fluids[slot].getContents(); + assert fluidStack != null; + float height = 10f / 16 * Math.max(fluidStack.amount * 1.0f / fluids[slot].getCapacity(), 0.001f); + RenderUtil.renderFluidOverLay(-7f / 16, 0.4375f - height, 14f / 16, height, 0.002f, fluidStack, 0.8f); + int fluidColor = WidgetOreList.getFluidColor(fluidStack.getFluid()); + int textColor = ((fluidColor & 0xff) + ((fluidColor >> 8) & 0xff) + ((fluidColor >> 16) & 0xff)) / 3 > (255 / 2) ? 0X0 : 0XFFFFFFFF; + RenderUtil.renderRect(-7f / 16, -7f / 16, 14f / 16, 3f / 16, 0.002f, fluidColor | (255 << 24)); + RenderUtil.renderText(0, -5.5F / 16, 0, 1.0f / (isProxy() ? 110 : 70), textColor, readAmountOrCountOrEnergy(fluidStack.amount, MODE.FLUID), true); + } + + static String[][] units = { + {"", "mB", "", "EU"}, + {"", "B", "K", "KEU"}, + {"", "KB", "M", "MEU"}, + {"", "MB", "G", "GEU"}, + {"", "GB", "T", "TEU"}, + {"", "TB", "P", "PEU"}, + }; + + @SideOnly(Side.CLIENT) + private String readAmountOrCountOrEnergy(long number, MODE mode) { + int unit = mode == MODE.FLUID ? 1 : mode == MODE.ITEM ? 2 : mode == MODE.ENERGY ? 3 : 0; + if (mode == MODE.MACHINE) { + return number + "%"; + } + + if (number / 1000 == 0) { + return number + units[0][unit]; + } + int i = 1; + + while (number / 10000000 != 0 && i < units.length) { + number = number / 1000; + ++i; + } + + return new DecimalFormat("#.#").format(number * 1.0f / 1000) + units[i][unit]; + } +} diff --git a/src/main/java/gregtech/common/covers/CoverDigitalInterfaceWireless.java b/src/main/java/gregtech/common/covers/CoverDigitalInterfaceWireless.java new file mode 100644 index 00000000000..8906c46280c --- /dev/null +++ b/src/main/java/gregtech/common/covers/CoverDigitalInterfaceWireless.java @@ -0,0 +1,103 @@ +package gregtech.common.covers; + +import codechicken.lib.raytracer.CuboidRayTraceResult; +import codechicken.lib.render.CCRenderState; +import codechicken.lib.render.pipeline.IVertexOperation; +import codechicken.lib.vec.Cuboid6; +import codechicken.lib.vec.Matrix4; +import gregtech.api.cover.ICoverable; +import gregtech.api.metatileentity.MetaTileEntityHolder; +import gregtech.api.render.Textures; +import gregtech.api.util.BlockPosFace; +import gregtech.api.util.RenderUtil; +import gregtech.common.items.behaviors.CoverDigitalInterfaceWirelessPlaceBehaviour; +import gregtech.common.metatileentities.multi.electric.centralmonitor.MetaTileEntityCentralMonitor; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTUtil; +import net.minecraft.network.PacketBuffer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.math.BlockPos; + +public class CoverDigitalInterfaceWireless extends CoverDigitalInterface{ + private BlockPos remote; + + public CoverDigitalInterfaceWireless(ICoverable coverHolder, EnumFacing attachedSide) { + super(coverHolder, attachedSide); + } + + @Override + public void setMode(MODE mode, int slot, EnumFacing spin) { + } + + @Override + public void writeToNBT(NBTTagCompound tagCompound) { + super.writeToNBT(tagCompound); + if (this.remote != null) { + tagCompound.setTag("cdiRemote", NBTUtil.createPosTag(this.remote)); + } + } + + @Override + public void readFromNBT(NBTTagCompound tagCompound) { + super.readFromNBT(tagCompound); + this.remote = tagCompound.hasKey("cdiRemote") ? NBTUtil.getPosFromTag(tagCompound.getCompoundTag("cdiRemote")) : null; + } + + @Override + public void writeInitialSyncData(PacketBuffer packetBuffer) { + packetBuffer.writeBoolean(remote != null); + if (remote != null) { + packetBuffer.writeBlockPos(remote); + } + super.writeInitialSyncData(packetBuffer); + } + + @Override + public void readInitialSyncData(PacketBuffer packetBuffer) { + if (packetBuffer.readBoolean()) { + this.remote = packetBuffer.readBlockPos(); + } + super.readInitialSyncData(packetBuffer); + } + + @Override + public void onAttached(ItemStack itemStack) { + remote = CoverDigitalInterfaceWirelessPlaceBehaviour.getRemotePos(itemStack); + } + + @Override + public void update() { + super.update(); + if (remote != null && !isRemote() && coverHolder.getOffsetTimer() % 20 == 0) { + TileEntity te = coverHolder.getWorld().getTileEntity(remote); + if (te instanceof MetaTileEntityHolder && ((MetaTileEntityHolder) te).getMetaTileEntity() instanceof MetaTileEntityCentralMonitor) { + ((MetaTileEntityCentralMonitor) ((MetaTileEntityHolder) te).getMetaTileEntity()).addRemoteCover(new BlockPosFace(coverHolder.getPos(), attachedSide)); + } + } + } + + @Override + public EnumActionResult onScrewdriverClick(EntityPlayer playerIn, EnumHand hand, CuboidRayTraceResult hitResult) { + return EnumActionResult.SUCCESS; + } + + @Override + public ItemStack getPickItem() { + ItemStack drop = super.getPickItem(); + if (remote != null) { + drop.setTagCompound(NBTUtil.createPosTag(remote)); + } + return drop; + } + + @Override + public void renderCover(CCRenderState ccRenderState, Matrix4 translation, IVertexOperation[] ops, Cuboid6 cuboid6, BlockRenderLayer blockRenderLayer) { + Textures.COVER_INTERFACE_WIRELESS.renderSided(this.attachedSide, cuboid6, ccRenderState, ops, RenderUtil.adjustTrans(translation, this.attachedSide, 1)); + } +} diff --git a/src/main/java/gregtech/common/events/PlayerEventHandler.java b/src/main/java/gregtech/common/events/PlayerEventHandler.java index 7803c1cc9fa..41ddec060fa 100644 --- a/src/main/java/gregtech/common/events/PlayerEventHandler.java +++ b/src/main/java/gregtech/common/events/PlayerEventHandler.java @@ -4,6 +4,7 @@ import gregtech.common.ConfigHolder; import gregtech.common.items.MetaItems; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; @@ -21,7 +22,11 @@ public static void onPlayerLoggedIn(PlayerEvent.PlayerLoggedInEvent event) { NBTTagCompound data = playerData.hasKey(EntityPlayer.PERSISTED_NBT_TAG) ? playerData.getCompoundTag(EntityPlayer.PERSISTED_NBT_TAG) : new NBTTagCompound(); if (!data.getBoolean(HAS_TERMINAL)) { - ItemHandlerHelper.giveItemToPlayer(event.player, MetaItems.TERMINAL.getStackForm()); + ItemStack terminal = MetaItems.TERMINAL.getStackForm(); + if (event.player.isCreative()) { + terminal.getOrCreateSubCompound("terminal").setBoolean("_creative", true); + } + ItemHandlerHelper.giveItemToPlayer(event.player, terminal); data.setBoolean(HAS_TERMINAL, true); playerData.setTag(EntityPlayer.PERSISTED_NBT_TAG, data); } diff --git a/src/main/java/gregtech/common/events/client/ClientEventHandler.java b/src/main/java/gregtech/common/events/client/ClientEventHandler.java index 3d41044c51b..2f0c338c9e1 100644 --- a/src/main/java/gregtech/common/events/client/ClientEventHandler.java +++ b/src/main/java/gregtech/common/events/client/ClientEventHandler.java @@ -2,6 +2,7 @@ import gregtech.api.render.DepthTextureHook; import gregtech.api.render.TerminalARRenderer; +import gregtech.common.render.WorldRenderEventRenderer; import gregtech.common.render.WrenchOverlayRenderer; import net.minecraftforge.client.event.DrawBlockHighlightEvent; import net.minecraftforge.client.event.RenderGameOverlayEvent; @@ -42,6 +43,7 @@ public static void onPlayerTick(TickEvent.PlayerTickEvent event) { public static void onRenderWorldLast(RenderWorldLastEvent event) { DepthTextureHook.renderWorld(event); // GTParticleManager.renderWorld(event); + WorldRenderEventRenderer.renderWorldLastEvent(event); TerminalARRenderer.renderWorldLastEvent(event); } diff --git a/src/main/java/gregtech/common/gui/impl/FakeModularUIContainerClipboard.java b/src/main/java/gregtech/common/gui/impl/FakeModularUIContainerClipboard.java index a7943fd2169..1be6fdfd499 100644 --- a/src/main/java/gregtech/common/gui/impl/FakeModularUIContainerClipboard.java +++ b/src/main/java/gregtech/common/gui/impl/FakeModularUIContainerClipboard.java @@ -1,10 +1,9 @@ package gregtech.common.gui.impl; import com.google.common.collect.Lists; -import gregtech.api.gui.INativeWidget; import gregtech.api.gui.ModularUI; import gregtech.api.gui.Widget; -import gregtech.api.gui.widgets.WidgetUIAccess; +import gregtech.api.gui.impl.FakeModularGuiContainer; import gregtech.api.net.NetworkHandler; import gregtech.api.net.PacketClipboardUIWidgetUpdate; import gregtech.common.metatileentities.MetaTileEntityClipboard; @@ -22,20 +21,15 @@ // Note: when porting the central monitor, please make this more generic. -public class FakeModularUIContainerClipboard implements WidgetUIAccess { +public class FakeModularUIContainerClipboard extends FakeModularGuiContainer { private final NonNullList inventoryItemStacks = NonNullList.create(); public final List inventorySlots = Lists.newArrayList(); - public final ModularUI modularUI; public int windowId; public MetaTileEntityClipboard clipboard; public FakeModularUIContainerClipboard(ModularUI modularUI, MetaTileEntityClipboard clipboard) { - this.modularUI = modularUI; + super(modularUI); this.clipboard = clipboard; - modularUI.initWidgets(); - modularUI.guiWidgets.values().forEach(widget -> widget.setUiAccess(this)); - modularUI.guiWidgets.values().stream().flatMap(widget -> widget.getNativeWidgets().stream()).forEach(nativeWidget -> addSlotToContainer(nativeWidget.getHandle())); - modularUI.triggerOpenListeners(); } protected void addSlotToContainer(Slot slotIn) { @@ -65,6 +59,11 @@ public void handleClientAction(PacketBuffer buffer) { } } + @Override + public boolean detectSyncedPacket(PacketBuffer buffer) { + return this.windowId == buffer.readVarInt(); + } + public void detectAndSendChanges() { List> toUpdate = new ArrayList<>(); for (int i = 0; i < this.inventorySlots.size(); ++i) { @@ -84,29 +83,6 @@ public void detectAndSendChanges() { modularUI.guiWidgets.values().forEach(Widget::detectAndSendChanges); } - @Override - public void notifySizeChange() { - - } - - @Override - public void notifyWidgetChange() { - - } - - @Override - public boolean attemptMergeStack(ItemStack itemStack, boolean b, boolean b1) { - return false; - } - - @Override - public void sendSlotUpdate(INativeWidget iNativeWidget) { - } - - @Override - public void sendHeldItemUpdate() { - } - @Override public void writeClientAction(Widget widget, int updateId, Consumer payloadWriter) { NetworkHandler.channel.sendToServer(new PacketClipboardUIWidgetUpdate(this.clipboard, updateId, buffer -> { diff --git a/src/main/java/gregtech/common/gui/impl/FakeModularUIPluginContainer.java b/src/main/java/gregtech/common/gui/impl/FakeModularUIPluginContainer.java new file mode 100644 index 00000000000..8e57edfd8b7 --- /dev/null +++ b/src/main/java/gregtech/common/gui/impl/FakeModularUIPluginContainer.java @@ -0,0 +1,85 @@ +package gregtech.common.gui.impl; + +import gregtech.api.capability.GregtechDataCodes; +import gregtech.api.gui.ModularUI; +import gregtech.api.gui.Widget; +import gregtech.api.gui.impl.FakeModularGuiContainer; +import gregtech.common.items.behaviors.monitorplugin.FakeGuiPluginBehavior; +import net.minecraft.item.ItemStack; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.Tuple; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + +public class FakeModularUIPluginContainer extends FakeModularGuiContainer { + protected int windowId; + private final FakeGuiPluginBehavior behavior; + public int syncId; + + public FakeModularUIPluginContainer(ModularUI modularUI, FakeGuiPluginBehavior pluginBehavior) { + super(modularUI); + this.behavior = pluginBehavior; + } + + @Override + public boolean detectSyncedPacket(PacketBuffer buffer) { + int syncId = buffer.readVarInt(); + int windowId = buffer.readVarInt(); + return (syncId == this.syncId && windowId == this.windowId); + } + + public void detectAndSendChanges() { + List> toUpdate = new ArrayList<>(); + for (int i = 0; i < this.inventorySlots.size(); ++i) { + ItemStack real = this.inventorySlots.get(i).getStack(); + ItemStack fake = this.inventoryItemStacks.get(i); + + if (!ItemStack.areItemStacksEqual(fake, real)) { + boolean clientStackChanged = !ItemStack.areItemStacksEqualUsingNBTShareTag(fake, real); + fake = real.isEmpty() ? ItemStack.EMPTY : real.copy(); + this.inventoryItemStacks.set(i, fake); + + if (clientStackChanged) { + toUpdate.add(new Tuple<>(i, fake)); + } + } + } + if (toUpdate.size() > 0 && this.behavior != null) { + behavior.writePluginData(GregtechDataCodes.UPDATE_FAKE_GUI_DETECT, packetBuffer -> { + packetBuffer.writeVarInt(toUpdate.size()); + for (Tuple tuple : toUpdate) { + packetBuffer.writeVarInt(tuple.getFirst()); + packetBuffer.writeItemStack(tuple.getSecond()); + } + }); + } + modularUI.guiWidgets.values().forEach(Widget::detectAndSendChanges); + } + + @Override + public void writeClientAction(Widget widget, int updateId, Consumer payloadWriter) { + if (behavior != null) { + behavior.writePluginAction(GregtechDataCodes.ACTION_FAKE_GUI, buffer -> { + buffer.writeVarInt(syncId); + buffer.writeVarInt(windowId); + buffer.writeVarInt(modularUI.guiWidgets.inverse().get(widget)); + buffer.writeVarInt(updateId); + payloadWriter.accept(buffer); + }); + } + } + + @Override + public void writeUpdateInfo(Widget widget, int updateId, Consumer payloadWriter) { + if(behavior != null) { + behavior.writePluginData(GregtechDataCodes.UPDATE_FAKE_GUI, buf -> { + buf.writeVarInt(windowId); + buf.writeVarInt(modularUI.guiWidgets.inverse().get(widget)); + buf.writeVarInt(updateId); + payloadWriter.accept(buf); + }); + } + } +} diff --git a/src/main/java/gregtech/common/gui/widget/WidgetARGB.java b/src/main/java/gregtech/common/gui/widget/WidgetARGB.java new file mode 100644 index 00000000000..936954daf6d --- /dev/null +++ b/src/main/java/gregtech/common/gui/widget/WidgetARGB.java @@ -0,0 +1,72 @@ +package gregtech.common.gui.widget; + +import gregtech.api.gui.IRenderContext; +import gregtech.api.gui.widgets.TextFieldWidget; +import gregtech.api.gui.widgets.WidgetGroup; +import gregtech.api.util.Position; +import net.minecraft.client.gui.Gui; +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import java.util.function.Consumer; +import java.util.function.Predicate; + +public class WidgetARGB extends WidgetGroup { + public int color; + private final int height; + + public WidgetARGB(int x, int y, int height, int initColor, Consumer onColorChanged) { + super(new Position(x, y)); + this.color = initColor; + this.height = height; + Predicate validator = (data)->{ + if (data.equals("")) return true; + try { int num = Integer.parseInt(data, 16); if (num > 255 || num < 0) return false; } catch (Exception e) { return false; } return true; + }; + Consumer update = (buf)->{ + buf.writeInt(color); + }; + TextFieldWidget[] ARGB = new TextFieldWidget[4]; + ARGB[0] = new TextFieldWidget(0, 0, 20, height, true, ()->Integer.toHexString(color >> 24 & 0XFF).toUpperCase(), (data)->{ + this.color = (data.equals("")? 0 : Integer.parseInt(data, 16)) << 24 | (color & 0X00FFFFFF); + onColorChanged.accept(color); + writeUpdateInfo(2, update); + }).setValidator(validator); + ARGB[1] = new TextFieldWidget(22, 0, 20, height, true, ()->Integer.toHexString(color >> 16 & 0XFF).toUpperCase(), (data)->{ + this.color = (data.equals("")? 0 : Integer.parseInt(data, 16)) << 16 | (color & 0XFF00FFFF); + onColorChanged.accept(color); + writeUpdateInfo(2, update); + }).setValidator(validator); + ARGB[2] = new TextFieldWidget(44, 0, 20, height, true, ()->Integer.toHexString(color >> 8 & 0XFF).toUpperCase(), (data)->{ + this.color = (data.equals("")? 0 : Integer.parseInt(data, 16)) << 8 | (color & 0X00FF00FF); + onColorChanged.accept(color); + writeUpdateInfo(2, update); + }).setValidator(validator); + ARGB[3] = new TextFieldWidget(66, 0, 20, height, true, ()->Integer.toHexString(color & 0XFF).toUpperCase(), (data)->{ + this.color = (data.equals("")? 0 : Integer.parseInt(data, 16)) | (color & 0XFFFFFF00); + onColorChanged.accept(color); + writeUpdateInfo(2, update); + }).setValidator(validator); + this.addWidget(ARGB[0]); + this.addWidget(ARGB[1]); + this.addWidget(ARGB[2]); + this.addWidget(ARGB[3]); + } + + @SideOnly(Side.CLIENT) + @Override + public void readUpdateInfo(int id, PacketBuffer buffer) { + super.readUpdateInfo(id, buffer); + if (id == 2) { + this.color = buffer.readInt(); + } + } + + @SideOnly(Side.CLIENT) + @Override + public void drawInBackground(int mouseX, int mouseY, IRenderContext context) { + super.drawInBackground(mouseX, mouseY, context); + Gui.drawRect(this.getPosition().x + 88, this.getPosition().y, this.getPosition().x + 100, this.getPosition().y + height, color); + } +} diff --git a/src/main/java/gregtech/common/gui/widget/WidgetScrollBar.java b/src/main/java/gregtech/common/gui/widget/WidgetScrollBar.java new file mode 100644 index 00000000000..b5bcce2e8fe --- /dev/null +++ b/src/main/java/gregtech/common/gui/widget/WidgetScrollBar.java @@ -0,0 +1,152 @@ +package gregtech.common.gui.widget; + +import gregtech.api.gui.GuiTextures; +import gregtech.api.gui.IRenderContext; +import gregtech.api.gui.Widget; +import gregtech.api.gui.resources.SizedTextureArea; +import gregtech.api.gui.resources.TextureArea; +import gregtech.api.util.Position; +import gregtech.api.util.RenderUtil; +import gregtech.api.util.Size; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.resources.I18n; +import net.minecraft.network.PacketBuffer; + +import java.text.DecimalFormat; +import java.util.function.Consumer; + +public class WidgetScrollBar extends Widget { + protected final float min; + protected final float max; + protected final float dur; + protected int xOffset; + protected boolean draggedOnScrollBar; + protected TextureArea buttonTexture; + protected int buttonWidth; + protected int buttonHeight; + protected int lineColor; + protected String title; + protected int titleColor; + protected Consumer onChanged; + + + public WidgetScrollBar(int x, int y, int width, float min, float max, float dur, Consumer onChanged) { + super(new Position(x, y), new Size(width, 20)); + this.max = max; + this.min = min; + this.dur = dur; + this.xOffset = width / 2; + this.buttonTexture = GuiTextures.VANILLA_BUTTON.getSubArea(0.0D, 0.0D, 1.0D, 0.5D); + this.buttonWidth = 6; + this.buttonHeight = 8; + this.lineColor = 0XFF000000; + this.title = ""; + this.titleColor = 0XFFFFFFFF; + this.onChanged = onChanged; + } + + public WidgetScrollBar setInitValue(float value) { + if (value >= min && value <= max) { + this.xOffset = (int) ((value - min) / (max - min) * this.getSize().width); + } + return this; + } + + public WidgetScrollBar setButtonTexture(TextureArea buttonTexture, int buttonWidth, int buttonHeight) { + this.buttonTexture = buttonTexture; + this.buttonWidth = buttonWidth; + this.buttonHeight = buttonHeight; + return this; + } + + public WidgetScrollBar setLineColor(int lineColor) { + this.lineColor = lineColor; + return this; + } + + public WidgetScrollBar setTitle(String title, int titleColor) { + this.title = title; + this.titleColor = titleColor; + return this; + } + + @Override + public void drawInBackground(int mouseX, int mouseY, IRenderContext context) { + super.drawInBackground(mouseX, mouseY, context); + Position position = this.getPosition(); + Size size = this.getSize(); + RenderUtil.renderRect(position.x, position.y + 15 - 0.5f, size.width, 1, 0, lineColor); + if (this.buttonTexture instanceof SizedTextureArea) { + ((SizedTextureArea)this.buttonTexture).drawHorizontalCutSubArea(position.x + xOffset - buttonWidth / 2, position.y + 15 - buttonHeight / 2, buttonWidth, buttonHeight, 0.0D, 1.0D); + } else { + this.buttonTexture.drawSubArea(position.x + xOffset - buttonWidth * 0.5f, position.y + 15 - buttonHeight * 0.5f, buttonWidth, buttonHeight, 0.0D, 0.0D, 1.0D, 1.0D); + } + + FontRenderer fontRenderer = Minecraft.getMinecraft().fontRenderer; + String text = I18n.format(this.title); + text += ": " + new DecimalFormat("#.00").format(getValue()); + fontRenderer.drawString(text, position.x + size.width / 2 - fontRenderer.getStringWidth(text) / 2, position.y - 3 + size.height / 2 - fontRenderer.FONT_HEIGHT / 2, this.titleColor); + GlStateManager.color(1.0F, 1.0F, 1.0F); + } + + private boolean isOnScrollPane(int mouseX, int mouseY) { + Position position = this.getPosition(); + Size size = this.getSize(); + return isMouseOver(position.x - buttonWidth / 2, position.y + 15 - buttonHeight / 2, size.width + buttonWidth / 2, buttonHeight, mouseX, mouseY); + } + + private float getValue() { + return (float) (min + Math.floor((max - min) * xOffset * 1.0f / this.getSize().width / dur) * dur) ; + } + + @Override + public boolean mouseClicked(int mouseX, int mouseY, int button) { + if (this.isOnScrollPane(mouseX, mouseY)) { + this.xOffset = mouseX - this.getPosition().x; + this.draggedOnScrollBar = true; + } + return this.isMouseOverElement(mouseX, mouseY); + } + + @Override + public boolean mouseDragged(int mouseX, int mouseY, int button, long timeDragged) { + if (draggedOnScrollBar) { + Position position = this.getPosition(); + Size size = this.getSize(); + if (mouseX > position.x + size.width) { + this.xOffset = size.width; + } else if(mouseX < position.x) { + this.xOffset = 0; + } else { + this.xOffset = mouseX - this.getPosition().x; + } + if (this.onChanged != null) { + onChanged.accept(getValue()); + } + return true; + } + return false; + } + + @Override + public boolean mouseReleased(int mouseX, int mouseY, int button) { + if(this.draggedOnScrollBar) { + this.writeClientAction(2, packetBuffer -> packetBuffer.writeFloat(getValue())); + } + this.draggedOnScrollBar = false; + return this.isMouseOverElement(mouseX, mouseY); + } + + @Override + public void handleClientAction(int id, PacketBuffer buffer) { + super.handleClientAction(id, buffer); + if (id == 2) { + float value = buffer.readFloat(); + if(this.onChanged != null) { + onChanged.accept(value); + } + } + } +} diff --git a/src/main/java/gregtech/common/gui/widget/CraftingSlotWidget.java b/src/main/java/gregtech/common/gui/widget/craftingstation/CraftingSlotWidget.java similarity index 98% rename from src/main/java/gregtech/common/gui/widget/CraftingSlotWidget.java rename to src/main/java/gregtech/common/gui/widget/craftingstation/CraftingSlotWidget.java index a17fb11d866..0e162522af5 100644 --- a/src/main/java/gregtech/common/gui/widget/CraftingSlotWidget.java +++ b/src/main/java/gregtech/common/gui/widget/craftingstation/CraftingSlotWidget.java @@ -1,4 +1,4 @@ -package gregtech.common.gui.widget; +package gregtech.common.gui.widget.craftingstation; import com.google.common.base.Preconditions; import gregtech.api.gui.impl.ModularUIContainer; diff --git a/src/main/java/gregtech/common/gui/widget/ItemListGridWidget.java b/src/main/java/gregtech/common/gui/widget/craftingstation/ItemListGridWidget.java similarity index 99% rename from src/main/java/gregtech/common/gui/widget/ItemListGridWidget.java rename to src/main/java/gregtech/common/gui/widget/craftingstation/ItemListGridWidget.java index c475b40a27b..dd96bda4c92 100644 --- a/src/main/java/gregtech/common/gui/widget/ItemListGridWidget.java +++ b/src/main/java/gregtech/common/gui/widget/craftingstation/ItemListGridWidget.java @@ -1,4 +1,4 @@ -package gregtech.common.gui.widget; +package gregtech.common.gui.widget.craftingstation; import gregtech.api.gui.INativeWidget; import gregtech.api.gui.Widget; diff --git a/src/main/java/gregtech/common/gui/widget/ItemListSlotWidget.java b/src/main/java/gregtech/common/gui/widget/craftingstation/ItemListSlotWidget.java similarity index 99% rename from src/main/java/gregtech/common/gui/widget/ItemListSlotWidget.java rename to src/main/java/gregtech/common/gui/widget/craftingstation/ItemListSlotWidget.java index 7e0c6ecfa2b..087b4ee6c98 100644 --- a/src/main/java/gregtech/common/gui/widget/ItemListSlotWidget.java +++ b/src/main/java/gregtech/common/gui/widget/craftingstation/ItemListSlotWidget.java @@ -1,4 +1,4 @@ -package gregtech.common.gui.widget; +package gregtech.common.gui.widget.craftingstation; import gregtech.api.gui.GuiTextures; import gregtech.api.gui.IRenderContext; diff --git a/src/main/java/gregtech/common/gui/widget/MemorizedRecipeWidget.java b/src/main/java/gregtech/common/gui/widget/craftingstation/MemorizedRecipeWidget.java similarity index 98% rename from src/main/java/gregtech/common/gui/widget/MemorizedRecipeWidget.java rename to src/main/java/gregtech/common/gui/widget/craftingstation/MemorizedRecipeWidget.java index 18b9e78ae7a..70830ef4a5c 100644 --- a/src/main/java/gregtech/common/gui/widget/MemorizedRecipeWidget.java +++ b/src/main/java/gregtech/common/gui/widget/craftingstation/MemorizedRecipeWidget.java @@ -1,4 +1,4 @@ -package gregtech.common.gui.widget; +package gregtech.common.gui.widget.craftingstation; import gregtech.api.gui.GuiTextures; import gregtech.api.gui.widgets.SlotWidget; diff --git a/src/main/java/gregtech/common/gui/widget/monitor/WidgetCoverList.java b/src/main/java/gregtech/common/gui/widget/monitor/WidgetCoverList.java new file mode 100644 index 00000000000..b500c430952 --- /dev/null +++ b/src/main/java/gregtech/common/gui/widget/monitor/WidgetCoverList.java @@ -0,0 +1,186 @@ +package gregtech.common.gui.widget.monitor; + +import gregtech.api.gui.IRenderContext; +import gregtech.api.gui.Widget; +import gregtech.api.gui.widgets.LabelWidget; +import gregtech.api.gui.widgets.ScrollableListWidget; +import gregtech.api.gui.widgets.SlotWidget; +import gregtech.api.gui.widgets.WidgetGroup; +import gregtech.api.pipenet.tile.PipeCoverableImplementation; +import gregtech.api.util.Position; +import gregtech.api.util.RenderUtil; +import gregtech.api.util.Size; +import gregtech.common.covers.CoverDigitalInterface; +import gregtech.common.render.WorldRenderEventRenderer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; +import net.minecraft.item.ItemStack; +import net.minecraft.network.PacketBuffer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.text.TextComponentString; +import net.minecraftforge.fml.common.ObfuscationReflectionHelper; +import net.minecraftforge.items.ItemStackHandler; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; + +public class WidgetCoverList extends ScrollableListWidget { + private WidgetGroup selected; + private final Map widgetMap; + public Consumer onSelected; + + public WidgetCoverList(int xPosition, int yPosition, int width, int slotSize, List covers, CoverDigitalInterface bindCover, Consumer onSelected) { + super(xPosition, yPosition, width, slotSize * 18); + widgetMap = new HashMap<>(); + this.onSelected = onSelected; + for (CoverDigitalInterface cover : covers) { + ItemStack itemStack = cover.coverHolder.getStackForm(); + BlockPos pos = cover.coverHolder.getPos(); + if (cover.coverHolder instanceof PipeCoverableImplementation) { + itemStack = null; + pos = pos.offset(cover.attachedSide); + TileEntity tileEntity = cover.coverHolder.getWorld().getTileEntity(pos); + IBlockState state = cover.coverHolder.getWorld().getBlockState(pos); + if (tileEntity != null) { + itemStack = tileEntity.getBlockType().getItem(cover.coverHolder.getWorld(), pos, state); + } + if (itemStack == null) continue; + } + ItemStackHandler itemStackHandler = new ItemStackHandler(1); + itemStackHandler.insertItem(0, itemStack, false); + WidgetGroup widgetGroup = new WidgetGroup(); + widgetGroup.addWidget(new SlotWidget(itemStackHandler, 0, 0, 0, false, false)); + widgetGroup.addWidget(new LabelWidget(20, 5, String.format("(%d, %d, %d)", pos.getX(), pos.getY(), pos.getZ()), 0XFFFFFFFF)); + widgetMap.put(widgetGroup, cover); + if (widgetGroup.getSize().width + this.scrollPaneWidth > this.getSize().width) + this.setSize(new Size(widgetGroup.getSize().width + this.scrollPaneWidth, this.getSize().height)); + this.addWidget(widgetGroup); + if (cover == bindCover) { + selected = widgetGroup; + } + } + } + + @Override + public boolean mouseWheelMove(int mouseX, int mouseY, int wheelDelta) { + if (this.isMouseOverElement(mouseX - this.getPosition().x + this.gui.getGuiLeft(), mouseY, true)) { + int direction = -MathHelper.clamp(wheelDelta, -2, 2); + int moveDelta = direction * (this.slotHeight / 2); + addScrollOffset(moveDelta); + return true; + } else { + return false; + } + } + + @Override + public boolean mouseClicked(int mouseX, int mouseY, int button) { + boolean result = super.mouseClicked(mouseX, mouseY, button); + if (!result && mouseY >= this.getPosition().y && mouseY <= this.getPosition().y + this.getSize().height) { + Widget widget = this.widgets.stream().filter(it -> it.isMouseOverElement(mouseX, mouseY)).findFirst().orElse(null); + if (widget instanceof WidgetGroup) { + List children = ((WidgetGroup) widget).getContainedWidgets(true); + if (children.get(0).isMouseOverElement(mouseX, mouseY)) { + try { + String posString = ObfuscationReflectionHelper.getPrivateValue(LabelWidget.class, (LabelWidget) children.get(1), "text"); + String[] posSplit = posString.split("[,() ]"); + WorldRenderEventRenderer.renderBlockBoxHighLight( + new BlockPos(Integer.parseInt(posSplit[1]), Integer.parseInt(posSplit[3]) + , Integer.parseInt(posSplit[5])), 5000); + Minecraft.getMinecraft().player.closeScreen(); + Minecraft.getMinecraft().player.sendMessage(new TextComponentString( + ((SlotWidget) children.get(0)).getHandle().getStack().getDisplayName() + + ": " + + posString + )); + return false; + } catch (Throwable e) { + e.printStackTrace(); + } + } + if (widget == this.selected) { + this.selected = null; + } else { + this.selected = (WidgetGroup) widget; + } + writeClientAction(2, buf -> { + if (this.selected == null) { + buf.writeInt(-1); + } else { + buf.writeInt(this.getContainedWidgets(true).indexOf(this.selected)); + } + }); + } + } + return result; + } + + @Override + public void handleClientAction(int id, PacketBuffer buffer) { + super.handleClientAction(id, buffer); + if (id == 2) { + int index = buffer.readInt(); + if (index == -1) { + this.selected = null; + } else { + this.selected = (WidgetGroup) this.getContainedWidgets(true).get(index); + } + if (onSelected != null) { + onSelected.accept(widgetMap.getOrDefault(this.selected, null)); + } + } + } + + @Override + public boolean mouseDragged(int mouseX, int mouseY, int button, long timeDragged) { + int mouseDelta = (mouseY - lastMouseY) * 5; + this.lastMouseX = mouseX; + this.lastMouseY = mouseY; + if (draggedOnScrollBar) { + addScrollOffset(mouseDelta); + return true; + } + if (isPositionInsideScissor(mouseX, mouseY)) { + return super.mouseDragged(mouseX, mouseY, button, timeDragged); + } + return false; + } + + private void addScrollOffset(int offset) { + this.scrollOffset = MathHelper.clamp(scrollOffset + offset, 0, totalListHeight - getSize().height); + onPositionUpdate(); + } + + private boolean isPositionInsideScissor(int mouseX, int mouseY) { + return isMouseOverElement(mouseX, mouseY) && !isOnScrollPane(mouseX, mouseY); + } + + private boolean isOnScrollPane(int mouseX, int mouseY) { + Position pos = getPosition(); + Size size = getSize(); + return isMouseOver(pos.x + size.width - scrollPaneWidth, pos.y, scrollPaneWidth, size.height, mouseX, mouseY); + } + + @Override + public void drawInBackground(int mouseX, int mouseY, float partialTicks, IRenderContext context) { + RenderUtil.useScissor(this.getPosition().x, this.getPosition().y, this.getSize().width, this.getSize().height, () -> { + widgets.forEach(widget -> { + if (widget instanceof WidgetGroup) { + Widget widget1 = ((WidgetGroup) widget).getContainedWidgets(true).get(0); + SlotWidget slotWidget = (SlotWidget) widget1; + slotWidget.setActive(widget.getPosition().y >= this.getPosition().y - 9 && widget.getPosition().y <= this.getPosition().y + this.getSize().height - 9); + } + }); + if (selected != null) { + Gui.drawRect(selected.getPosition().x, selected.getPosition().y, selected.getPosition().x + this.getSize().width - this.scrollPaneWidth, selected.getPosition().y + selected.getSize().height, 0x4BFFFFFF); + } + super.drawInBackground(mouseX, mouseY, partialTicks, context); + }); + } + +} diff --git a/src/main/java/gregtech/common/gui/widget/monitor/WidgetMonitorScreen.java b/src/main/java/gregtech/common/gui/widget/monitor/WidgetMonitorScreen.java new file mode 100644 index 00000000000..f0ac48fe075 --- /dev/null +++ b/src/main/java/gregtech/common/gui/widget/monitor/WidgetMonitorScreen.java @@ -0,0 +1,38 @@ +package gregtech.common.gui.widget.monitor; + +import gregtech.api.gui.IRenderContext; +import gregtech.api.gui.Widget; +import gregtech.api.util.Position; +import gregtech.api.util.RenderUtil; +import gregtech.api.util.Size; +import gregtech.common.metatileentities.multi.electric.centralmonitor.MetaTileEntityMonitorScreen; +import net.minecraft.client.renderer.GlStateManager; + +public class WidgetMonitorScreen extends Widget { + private final MetaTileEntityMonitorScreen screen; + + public WidgetMonitorScreen(int x, int y, int w, MetaTileEntityMonitorScreen screen) { + super(new Position(x, y), new Size(w + 4, w + 4)); + this.screen = screen; + } + + @Override + public void drawInBackground(int mouseX, int mouseY, IRenderContext context) { + Position position = this.getPosition(); + Size size = this.getSize(); + RenderUtil.renderRect(position.x, position.y, size.width, size.height, 0, 0XFF7B7A7C); + RenderUtil.renderRect(position.x + 2, position.y + 2, size.width - 4, size.height - 4, 0, 0XFF000000); + + if (screen != null && screen.isActive()) { + GlStateManager.pushMatrix(); + GlStateManager.translate(position.x + 2 + 0.5 * (size.width - 4), position.y + 2 + 0.5 * (size.height - 4),0); + GlStateManager.scale(size.getWidth(), size.getWidth(), 1.0f / size.getWidth()); + GlStateManager.scale(1 / screen.scale,1 / screen.scale,1 / screen.scale); + GlStateManager.translate(-(screen.scale - 1) * 0.5, -(screen.scale - 1) * 0.5, 0); + + screen.renderScreen(0,null); + GlStateManager.popMatrix(); + } + + } +} diff --git a/src/main/java/gregtech/common/gui/widget/monitor/WidgetPluginConfig.java b/src/main/java/gregtech/common/gui/widget/monitor/WidgetPluginConfig.java new file mode 100644 index 00000000000..22d641f4243 --- /dev/null +++ b/src/main/java/gregtech/common/gui/widget/monitor/WidgetPluginConfig.java @@ -0,0 +1,77 @@ +package gregtech.common.gui.widget.monitor; + +import gregtech.api.gui.IRenderContext; +import gregtech.api.gui.ModularUI; +import gregtech.api.gui.Widget; +import gregtech.api.gui.resources.TextureArea; +import gregtech.api.gui.widgets.SlotWidget; +import gregtech.api.gui.widgets.WidgetGroup; +import gregtech.api.util.Position; +import gregtech.api.util.Size; +import net.minecraft.entity.player.InventoryPlayer; + +public class WidgetPluginConfig extends WidgetGroup { + protected TextureArea textureArea; + int width,height; + + public WidgetPluginConfig setSize(int width, int height) { + setSize(new Size(width, height)); + this.width = width; + this.height = height; + if (this.gui != null) { + setSelfPosition(new Position((gui.getWidth() - width) / 2, (gui.getHeight() - height) / 2)); + onPositionUpdate(); + } + return this; + } + + @Override + public void setGui(ModularUI gui) { + super.setGui(gui); + setSelfPosition(new Position((gui.getWidth() - width) / 2, (gui.getHeight() - height) / 2)); + onPositionUpdate(); + } + + public WidgetPluginConfig setBackGround(TextureArea textureArea){ + this.textureArea = textureArea; + return this; + } + + public WidgetPluginConfig widget(Widget widget){ + addWidget(widget); + return this; + } + + public void removePluginWidget() { + clearAllWidgets(); + } + + public WidgetPluginConfig bindPlayerInventory(InventoryPlayer inventoryPlayer, TextureArea imageLocation, int x, int y) { + for(int row = 0; row < 3; ++row) { + for(int col = 0; col < 9; ++col) { + this.widget((new SlotWidget(inventoryPlayer, col + (row + 1) * 9, x + col * 18, y + row * 18)).setBackgroundTexture(new TextureArea[]{imageLocation}).setLocationInfo(true, false)); + } + } + + return this.bindPlayerHotbar(inventoryPlayer, imageLocation, x, y + 58); + } + + public WidgetPluginConfig bindPlayerHotbar(InventoryPlayer inventoryPlayer, TextureArea imageLocation, int x, int y) { + for(int slot = 0; slot < 9; ++slot) { + this.widget((new SlotWidget(inventoryPlayer, slot, x + slot * 18, y)).setBackgroundTexture(new TextureArea[]{imageLocation}).setLocationInfo(true, true)); + } + + return this; + } + + @Override + public void drawInBackground(int mouseX, int mouseY, IRenderContext context) { + if (widgets.size() > 0 && textureArea != null) { + Position pos = this.getPosition(); + Size size = this.getSize(); + textureArea.draw(pos.x, pos.y, size.width, size.height); + } + super.drawInBackground(mouseX, mouseY, context); + } + +} diff --git a/src/main/java/gregtech/common/gui/widget/monitor/WidgetScreenGrid.java b/src/main/java/gregtech/common/gui/widget/monitor/WidgetScreenGrid.java new file mode 100644 index 00000000000..bbe4e571df6 --- /dev/null +++ b/src/main/java/gregtech/common/gui/widget/monitor/WidgetScreenGrid.java @@ -0,0 +1,98 @@ +package gregtech.common.gui.widget.monitor; + +import gregtech.api.gui.IRenderContext; +import gregtech.api.gui.Widget; +import gregtech.api.metatileentity.MetaTileEntityUIFactory; +import gregtech.api.util.Position; +import gregtech.api.util.RenderUtil; +import gregtech.api.util.Size; +import gregtech.common.metatileentities.multi.electric.centralmonitor.MetaTileEntityMonitorScreen; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import org.lwjgl.input.Mouse; + +public class WidgetScreenGrid extends Widget { + public int x,y; + public static final int width = 20; + public static final int height = 20; + MetaTileEntityMonitorScreen monitorScreen; + private int color = 0XFF000000; + + public WidgetScreenGrid(int xPosition, int yPosition, int x, int y) { + super(new Position(xPosition + x * width, yPosition + y * height), new Size(width, height)); + this.x = x; this.y = y; + } + + public void setScreen(MetaTileEntityMonitorScreen monitorScreen) { + this.monitorScreen = monitorScreen; + color = (monitorScreen != null && monitorScreen.isActive())? 0XFF4F66FF : 0XFF000000; + } + + @SideOnly(Side.CLIENT) + @Override + public void drawInBackground(int mouseX, int mouseY, IRenderContext context) { + int x = this.getPosition().x; + int y = this.getPosition().y; + int width = this.getSize().width; + int height = this.getSize().height; + int color = (monitorScreen != null && monitorScreen.isActive())? monitorScreen.frameColor:this.color; + Gui.drawRect(x + 1, y + 1, x + width - 2, y + height - 2, color); +// if (monitorScreen.scale > 1) { +// width = (int) (monitorScreen.scale * width); +// height = (int) (monitorScreen.scale * height); +// Gui.drawRect(x, y, x + width - 1, y + 1, color); +// Gui.drawRect(x, y + height - 1, x + width - 1, y + height, color); +// Gui.drawRect(x, y, x + 1, y + height, color); +// Gui.drawRect(x + width - 1, y, x + width, y + height, color); +// } +// if (this.isMouseOverElement(mouseX, mouseY)) { +// Gui.drawRect(x, y, x + width, y + height, 0x4B6C6C6C); +// } + } + + @SideOnly(Side.CLIENT) + @Override + public void drawInForeground(int mouseX, int mouseY) { + if (this.isMouseOverElement(mouseX, mouseY)) { + if (monitorScreen != null && monitorScreen.isActive()) { + int x = this.getPosition().x; + int y = this.getPosition().y; + int width = this.getSize().width; + int height = this.getSize().height; + GlStateManager.pushMatrix(); + GlStateManager.translate(x + (width / 2), y + (height / 2), 100); + GlStateManager.scale(width, height, 1); + RenderUtil.renderRect(-0.5f, -0.5f, this.monitorScreen.scale, this.monitorScreen.scale, 0, 0XFF000000); + monitorScreen.renderScreen(0, null); + GlStateManager.popMatrix(); + } + } + } + + @SideOnly(Side.CLIENT) + @Override + public boolean mouseClicked(int mouseX, int mouseY, int button) { + if (this.isMouseOverElement(mouseX, mouseY)) { + ClickData clickData = new ClickData(Mouse.getEventButton(), this.isShiftDown(), this.isCtrlDown()); + this.writeClientAction(1, clickData::writeToBuf); + this.playButtonClickSound(); + return true; + } else { + return false; + } + } + + @Override + public void handleClientAction(int id, PacketBuffer buffer) { + super.handleClientAction(id, buffer); + if (id == 1) { + if (monitorScreen != null) { + MetaTileEntityUIFactory.INSTANCE.openUI(monitorScreen.getHolder(), (EntityPlayerMP) this.gui.entityPlayer); + } + } + } +} diff --git a/src/main/java/gregtech/common/items/MetaItem1.java b/src/main/java/gregtech/common/items/MetaItem1.java index e6046f78eca..15a4e367635 100644 --- a/src/main/java/gregtech/common/items/MetaItem1.java +++ b/src/main/java/gregtech/common/items/MetaItem1.java @@ -19,6 +19,10 @@ import gregtech.api.util.RandomPotionEffect; import gregtech.common.ConfigHolder; import gregtech.common.items.behaviors.*; +import gregtech.common.items.behaviors.monitorplugin.AdvancedMonitorPluginBehavior; +import gregtech.common.items.behaviors.monitorplugin.FakeGuiPluginBehavior; +import gregtech.common.items.behaviors.monitorplugin.OnlinePicPluginBehavior; +import gregtech.common.items.behaviors.monitorplugin.TextPluginBehavior; import net.minecraft.init.Items; import net.minecraft.init.MobEffects; import net.minecraft.item.EnumDyeColor; @@ -290,6 +294,9 @@ public void registerSubItems() { COVER_SHUTTER = addItem(309, "cover.shutter"); COVER_INFINITE_WATER = addItem(310, "cover.infinite_water"); COVER_ENDER_FLUID_LINK = addItem(311, "cover.ender_fluid_link"); + COVER_DIGITAL_INTERFACE = addItem(312, "cover.digital"); + COVER_DIGITAL_INTERFACE_WIRELESS = addItem(313, "cover.digital.wireless"); + COVER_FACADE = addItem(330, "cover.facade").addComponents(new FacadeItem()).disableModelLoading(); // Solar Panels: ID 331-346 @@ -569,6 +576,16 @@ public void registerSubItems() { IMPELLER_MV = addItem(776, "impeller.mv").setRarity(EnumRarity.UNCOMMON); IMPELLER_HV = addItem(777, "impeller.hv").setRarity(EnumRarity.RARE); GRAVITATION_ENGINE = addItem(778, "gravitation_engine").setRarity(EnumRarity.EPIC); + + // Plugins: 780-799 + PLUGIN_ADVANCED_MONITOR = addItem(780, "plugin.advanced_monitor").addComponents(new AdvancedMonitorPluginBehavior()); + PLUGIN_FAKE_GUI = addItem(781, "plugin.fake_gui").addComponents(new FakeGuiPluginBehavior()); + PLUGIN_ONLINE_PIC = addItem(782, "plugin.online_pic").addComponents(new OnlinePicPluginBehavior()); + PLUGIN_TEXT = addItem(783, "plugin.text").addComponents(new TextPluginBehavior()); + + COLOURED_LEDS = addItem(800, "coloured.leds"); + DISPLAY = addItem(801, "display"); + } } diff --git a/src/main/java/gregtech/common/items/MetaItems.java b/src/main/java/gregtech/common/items/MetaItems.java index dc3c41c116e..8b49e15cb31 100644 --- a/src/main/java/gregtech/common/items/MetaItems.java +++ b/src/main/java/gregtech/common/items/MetaItems.java @@ -398,6 +398,8 @@ private MetaItems() { public static MetaItem.MetaValueItem COVER_DRAIN; public static MetaItem.MetaValueItem COVER_INFINITE_WATER; public static MetaItem.MetaValueItem COVER_ENDER_FLUID_LINK; + public static MetaItem.MetaValueItem COVER_DIGITAL_INTERFACE; + public static MetaItem.MetaValueItem COVER_DIGITAL_INTERFACE_WIRELESS; public static MetaItem.MetaValueItem COVER_SOLAR_PANEL; public static MetaItem.MetaValueItem COVER_SOLAR_PANEL_ULV; @@ -410,6 +412,15 @@ private MetaItems() { public static MetaItem.MetaValueItem COVER_SOLAR_PANEL_ZPM; public static MetaItem.MetaValueItem COVER_SOLAR_PANEL_UV; + + public static MetaItem.MetaValueItem PLUGIN_TEXT; + public static MetaItem.MetaValueItem PLUGIN_ONLINE_PIC; + public static MetaItem.MetaValueItem PLUGIN_FAKE_GUI; + public static MetaItem.MetaValueItem PLUGIN_ADVANCED_MONITOR; + + public static MetaItem.MetaValueItem COLOURED_LEDS; + public static MetaItem.MetaValueItem DISPLAY; + public static MetaItem.MetaValueItem INTEGRATED_CIRCUIT; public static MetaItem.MetaValueItem FOAM_SPRAYER; diff --git a/src/main/java/gregtech/common/items/behaviors/ClipboardBehavior.java b/src/main/java/gregtech/common/items/behaviors/ClipboardBehavior.java index f90c7712f3a..846803fedc0 100644 --- a/src/main/java/gregtech/common/items/behaviors/ClipboardBehavior.java +++ b/src/main/java/gregtech/common/items/behaviors/ClipboardBehavior.java @@ -62,7 +62,7 @@ public ModularUI createMTEUI(PlayerInventoryHolder holder, EntityPlayer entityPl ModularUI.Builder builder = ModularUI.builder(GuiTextures.BACKGROUND, 170, 238); builder.image(18, 8, 130, 14, GuiTextures.CLIPBOARD_TEXT_BOX); - builder.widget(new SimpleTextWidget(20, 10, "", 0xFFFFFF, () -> getTitle(holder), true).setCenter(false)); + builder.widget(new SimpleTextWidget(20, 10, "", 0xFFFFFF, () -> getTitle(holder), false).setCenter(false)); for (int i = 0; i < 8; i++) { @@ -70,7 +70,7 @@ public ModularUI createMTEUI(PlayerInventoryHolder holder, EntityPlayer entityPl builder.widget(new ImageCycleButtonWidget(6, 37 + 20 * i, 15, 15, GuiTextures.CLIPBOARD_BUTTON, 4, () -> getButtonState(holder, finalI), (x) -> setButton(holder, finalI, x))); builder.image(22, 38 + 20 * i, 140, 12, GuiTextures.CLIPBOARD_TEXT_BOX); - builder.widget(new SimpleTextWidget(24, 40 + 20 * i, "", 0xFFFFFF, () -> getString(holder, finalI), true).setCenter(false)); + builder.widget(new SimpleTextWidget(24, 40 + 20 * i, "", 0xFFFFFF, () -> getString(holder, finalI), false).setCenter(false)); } builder.widget(new ClickButtonWidget(30, 200, 16, 16, "", (x) -> incrPageNum(holder, -1)) diff --git a/src/main/java/gregtech/common/items/behaviors/CoverDigitalInterfaceWirelessPlaceBehaviour.java b/src/main/java/gregtech/common/items/behaviors/CoverDigitalInterfaceWirelessPlaceBehaviour.java new file mode 100644 index 00000000000..5d5b3fa996f --- /dev/null +++ b/src/main/java/gregtech/common/items/behaviors/CoverDigitalInterfaceWirelessPlaceBehaviour.java @@ -0,0 +1,77 @@ +package gregtech.common.items.behaviors; + +import gregtech.api.cover.CoverDefinition; +import gregtech.api.metatileentity.MetaTileEntityHolder; +import gregtech.common.metatileentities.multi.electric.centralmonitor.MetaTileEntityCentralMonitor; +import gregtech.common.render.WorldRenderEventRenderer; +import net.minecraft.client.resources.I18n; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTUtil; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ActionResult; +import net.minecraft.util.EnumActionResult; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import java.util.List; + +public class CoverDigitalInterfaceWirelessPlaceBehaviour extends CoverPlaceBehavior { + public CoverDigitalInterfaceWirelessPlaceBehaviour(CoverDefinition coverDefinition) { + super(coverDefinition); + } + + public static BlockPos getRemotePos(ItemStack itemStack) { + NBTTagCompound tag = itemStack.getTagCompound(); + if (tag != null) { + return NBTUtil.getPosFromTag(tag); + } + return null; + } + + @Override + public void onUpdate(ItemStack itemStack, Entity entity) { + if (entity.world.isRemote && entity instanceof EntityPlayer) { + ItemStack held = ((EntityPlayer) entity).getHeldItemMainhand(); + if (held == itemStack) { + BlockPos pos = getRemotePos(itemStack); + if (pos != null) { + WorldRenderEventRenderer.renderBlockBoxHighLight(pos, 1500); + } + } + } + } + + @Override + public EnumActionResult onItemUseFirst(EntityPlayer player, World world, BlockPos pos, EnumFacing side, float hitX, float hitY, float hitZ, EnumHand hand) { + TileEntity tileEntity = world.getTileEntity(pos); + if (tileEntity instanceof MetaTileEntityHolder && ((MetaTileEntityHolder) tileEntity).getMetaTileEntity() instanceof MetaTileEntityCentralMonitor) { + ItemStack itemStack = player.getHeldItem(hand); + itemStack.setTagCompound(NBTUtil.createPosTag(pos)); + return EnumActionResult.SUCCESS; + } + return super.onItemUseFirst(player, world, pos, side, hitX, hitY, hitZ, hand); + } + + @Override + public ActionResult onItemRightClick(World world, EntityPlayer player, EnumHand hand) { + if (player.isSneaking()) { + player.getHeldItem(hand).setTagCompound(null); + return ActionResult.newResult(EnumActionResult.SUCCESS, player.getHeldItem(hand)); + } + return ActionResult.newResult(EnumActionResult.PASS, player.getHeldItem(hand)); + } + + @Override + public void addInformation(ItemStack itemStack, List lines) { + BlockPos pos = getRemotePos(itemStack); + String binding = pos == null ? "---" : String.format("%d, %d, %d", pos.getX(), pos.getY(), pos.getZ()); + lines.add(I18n.format("metaitem.cover.digital.wireless.tooltip.1")); + lines.add(I18n.format("metaitem.cover.digital.wireless.tooltip.2")); + lines.add(I18n.format("metaitem.cover.digital.wireless.tooltip.3", binding)); + } +} diff --git a/src/main/java/gregtech/common/items/behaviors/monitorplugin/AdvancedMonitorPluginBehavior.java b/src/main/java/gregtech/common/items/behaviors/monitorplugin/AdvancedMonitorPluginBehavior.java new file mode 100644 index 00000000000..060f947ddc8 --- /dev/null +++ b/src/main/java/gregtech/common/items/behaviors/monitorplugin/AdvancedMonitorPluginBehavior.java @@ -0,0 +1,435 @@ +package gregtech.common.items.behaviors.monitorplugin; + +import codechicken.lib.render.BlockRenderer; +import codechicken.lib.render.CCRenderState; +import codechicken.lib.render.pipeline.ColourMultiplier; +import codechicken.lib.vec.Cuboid6; +import codechicken.lib.vec.Translation; +import gregtech.api.capability.GregtechDataCodes; +import gregtech.api.gui.IUIHolder; +import gregtech.api.gui.widgets.LabelWidget; +import gregtech.api.gui.widgets.ToggleButtonWidget; +import gregtech.api.items.behavior.MonitorPluginBaseBehavior; +import gregtech.api.items.behavior.ProxyHolderPluginBehavior; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.MetaTileEntityHolder; +import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; +import gregtech.api.multiblock.PatternMatchContext; +import gregtech.api.render.scene.FBOWorldSceneRenderer; +import gregtech.api.render.scene.TrackedDummyWorld; +import gregtech.api.render.scene.WorldSceneRenderer; +import gregtech.api.util.RenderUtil; +import gregtech.common.gui.widget.WidgetScrollBar; +import gregtech.common.gui.widget.monitor.WidgetPluginConfig; +import gregtech.common.metatileentities.multi.electric.centralmonitor.MetaTileEntityCentralMonitor; +import gregtech.common.metatileentities.multi.electric.centralmonitor.MetaTileEntityMonitorScreen; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.client.shader.Framebuffer; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.init.Blocks; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import org.apache.commons.lang3.tuple.MutablePair; +import org.apache.commons.lang3.tuple.Pair; +import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.GL11; + +import javax.vecmath.Vector3f; +import java.util.*; + +public class AdvancedMonitorPluginBehavior extends ProxyHolderPluginBehavior { + @SideOnly(Side.CLIENT) + private static Framebuffer FBO; + private static final int RESOLUTION = 1080; + + private float scale; + private int rotationPitch; + private int rotationYaw; + private float spin; + private boolean connect; + + //run-time + @SideOnly(Side.CLIENT) + private FBOWorldSceneRenderer worldSceneRenderer; + @SideOnly(Side.CLIENT) + private Map, Vector3f>> connections; + @SideOnly(Side.CLIENT) + private Vector3f center; + @SideOnly(Side.CLIENT) + private double[] lastMouse; + private boolean isValid; + Set validPos; + + @SideOnly(Side.CLIENT) + private void createWorldScene() { + if (this.screen == null || this.screen.getWorld() == null) return; + isValid = true; + World world = this.screen.getWorld(); + int minX = Integer.MAX_VALUE; + int minY = Integer.MAX_VALUE; + int minZ = Integer.MAX_VALUE; + int maxX = Integer.MIN_VALUE; + int maxY = Integer.MIN_VALUE; + int maxZ = Integer.MIN_VALUE; + for (BlockPos pos : validPos) { + minX = Math.min(minX, pos.getX()); + minY = Math.min(minY, pos.getY()); + minZ = Math.min(minZ, pos.getZ()); + maxX = Math.max(maxX, pos.getX()); + maxY = Math.max(maxY, pos.getY()); + maxZ = Math.max(maxZ, pos.getZ()); + } + if (FBO == null) { + FBO = new Framebuffer(RESOLUTION, RESOLUTION, true); + } + TrackedDummyWorld dummyWorld = new TrackedDummyWorld(world); + dummyWorld.setRenderFilter(pos->validPos.contains(pos)); + worldSceneRenderer = new FBOWorldSceneRenderer(dummyWorld, FBO); + worldSceneRenderer.addRenderedBlocks(validPos, null); + center = new Vector3f((minX + maxX) / 2f + 0.5f, (minY + maxY) / 2f + 0.5f, (minZ + maxZ) / 2f + 0.5f); + worldSceneRenderer.setCameraLookAt(center, 10 / scale, Math.toRadians(rotationPitch), Math.toRadians(rotationYaw)); + worldSceneRenderer.setBeforeWorldRender(this::renderBefore); + worldSceneRenderer.setAfterWorldRender(this::renderAfter); + worldSceneRenderer.setOnLookingAt(rayTrace->renderBlockOverLay(rayTrace.getBlockPos())); + } + + @SideOnly(Side.CLIENT) + private void renderBefore(WorldSceneRenderer renderer) { + if (spin > 0 && lastMouse == null) { + worldSceneRenderer.setCameraLookAt(center, 10 / scale, Math.toRadians(rotationPitch), Math.toRadians(rotationYaw)); + } + } + + @SideOnly(Side.CLIENT) + private void renderAfter(WorldSceneRenderer renderer) { + if (lastMouse != null) { + int mouseX = (int) (RESOLUTION * lastMouse[0]); + int mouseY = (int) (RESOLUTION * (1 - (lastMouse[1]))); + Vector3f hitPos = renderer.unProject(mouseX, mouseY); + Vec3d eyePos = new Vec3d(renderer.getEyePos().x, renderer.getEyePos().y, renderer.getEyePos().z); + hitPos.scale(2); // Double view range to ensure pos can be seen. + Vec3d endPos = new Vec3d((hitPos.x - eyePos.x), (hitPos.y - eyePos.y), (hitPos.z - eyePos.z)); + double min = Float.MAX_VALUE; + BlockPos pos = null; + for (BlockPos core : validPos) { + IBlockState blockState = renderer.world.getBlockState(core); + if (blockState.getBlock() == Blocks.AIR) { + continue; + } + RayTraceResult hit = blockState.collisionRayTrace(renderer.world, core, eyePos, endPos); + if (hit != null && hit.typeOfHit != RayTraceResult.Type.MISS) { + double dist = eyePos.distanceTo(new Vec3d(hit.getBlockPos())); + if (dist < min) { + min = dist; + pos = hit.getBlockPos(); + } + } + } + if (pos != null) { + renderBlockOverLay(pos); + } + } + if (connect && connections != null) { + for (BlockPos pos : connections.keySet()) { + Vector3f winPos = worldSceneRenderer.project(pos); + connections.get(pos).setValue(winPos); + if (winPos != null) { + renderBlockOverLay(pos); + } + } + } + } + + @SideOnly(Side.CLIENT) + private void renderBlockOverLay(BlockPos pos) { + GlStateManager.enableBlend(); + GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE); + GlStateManager.translate((pos.getX() + 0.5), (pos.getY() + 0.5), (pos.getZ() + 0.5)); + GlStateManager.scale(1.01, 1.01, 1.01); + Tessellator tessellator = Tessellator.getInstance(); + GlStateManager.disableTexture2D(); + CCRenderState renderState = CCRenderState.instance(); + renderState.startDrawing(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR, tessellator.getBuffer()); + ColourMultiplier multiplier = new ColourMultiplier(0); + renderState.setPipeline(new Translation(-0.5, -0.5, -0.5), multiplier); + BlockRenderer.BlockFace blockFace = new BlockRenderer.BlockFace(); + renderState.setModel(blockFace); + for (EnumFacing renderSide : EnumFacing.VALUES) { + multiplier.colour = RenderUtil.packColor(255, 255, 255, 100); + blockFace.loadCuboidFace(Cuboid6.full, renderSide.getIndex()); + renderState.render(); + } + renderState.draw(); + GlStateManager.scale(1 / 1.01, 1 / 1.01, 1 / 1.01); + GlStateManager.translate(-(pos.getX() + 0.5), -(pos.getY() + 0.5), -(pos.getZ() + 0.5)); + GlStateManager.enableTexture2D(); + + GlStateManager.color(1, 1, 1, 1); + } + + public void setConfig(float scale, int rY, int rX, float spin, boolean connect) { + if (this.scale == scale && this.rotationPitch == rY && this.rotationYaw == rX && this.spin == spin && this.connect == connect) + return; + if (scale < 0.3 || scale > 2 || rY < 0 || rY > 360 || rX < -90 || rX > 90 || spin < 0 || spin > 2) + return; + this.scale = scale; + this.rotationPitch = rY; + this.rotationYaw = rX; + this.spin = spin; + this.connect = connect; + if (this.screen.getWorld().isRemote) { + if (worldSceneRenderer != null) { + worldSceneRenderer.setCameraLookAt(center, 10 / scale, Math.toRadians(rY), Math.toRadians(rX)); + } + } else { + writePluginData(GregtechDataCodes.UPDATE_PLUGIN_CONFIG, buffer -> { + buffer.writeFloat(scale); + buffer.writeVarInt(rY); + buffer.writeVarInt(rX); + buffer.writeFloat(spin); + buffer.writeBoolean(connect); + }); + markAsDirty(); + } + } + + @Override + public void update() { + super.update(); + if (this.screen.getOffsetTimer() % 20 == 0) { + if (this.screen.getWorld().isRemote) { // check connections + if (worldSceneRenderer == null && validPos != null && validPos.size() > 0) { + createWorldScene(); + } + if (this.connect && worldSceneRenderer != null && this.screen.getController() instanceof MetaTileEntityCentralMonitor) { + if (connections == null) connections = new HashMap<>(); + connections.clear(); + for (MetaTileEntityMonitorScreen[] monitorScreens : ((MetaTileEntityCentralMonitor) this.screen.getController()).screens) { + for (MetaTileEntityMonitorScreen screen : monitorScreens) { + if (screen != null && screen.plugin instanceof FakeGuiPluginBehavior && ((FakeGuiPluginBehavior) screen.plugin).getHolder() == this.holder) { + MetaTileEntity met = ((FakeGuiPluginBehavior) screen.plugin).getRealMTE(); + if (met != null) { + BlockPos pos = met.getPos(); + Pair, Vector3f> tuple = connections.getOrDefault(pos, new MutablePair<>(new ArrayList<>(), null)); + tuple.getLeft().add(screen); + connections.put(pos, tuple); + } + } + } + } + } + } else { // check multi-block valid + if (holder != null && holder.getMetaTileEntity() instanceof MultiblockControllerBase) { + MultiblockControllerBase entity = (MultiblockControllerBase) holder.getMetaTileEntity(); + if (entity.isStructureFormed()) { + if (!isValid) { + validPos = new HashSet<>(); + PatternMatchContext result = entity.structurePattern.checkPatternAt(entity.getWorld(), entity.getPos(), entity.getFrontFacing().getOpposite(), validPos); + if (result != null) { + writePluginData(GregtechDataCodes.UPDATE_ADVANCED_VALID_POS, buf -> { + buf.writeVarInt(validPos.size()); + for (BlockPos pos : validPos) { + buf.writeBlockPos(pos); + } + }); + isValid = true; + } else { + validPos.clear(); + } + } + } else if (isValid) { + writePluginData(GregtechDataCodes.UPDATE_ADVANCED_VALID_POS, buf -> buf.writeVarInt(0)); + isValid = false; + } + } + } + } + if (this.screen.getWorld().isRemote && spin > 0 && lastMouse == null) { + rotationPitch = (int) ((rotationPitch + spin * 4)% 360); + } + } + + @Override + public WidgetPluginConfig customUI(WidgetPluginConfig widgetGroup, IUIHolder holder, EntityPlayer entityPlayer) { + return widgetGroup.setSize(260, 170) + .widget(new WidgetScrollBar(25, 20, 210, 0.3f, 2, 0.1f, value -> setConfig(value, this.rotationPitch, this.rotationYaw, this.spin, this.connect)).setTitle("zoom", 0XFFFFFFFF).setInitValue(this.scale)) + .widget(new WidgetScrollBar(25, 40, 210, 0, 360, 1, value -> setConfig(this.scale, value.intValue(), this.rotationYaw, this.spin, this.connect)).setTitle("rotationPitch", 0XFFFFFFFF).setInitValue(this.rotationPitch)) + .widget(new WidgetScrollBar(25, 60, 210, -90, 90, 1, value -> setConfig(this.scale, this.rotationPitch, value.intValue(), this.spin, this.connect)).setTitle("rotationYaw", 0XFFFFFFFF).setInitValue(this.rotationYaw)) + .widget(new WidgetScrollBar(25, 100, 210, 0, 2, 0.1f, value -> setConfig(this.scale, this.rotationPitch, this.rotationYaw, value, this.connect)).setTitle("spinDur", 0XFFFFFFFF).setInitValue(this.spin)) + .widget(new LabelWidget(25, 135, "Fake GUI:", 0XFFFFFFFF)) + .widget(new ToggleButtonWidget(80, 130, 20, 20, () -> this.connect, state -> setConfig(this.scale, this.rotationPitch, this.rotationYaw, this.spin, state))); + } + + @Override + public void writeInitialSyncData(PacketBuffer buf) { + super.writeInitialSyncData(buf); + if (validPos != null && validPos.size() > 0) { + buf.writeVarInt(validPos.size()); + for (BlockPos pos : validPos) { + buf.writeBlockPos(pos); + } + } else { + buf.writeVarInt(0); + } + } + + @Override + public void receiveInitialSyncData(PacketBuffer buf) { + loadValidPos(buf); + } + + @Override + public void writeToNBT(NBTTagCompound data) { + super.writeToNBT(data); + data.setFloat("scale", this.scale); + data.setInteger("rY", this.rotationPitch); + data.setInteger("rX", this.rotationYaw); + data.setFloat("spin", this.spin); + data.setBoolean("connect", this.connect); + } + + @Override + public void readFromNBT(NBTTagCompound data) { + super.readFromNBT(data); + this.scale = data.hasKey("scale") ? data.getFloat("scale") : 0.6f; + this.rotationPitch = data.hasKey("rY") ? data.getInteger("rY") : 45; + this.rotationYaw = data.hasKey("rX") ? data.getInteger("rX") : 0; + this.spin = data.hasKey("spin") ? data.getFloat("spin") : 0f; + this.connect = data.hasKey("connect") && data.getBoolean("connect"); + } + + @Override + public void readPluginData(int id, PacketBuffer buf) { + if (id == GregtechDataCodes.UPDATE_ADVANCED_VALID_POS) { + loadValidPos(buf); + } else if (id == GregtechDataCodes.UPDATE_PLUGIN_CONFIG) { + this.scale = buf.readFloat(); + this.rotationPitch = buf.readVarInt(); + this.rotationYaw = buf.readVarInt(); + this.spin = buf.readFloat(); + this.connect = buf.readBoolean(); + if (worldSceneRenderer != null) { + worldSceneRenderer.setCameraLookAt(center, 10 / scale, Math.toRadians(rotationPitch), Math.toRadians(rotationYaw)); + } + } + } + + private void loadValidPos(PacketBuffer buf) { + int size = buf.readVarInt(); + if (size > 0) { + validPos = new HashSet<>(); + for (int i = 0; i < size; i++) { + validPos.add(buf.readBlockPos()); + } + createWorldScene(); + } else { + validPos = null; + worldSceneRenderer = null; + isValid = false; + } + } + + @Override + public void readPluginAction(EntityPlayerMP player, int id, PacketBuffer buf) { + if (id == GregtechDataCodes.ACTION_PLUGIN_CONFIG) { //open GUI + BlockPos pos = buf.readBlockPos(); + TileEntity tileEntity = this.screen.getWorld().getTileEntity(pos); + if (tileEntity instanceof MetaTileEntityHolder && ((MetaTileEntityHolder) tileEntity).isValid()) { + ((MetaTileEntityHolder) tileEntity).getMetaTileEntity().onRightClick(player, EnumHand.MAIN_HAND, ((MetaTileEntityHolder) tileEntity).getMetaTileEntity().getFrontFacing(), null); + } + } + } + + @Override + public boolean onClickLogic(EntityPlayer playerIn, EnumHand hand, EnumFacing facing, boolean isRight, double x, double y) { + if (this.screen.getWorld().isRemote) { + if (this.worldSceneRenderer != null) { + RayTraceResult rayTrace = this.worldSceneRenderer.screenPos2BlockPosFace((int) (x * RESOLUTION), (int) ((1 - y) * RESOLUTION)); + if (rayTrace != null && isRight) { + writePluginAction(GregtechDataCodes.ACTION_PLUGIN_CONFIG, buf -> buf.writeBlockPos(rayTrace.getBlockPos())); + } + } + } + return true; + } + + @Override + protected void onHolderChanged(MetaTileEntityHolder lastHolder) { + if (!this.screen.getWorld().isRemote) { + validPos = null; + isValid = false; + writePluginData(GregtechDataCodes.UPDATE_ADVANCED_VALID_POS, buf -> buf.writeVarInt(0)); + } + } + + @Override + public MonitorPluginBaseBehavior createPlugin() { + return new AdvancedMonitorPluginBehavior(); + } + + @Override + public void renderPlugin(float partialTicks, RayTraceResult rayTraceResult) { + if (worldSceneRenderer != null && this.screen != null) { + GlStateManager.pushMatrix(); + GlStateManager.translate(-0.5, -0.5, 0.01); + double[] currentMouse = this.screen.checkLookingAt(rayTraceResult); + if (currentMouse != null) { + worldSceneRenderer.render(0, 0, 1, 1, (float)currentMouse[0], (float)currentMouse[1]); + if (lastMouse != null) { + if (Mouse.isButtonDown(0)) { + rotationPitch += (currentMouse[0] - lastMouse[0]) * 300; + rotationPitch = rotationPitch % 360; + rotationYaw = (int) MathHelper.clamp(rotationYaw + (currentMouse[1] - lastMouse[1]) * 300, -89.9, 89.9); + } + worldSceneRenderer.setCameraLookAt(center, 10 / scale, Math.toRadians(rotationPitch), Math.toRadians(rotationYaw)); + } + } else { + worldSceneRenderer.render(0, 0, 1, 1, 0, 0); + } + + lastMouse = currentMouse; + + if (this.connect && connections != null) { + GlStateManager.scale(1 / this.screen.scale, 1 / this.screen.scale, 1); + for (Pair, Vector3f> tuple : connections.values()) { + Vector3f origin = tuple.getRight(); + List screens = tuple.getLeft(); + if (origin != null) { + float oX = (origin.x / RESOLUTION - 0.025f) * this.screen.scale; + float oY = (1 - origin.y / RESOLUTION) * this.screen.scale; + RenderUtil.renderRect(oX, oY, 0.05f, 0.05f, 0.002f, 0XFFFFFF00); + for (MetaTileEntityMonitorScreen screen : screens) { + float dX = screen.getX() - this.screen.getX() - 0.025f; + float dY = screen.getY() - this.screen.getY() + screen.scale / 2 - 0.025f; + float rX = screen.getX() - this.screen.getX() + screen.scale - 0.025f; + float rY = screen.getY() - this.screen.getY() + screen.scale / 2 - 0.025f; + if ((oX - dX) * (oX - dX) + (oY - dY) * (oY - dY) > (oX - rX) * (oX - rX) + (oY - rY) * (oY - rY)) { + dX = rX; + dY = rY; + } + RenderUtil.renderRect(dX, dY, 0.05f, 0.05f, 0.002f, screen.frameColor); + RenderUtil.renderLine(oX + 0.025f, oY + 0.025f, dX + 0.025f, dY + 0.025f, 0.01f, screen.frameColor); + } + } + + } + } + GlStateManager.popMatrix(); + } + } +} diff --git a/src/main/java/gregtech/common/items/behaviors/monitorplugin/FakeGuiPluginBehavior.java b/src/main/java/gregtech/common/items/behaviors/monitorplugin/FakeGuiPluginBehavior.java new file mode 100644 index 00000000000..058c882611f --- /dev/null +++ b/src/main/java/gregtech/common/items/behaviors/monitorplugin/FakeGuiPluginBehavior.java @@ -0,0 +1,282 @@ +package gregtech.common.items.behaviors.monitorplugin; + +import gregtech.api.capability.GregtechCapabilities; +import gregtech.api.capability.GregtechDataCodes; +import gregtech.api.gui.GuiTextures; +import gregtech.api.gui.IUIHolder; +import gregtech.api.gui.ModularUI; +import gregtech.api.gui.Widget; +import gregtech.api.gui.impl.FakeModularGui; +import gregtech.api.gui.widgets.*; +import gregtech.api.items.behavior.MonitorPluginBaseBehavior; +import gregtech.api.items.behavior.ProxyHolderPluginBehavior; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.MetaTileEntityHolder; +import gregtech.api.metatileentity.multiblock.IMultiblockPart; +import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; +import gregtech.api.multiblock.PatternMatchContext; +import gregtech.api.util.GTLog; +import gregtech.api.util.GregFakePlayer; +import gregtech.common.gui.impl.FakeModularUIPluginContainer; +import gregtech.common.gui.widget.monitor.WidgetPluginConfig; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.RayTraceResult; +import net.minecraftforge.fml.common.ObfuscationReflectionHelper; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import net.minecraftforge.items.wrapper.PlayerMainInvWrapper; + +import java.lang.reflect.Method; +import java.util.*; + +public class FakeGuiPluginBehavior extends ProxyHolderPluginBehavior { + + private int partIndex; + + //run-time + @SideOnly(Side.CLIENT) + private FakeModularGui fakeModularGui; + private BlockPos partPos; + private FakeModularUIPluginContainer fakeModularUIContainer; + private GregFakePlayer fakePlayer; + private static final Method methodCreateUI = ObfuscationReflectionHelper.findMethod(MetaTileEntity.class, "createUI", ModularUI.class, EntityPlayer.class); + static{ + methodCreateUI.setAccessible(true); + } + + public void setConfig(int partIndex) { + if(this.partIndex == partIndex || partIndex < 0) return; + this.partIndex = partIndex; + this.partPos = null; + writePluginData(GregtechDataCodes.UPDATE_PLUGIN_CONFIG, buffer -> buffer.writeVarInt(this.partIndex)); + markAsDirty(); + } + + public MetaTileEntity getRealMTE() { + MetaTileEntity target = this.holder.getMetaTileEntity(); + if (target instanceof MultiblockControllerBase && partIndex > 0) { + if (partPos != null) { + TileEntity entity = this.screen.getWorld().getTileEntity(partPos); + if (entity instanceof MetaTileEntityHolder) { + return ((MetaTileEntityHolder) entity).getMetaTileEntity(); + } else { + partPos = null; + return null; + } + } + PatternMatchContext context = ((MultiblockControllerBase) target).structurePattern.checkPatternAt(target.getWorld(), target.getPos(), target.getFrontFacing().getOpposite()); + if (context == null) { + return null; + } + Set rawPartsSet = context.getOrCreate("MultiblockParts", HashSet::new); + List parts = new ArrayList<>(rawPartsSet); + parts.sort(Comparator.comparing((it) -> ((MetaTileEntity)it).getPos().hashCode())); + if (parts.size() > partIndex - 1 && parts.get(partIndex - 1) instanceof MetaTileEntity) { + target = (MetaTileEntity) parts.get(partIndex - 1); + partPos = target.getPos(); + } else { + return null; + } + } + return target; + } + + public void createFakeGui() { + if (this.holder == null || this.screen == null || !this.screen.isValid()) return; + try { + fakePlayer = new GregFakePlayer(this.screen.getWorld()); + MetaTileEntity mte = getRealMTE(); + if (mte == null || (this.partIndex > 0 && this.holder.getMetaTileEntity() == mte)) { + fakeModularUIContainer = null; + if (this.screen.getWorld().isRemote) { + fakeModularGui = null; + } + return; + } + ModularUI ui = (ModularUI) methodCreateUI.invoke(mte, fakePlayer); + if (ui == null) { + fakeModularUIContainer = null; + if (this.screen.getWorld().isRemote) { + fakeModularGui = null; + } + return; + } + List widgets = new ArrayList<>(); + boolean hasPlayerInventory = false; + for (Widget widget : ui.guiWidgets.values()) { + if (widget instanceof SlotWidget) { + IInventory handler = ((SlotWidget) widget).getHandle().inventory; + if (handler instanceof PlayerMainInvWrapper || handler instanceof InventoryPlayer) { + hasPlayerInventory = true; + continue; + } + } + widgets.add(widget); + } + ModularUI.Builder builder = new ModularUI.Builder(ui.backgroundPath, ui.getWidth(), ui.getHeight() - (hasPlayerInventory? 80:0)); + for (Widget widget : widgets) { + builder.widget(widget); + } + ui = builder.build(ui.holder, ui.entityPlayer); + fakeModularUIContainer = new FakeModularUIPluginContainer(ui, this); + if (this.screen.getWorld().isRemote) { + fakeModularGui = new FakeModularGui(ui, fakeModularUIContainer); + writePluginAction(GregtechDataCodes.ACTION_PLUGIN_CONFIG, buffer -> {}); + } + } catch (Exception e) { + GTLog.logger.error(e); + } + } + + @Override + public void readPluginAction(EntityPlayerMP player, int id, PacketBuffer buf) { + if (id == GregtechDataCodes.ACTION_PLUGIN_CONFIG) { + createFakeGui(); + } + if (id == GregtechDataCodes.ACTION_FAKE_GUI) { + if (this.fakeModularUIContainer != null) { + fakeModularUIContainer.handleClientAction(buf); + } + } + } + + @Override + public void writeToNBT(NBTTagCompound data) { + super.writeToNBT(data); + data.setInteger("part", partIndex); + } + + @Override + public void readFromNBT(NBTTagCompound data) { + super.readFromNBT(data); + partIndex = data.hasKey("part")? data.getInteger("part"):0; + } + + @Override + public void onHolderChanged(MetaTileEntityHolder lastHolder) { + if (holder == null) { + if (this.screen.getWorld() != null && this.screen.getWorld().isRemote) { + fakeModularGui = null; + } + fakeModularUIContainer = null; + fakePlayer = null; + } else { + if (this.screen.getWorld().isRemote) { + createFakeGui(); + } + } + } + + @Override + public void update() { + super.update(); + if (this.screen.getWorld().isRemote) { + if (partIndex > 0 && fakeModularUIContainer == null && this.screen.getOffsetTimer() % 20 == 0) { + createFakeGui(); + } + if (fakeModularGui != null) + fakeModularGui.updateScreen(); + } else { + if (partIndex > 0 && this.screen.getOffsetTimer() % 20 == 0) { + if (fakeModularUIContainer != null && getRealMTE() == null) { + this.writePluginData(GregtechDataCodes.UPDATE_PLUGIN_CONFIG, buf-> buf.writeVarInt(this.partIndex)); + fakeModularUIContainer = null; + } + } + if (fakeModularUIContainer != null) + fakeModularUIContainer.detectAndSendChanges(); + } + } + + @Override + public MonitorPluginBaseBehavior createPlugin() { + return new FakeGuiPluginBehavior(); + } + + @Override + public void renderPlugin(float partialTicks, RayTraceResult rayTraceResult) { + if (fakeModularGui != null) { + double[] result = this.screen.checkLookingAt(rayTraceResult); + GlStateManager.translate(0, 0, 0.01); + if (result == null) + fakeModularGui.drawScreen(0, 0, partialTicks); + else + fakeModularGui.drawScreen(result[0], result[1], partialTicks); + } + } + + @Override + public boolean onClickLogic(EntityPlayer playerIn, EnumHand hand, EnumFacing facing, boolean isRight, double x, double y) { + if (this.screen.getWorld().isRemote) return true; + if (fakeModularUIContainer != null && fakeModularUIContainer.modularUI != null && !playerIn.getHeldItemMainhand().hasCapability(GregtechCapabilities.CAPABILITY_SCREWDRIVER, null)) { + int width = fakeModularUIContainer.modularUI.getWidth(); + int height = fakeModularUIContainer.modularUI.getHeight(); + float halfW = width / 2f; + float halfH = height / 2f; + float scale = 0.5f / Math.max(halfW, halfH); + int mouseX = (int) ((x / scale) + (halfW > halfH? 0: (halfW - halfH))); + int mouseY = (int) ((y / scale) + (halfH > halfW? 0: (halfH - halfW))); + MetaTileEntity mte = getRealMTE(); + if (mte != null && 0 <= mouseX && mouseX <= width && 0 <= mouseY&& mouseY <= height) { + if (playerIn.isSneaking()) { + writePluginData(GregtechDataCodes.UPDATE_PLUGIN_CLICK, buf->{ + buf.writeVarInt(mouseX); + buf.writeVarInt(mouseY); + buf.writeVarInt(isRight?1:0); + buf.writeVarInt(fakeModularUIContainer.syncId); + }); + } else { + return isRight && mte.onRightClick(playerIn, hand, facing, null); + } + } + } + return false; + } + + @Override + public void readPluginData(int id, PacketBuffer buf) { + if (id == GregtechDataCodes.UPDATE_PLUGIN_CONFIG) { + this.partIndex = buf.readVarInt(); + this.partPos = null; + createFakeGui(); + } + else if (id == GregtechDataCodes.UPDATE_FAKE_GUI) { + int windowID = buf.readVarInt(); + int widgetID = buf.readVarInt(); + if (fakeModularGui != null) + fakeModularGui.handleWidgetUpdate(windowID, widgetID, buf); + } else if (id == GregtechDataCodes.UPDATE_FAKE_GUI_DETECT) { + if (fakeModularUIContainer != null) + fakeModularUIContainer.handleSlotUpdate(buf); + } else if (id == GregtechDataCodes.UPDATE_PLUGIN_CLICK) { + int mouseX = buf.readVarInt(); + int mouseY = buf.readVarInt(); + int button = buf.readVarInt(); + int syncID = buf.readVarInt(); + if (fakeModularGui != null && fakeModularUIContainer != null) { + fakeModularUIContainer.syncId = syncID; + fakeModularGui.mouseClicked(mouseX, mouseY, button); + } + } + } + + @Override + public WidgetPluginConfig customUI(WidgetPluginConfig widgetGroup, IUIHolder holder, EntityPlayer entityPlayer) { + return widgetGroup.setSize(170, 50) + .widget(new LabelWidget(20, 20, "Part:", 0xFFFFFFFF)) + .widget(new ClickButtonWidget(55, 15, 20, 20, "-1", (data) -> setConfig(this.partIndex - 1))) + .widget(new ClickButtonWidget(135, 15, 20, 20, "+1", (data) -> setConfig(this.partIndex + 1))) + .widget(new ImageWidget(75, 15, 60, 20, GuiTextures.DISPLAY)) + .widget(new SimpleTextWidget(105, 25, "", 16777215, () -> Integer.toString(this.partIndex))); + } +} diff --git a/src/main/java/gregtech/common/items/behaviors/monitorplugin/OnlinePicPluginBehavior.java b/src/main/java/gregtech/common/items/behaviors/monitorplugin/OnlinePicPluginBehavior.java new file mode 100644 index 00000000000..e0cf0e51a76 --- /dev/null +++ b/src/main/java/gregtech/common/items/behaviors/monitorplugin/OnlinePicPluginBehavior.java @@ -0,0 +1,169 @@ +package gregtech.common.items.behaviors.monitorplugin; + +import gregtech.api.capability.GregtechDataCodes; +import gregtech.api.gui.IUIHolder; +import gregtech.api.gui.resources.picturetexture.PictureTexture; +import gregtech.api.gui.resources.utils.DownloadThread; +import gregtech.api.gui.widgets.*; +import gregtech.api.items.behavior.MonitorPluginBaseBehavior; +import gregtech.common.gui.widget.WidgetScrollBar; +import gregtech.common.gui.widget.monitor.WidgetPluginConfig; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.math.RayTraceResult; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +public class OnlinePicPluginBehavior extends MonitorPluginBaseBehavior { + + public String url; + public float scaleX; + public float scaleY; + public float rotation; + public boolean flippedX; + public boolean flippedY; + + // run-time + private String tmpUrl; + + @SideOnly(Side.CLIENT) + private DownloadThread downloader; + @SideOnly(Side.CLIENT) + public PictureTexture texture; + @SideOnly(Side.CLIENT) + public boolean failed; + @SideOnly(Side.CLIENT) + public String error; + + public void setConfig(String url, float rotation, float scaleX, float scaleY, boolean flippedX, boolean flippedY) { + if (url.length() > 200 || (this.url.equals(url) && this.rotation == rotation && this.scaleX == scaleX && this.scaleY == scaleY && this.flippedX == flippedX && this.flippedY == flippedY)) return; + this.url = url; + this.rotation = rotation; + this.scaleX = scaleX; + this.scaleY = scaleY; + this.flippedX = flippedX; + this.flippedY = flippedY; + writePluginData(GregtechDataCodes.UPDATE_PLUGIN_CONFIG, packetBuffer -> { + packetBuffer.writeString(url); + packetBuffer.writeFloat(rotation); + packetBuffer.writeFloat(scaleX); + packetBuffer.writeFloat(scaleY); + packetBuffer.writeBoolean(flippedX); + packetBuffer.writeBoolean(flippedY); + }); + markAsDirty(); + } + + @Override + public void readPluginData(int id, PacketBuffer buf) { + if(id == GregtechDataCodes.UPDATE_PLUGIN_CONFIG){ + String _url = buf.readString(200); + if (!this.url.equals(_url)) { + this.url = _url; + this.texture = null; + this.failed = false; + this.error = null; + } + this.rotation = buf.readFloat(); + this.scaleX = buf.readFloat(); + this.scaleY = buf.readFloat(); + this.flippedX = buf.readBoolean(); + this.flippedY = buf.readBoolean(); + } + } + + @Override + public void writeToNBT(NBTTagCompound data) { + super.writeToNBT(data); + data.setString("url", url); + data.setFloat("rotation", rotation); + data.setFloat("scaleX", scaleX); + data.setFloat("scaleY", scaleY); + data.setBoolean("flippedX", flippedX); + data.setBoolean("flippedY", flippedY); + } + + @Override + public void readFromNBT(NBTTagCompound data) { + super.readFromNBT(data); + this.url = data.hasKey("url")? data.getString("url"):""; + this.rotation = data.hasKey("rotation")? data.getFloat("rotation"):0; + this.scaleX = data.hasKey("scaleX")? data.getFloat("scaleX"):1; + this.scaleY = data.hasKey("scaleY")? data.getFloat("scaleY"):1; + this.flippedX = data.hasKey("flippedX") && data.getBoolean("flippedX"); + this.flippedY = data.hasKey("flippedY") && data.getBoolean("flippedY"); + } + + @Override + public MonitorPluginBaseBehavior createPlugin() { + return new OnlinePicPluginBehavior(); + } + + @Override + public WidgetPluginConfig customUI(WidgetPluginConfig widgetGroup, IUIHolder holder, EntityPlayer entityPlayer) { + tmpUrl = url; + return widgetGroup.setSize(260, 150) + .widget(new DynamicLabelWidget(20, 20, ()->url.length() > 40?(url.substring(0, 39) + "..."):url,0XFFFFFFFF)) + .widget(new TextFieldWidget(20, 30, 175, 10, true, ()-> tmpUrl, (text)->{ + tmpUrl = text; + }).setValidator((data)->true).setMaxStringLength(200)) + .widget(new ClickButtonWidget(200, 30, 45, 10, "confirm", pressed-> setConfig(tmpUrl, this.rotation, this.scaleX, this.scaleY, this.flippedX, this.flippedY))) + .widget(new WidgetScrollBar(25, 40, 210, -180, 180, 1, value -> setConfig(this.url, value, this.scaleX, this.scaleY, this.flippedX, this.flippedY)).setTitle("rotation", 0XFFFFFFFF).setInitValue(this.rotation)) + .widget(new WidgetScrollBar(25, 60, 210, 0, 1, 0.05f, value -> setConfig(this.url, this.rotation, value, this.scaleY, this.flippedX, this.flippedY)).setTitle("scaleX", 0XFFFFFFFF).setInitValue(this.scaleX)) + .widget(new WidgetScrollBar(25, 80, 210, 0, 1, 0.05f, value -> setConfig(this.url, this.rotation, this.scaleX, value, this.flippedX, this.flippedY)).setTitle("scaleY", 0XFFFFFFFF).setInitValue(this.scaleY)) + .widget(new LabelWidget(40, 115, "flippedX:", 0XFFFFFFFF)) + .widget(new ToggleButtonWidget(90, 110, 20, 20, ()->this.flippedX, state -> setConfig(this.url, this.rotation, this.scaleX, this.scaleY, state, this.flippedY))) + .widget(new LabelWidget(140, 115, "flippedY:", 0XFFFFFFFF)) + .widget(new ToggleButtonWidget(190, 110, 20, 20, ()->this.flippedY, state -> setConfig(this.url, this.rotation, this.scaleX, this.scaleY, this.flippedX, state))); + } + + @Override + public void update() { + if(this.screen != null && this.screen.getWorld().isRemote) { + if(this.texture != null) { + texture.tick(); // gif update + } + } + } + + @Override + public void renderPlugin(float partialTicks, RayTraceResult rayTraceResult) { + if (!this.url.equals("")) { + if (texture != null && texture.hasTexture()) { + texture.render(-0.5f, -0.5f, 1, 1, this.rotation, this.scaleX, this.scaleY, this.flippedX, this.flippedY); + } else + this.loadTexture(); + } + } + + @SideOnly(Side.CLIENT) + public void loadTexture() { + if (texture == null && !failed) { + if (downloader == null && DownloadThread.activeDownloads < DownloadThread.MAXIMUM_ACTIVE_DOWNLOADS) { + PictureTexture loadedTexture = DownloadThread.loadedImages.get(url); + + if (loadedTexture == null) { + synchronized (DownloadThread.LOCK) { + if (!DownloadThread.loadingImages.contains(url)) { + downloader = new DownloadThread(url); + return; + } + } + } else { + texture = loadedTexture; + } + } + if (downloader != null && downloader.hasFinished()) { + if (downloader.hasFailed()) { + failed = true; + error = downloader.getError(); + DownloadThread.LOGGER.error("Could not load image of " + (this.screen!=null?this.screen.getPos().toString():"") + " " + error); + } else { + texture = DownloadThread.loadImage(downloader); + } + downloader = null; + } + } + } +} diff --git a/src/main/java/gregtech/common/items/behaviors/monitorplugin/TextPluginBehavior.java b/src/main/java/gregtech/common/items/behaviors/monitorplugin/TextPluginBehavior.java new file mode 100644 index 00000000000..7f78b130bd0 --- /dev/null +++ b/src/main/java/gregtech/common/items/behaviors/monitorplugin/TextPluginBehavior.java @@ -0,0 +1,103 @@ +package gregtech.common.items.behaviors.monitorplugin; + +import gregtech.api.capability.GregtechDataCodes; +import gregtech.api.gui.IUIHolder; +import gregtech.api.gui.widgets.TextFieldWidget; +import gregtech.api.items.behavior.MonitorPluginBaseBehavior; +import gregtech.api.util.RenderUtil; +import gregtech.common.gui.widget.WidgetARGB; +import gregtech.common.gui.widget.monitor.WidgetPluginConfig; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.math.RayTraceResult; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import java.util.Arrays; + +public class TextPluginBehavior extends MonitorPluginBaseBehavior { + public String[] texts; + public int[] colors; + + public void setText(int line, String text, int color) { + if (line < 0 || line > texts.length || (texts[line].equals(text) && colors[line] == color)) return; + this.texts[line] = text; + this.colors[line] = color; + writePluginData(GregtechDataCodes.UPDATE_PLUGIN_CONFIG, packetBuffer -> { + packetBuffer.writeInt(texts.length); + for (int i = 0; i < texts.length; i++) { + packetBuffer.writeString(texts[i]); + packetBuffer.writeInt(colors[i]); + } + }); + markAsDirty(); + } + + @Override + public void readPluginData(int id, PacketBuffer buf) { + if(id == GregtechDataCodes.UPDATE_PLUGIN_CONFIG){ + texts = new String[buf.readInt()]; + colors = new int[texts.length]; + for (int i = 0; i < texts.length; i++) { + texts[i] = buf.readString(100); + colors[i] = buf.readInt(); + } + } + } + + @Override + public MonitorPluginBaseBehavior createPlugin() { + TextPluginBehavior plugin = new TextPluginBehavior(); + plugin.texts = new String[16]; + plugin.colors = new int[16]; + return plugin; + } + + @Override + public void writeToNBT(NBTTagCompound data) { + super.writeToNBT(data); + for (int i = 0; i < texts.length; i++) { + data.setString("t" + i, texts[i]); + } + data.setIntArray("color", colors); + } + + @Override + public void readFromNBT(NBTTagCompound data) { + super.readFromNBT(data); + for (int i = 0; i < texts.length; i++) { + texts[i] = data.hasKey("t" + i)? data.getString("t" + i) : ""; + } + if(data.hasKey("color")) { + colors = data.getIntArray("color"); + } else { + Arrays.fill(colors, 0XFFFFFFFF); + } + } + + @SideOnly(Side.CLIENT) + @Override + public void renderPlugin(float partialTicks, RayTraceResult rayTraceResult) { + for (int i = 0; i < texts.length; i++) { + RenderUtil.renderText(-0.5f, -0.4625f + i / 16f, 0.002f, 1/128f, colors[i], texts[i], false); + } + } + + @Override + public boolean hasUI() { + return true; + } + + @Override + public WidgetPluginConfig customUI(WidgetPluginConfig widgets, IUIHolder holder, EntityPlayer entityPlayer) { + widgets.setSize(260, 210); + for (int i = 0; i < texts.length; i++) { + int finalI = i; + widgets.addWidget(new TextFieldWidget(25, 25 + i * 10, 100, 10, true, ()-> this.texts[finalI], (text)-> setText(finalI, text, this.colors[finalI])).setValidator((data)->true)); + widgets.addWidget(new WidgetARGB(135, 25 + i * 10, 10, colors[i], color-> setText(finalI, this.texts[finalI], color))); + } + return widgets; + } + +} diff --git a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java index 20e7a26b017..d788a88f617 100644 --- a/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java +++ b/src/main/java/gregtech/common/metatileentities/MetaTileEntities.java @@ -13,23 +13,79 @@ import gregtech.api.util.GTLog; import gregtech.api.util.GTUtility; import gregtech.common.ConfigHolder; -import gregtech.common.metatileentities.electric.*; -import gregtech.common.metatileentities.electric.multiblockpart.*; -import gregtech.common.metatileentities.multi.*; +import gregtech.common.metatileentities.electric.MetaTileEntityAdjustableTransformer; +import gregtech.common.metatileentities.electric.MetaTileEntityBatteryBuffer; +import gregtech.common.metatileentities.electric.MetaTileEntityBlockBreaker; +import gregtech.common.metatileentities.electric.MetaTileEntityCharger; +import gregtech.common.metatileentities.electric.MetaTileEntityDiode; +import gregtech.common.metatileentities.electric.MetaTileEntityFisher; +import gregtech.common.metatileentities.electric.MetaTileEntityGasCollector; +import gregtech.common.metatileentities.electric.MetaTileEntityHull; +import gregtech.common.metatileentities.electric.MetaTileEntityItemCollector; +import gregtech.common.metatileentities.electric.MetaTileEntityMacerator; +import gregtech.common.metatileentities.electric.MetaTileEntityMagicEnergyAbsorber; +import gregtech.common.metatileentities.electric.MetaTileEntityMiner; +import gregtech.common.metatileentities.electric.MetaTileEntityPump; +import gregtech.common.metatileentities.electric.MetaTileEntityRockBreaker; +import gregtech.common.metatileentities.electric.MetaTileEntitySimpleOreWasher; +import gregtech.common.metatileentities.electric.MetaTileEntityTransformer; +import gregtech.common.metatileentities.electric.MetaTileEntityWorldAccelerator; +import gregtech.common.metatileentities.electric.multiblockpart.MetaTileEntityAdjustableEnergyHatch; +import gregtech.common.metatileentities.electric.multiblockpart.MetaTileEntityAutoMaintenanceHatch; +import gregtech.common.metatileentities.electric.multiblockpart.MetaTileEntityEnergyHatch; +import gregtech.common.metatileentities.electric.multiblockpart.MetaTileEntityFluidHatch; +import gregtech.common.metatileentities.electric.multiblockpart.MetaTileEntityItemBus; +import gregtech.common.metatileentities.electric.multiblockpart.MetaTileEntityMaintenanceHatch; +import gregtech.common.metatileentities.electric.multiblockpart.MetaTileEntityMufflerHatch; +import gregtech.common.metatileentities.electric.multiblockpart.MetaTileEntityMultiFluidHatch; +import gregtech.common.metatileentities.electric.multiblockpart.MetaTileEntityRotorHolder; +import gregtech.common.metatileentities.multi.MetaTileEntityCokeOven; +import gregtech.common.metatileentities.multi.MetaTileEntityCokeOvenHatch; +import gregtech.common.metatileentities.multi.MetaTileEntityLargeBoiler; import gregtech.common.metatileentities.multi.MetaTileEntityLargeBoiler.BoilerType; -import gregtech.common.metatileentities.multi.electric.*; +import gregtech.common.metatileentities.multi.MetaTileEntityPrimitiveBlastFurnace; +import gregtech.common.metatileentities.multi.MetaTileEntityPrimitiveWaterPump; +import gregtech.common.metatileentities.multi.MetaTileEntityPumpHatch; +import gregtech.common.metatileentities.multi.electric.MetaTileEntityAssemblyLine; +import gregtech.common.metatileentities.multi.electric.MetaTileEntityCrackingUnit; +import gregtech.common.metatileentities.multi.electric.MetaTileEntityDistillationTower; +import gregtech.common.metatileentities.multi.electric.MetaTileEntityElectricBlastFurnace; +import gregtech.common.metatileentities.multi.electric.MetaTileEntityFusionReactor; +import gregtech.common.metatileentities.multi.electric.MetaTileEntityImplosionCompressor; +import gregtech.common.metatileentities.multi.electric.MetaTileEntityLargeChemicalReactor; +import gregtech.common.metatileentities.multi.electric.MetaTileEntityLargeMiner; +import gregtech.common.metatileentities.multi.electric.MetaTileEntityMultiSmelter; +import gregtech.common.metatileentities.multi.electric.MetaTileEntityPyrolyseOven; +import gregtech.common.metatileentities.multi.electric.MetaTileEntityVacuumFreezer; +import gregtech.common.metatileentities.multi.electric.centralmonitor.MetaTileEntityCentralMonitor; +import gregtech.common.metatileentities.multi.electric.centralmonitor.MetaTileEntityMonitorScreen; import gregtech.common.metatileentities.multi.electric.generator.MetaTileEntityLargeCombustionEngine; import gregtech.common.metatileentities.multi.electric.generator.MetaTileEntityLargeTurbine; import gregtech.common.metatileentities.multi.electric.generator.MetaTileEntityLargeTurbine.TurbineType; import gregtech.common.metatileentities.multi.steam.MetaTileEntitySteamGrinder; import gregtech.common.metatileentities.multi.steam.MetaTileEntitySteamOven; -import gregtech.common.metatileentities.steam.*; +import gregtech.common.metatileentities.steam.SteamAlloySmelter; +import gregtech.common.metatileentities.steam.SteamCompressor; +import gregtech.common.metatileentities.steam.SteamExtractor; +import gregtech.common.metatileentities.steam.SteamFurnace; +import gregtech.common.metatileentities.steam.SteamHammer; +import gregtech.common.metatileentities.steam.SteamMacerator; +import gregtech.common.metatileentities.steam.SteamMiner; +import gregtech.common.metatileentities.steam.SteamRockBreaker; import gregtech.common.metatileentities.steam.boiler.SteamCoalBoiler; import gregtech.common.metatileentities.steam.boiler.SteamLavaBoiler; import gregtech.common.metatileentities.steam.boiler.SteamSolarBoiler; import gregtech.common.metatileentities.steam.multiblockpart.MetaTileEntitySteamHatch; import gregtech.common.metatileentities.steam.multiblockpart.MetaTileEntitySteamItemBus; -import gregtech.common.metatileentities.storage.*; +import gregtech.common.metatileentities.storage.MetaTileEntityBuffer; +import gregtech.common.metatileentities.storage.MetaTileEntityCrate; +import gregtech.common.metatileentities.storage.MetaTileEntityCreativeEnergy; +import gregtech.common.metatileentities.storage.MetaTileEntityDrum; +import gregtech.common.metatileentities.storage.MetaTileEntityLockedSafe; +import gregtech.common.metatileentities.storage.MetaTileEntityQuantumChest; +import gregtech.common.metatileentities.storage.MetaTileEntityQuantumTank; +import gregtech.common.metatileentities.storage.MetaTileEntityTank; +import gregtech.common.metatileentities.storage.MetaTileEntityWorkbench; import net.minecraft.util.ResourceLocation; import java.util.HashMap; @@ -45,33 +101,6 @@ public class MetaTileEntities { public static final MetaTileEntityDiode[] DIODES = new MetaTileEntityDiode[GTValues.V.length]; public static final MetaTileEntityBatteryBuffer[][] BATTERY_BUFFER = new MetaTileEntityBatteryBuffer[GTValues.V.length][]; public static final MetaTileEntityCharger[] CHARGER = new MetaTileEntityCharger[GTValues.V.length]; - - //STEAM AGE SECTION - public static SteamCoalBoiler STEAM_BOILER_COAL_BRONZE; - public static SteamCoalBoiler STEAM_BOILER_COAL_STEEL; - public static SteamSolarBoiler STEAM_BOILER_SOLAR_BRONZE; - public static SteamSolarBoiler STEAM_BOILER_SOLAR_STEEL; - public static SteamLavaBoiler STEAM_BOILER_LAVA_BRONZE; - public static SteamLavaBoiler STEAM_BOILER_LAVA_STEEL; - public static SteamExtractor STEAM_EXTRACTOR_BRONZE; - public static SteamExtractor STEAM_EXTRACTOR_STEEL; - public static SteamMacerator STEAM_MACERATOR_BRONZE; - public static SteamMacerator STEAM_MACERATOR_STEEL; - public static SteamCompressor STEAM_COMPRESSOR_BRONZE; - public static SteamCompressor STEAM_COMPRESSOR_STEEL; - public static SteamHammer STEAM_HAMMER_BRONZE; - public static SteamHammer STEAM_HAMMER_STEEL; - public static SteamFurnace STEAM_FURNACE_BRONZE; - public static SteamFurnace STEAM_FURNACE_STEEL; - public static SteamAlloySmelter STEAM_ALLOY_SMELTER_BRONZE; - public static SteamAlloySmelter STEAM_ALLOY_SMELTER_STEEL; - public static SteamRockBreaker STEAM_ROCK_BREAKER_BRONZE; - public static SteamRockBreaker STEAM_ROCK_BREAKER_STEEL; - public static SteamMiner STEAM_MINER; - - public static MetaTileEntityPumpHatch PUMP_OUTPUT_HATCH; - public static MetaTileEntityPrimitiveWaterPump PRIMITIVE_WATER_PUMP; - //SIMPLE MACHINES SECTION public static final SimpleMachineMetaTileEntity[] ELECTRIC_FURNACE = new SimpleMachineMetaTileEntity[GTValues.V.length - 1]; public static final MetaTileEntityMacerator[] MACERATOR = new MetaTileEntityMacerator[GTValues.V.length - 1]; @@ -114,14 +143,10 @@ public class MetaTileEntities { public static final SimpleMachineMetaTileEntity[] GAS_COLLECTOR = new MetaTileEntityGasCollector[GTValues.V.length - 1]; public static final MetaTileEntityRockBreaker[] ROCK_BREAKER = new MetaTileEntityRockBreaker[GTValues.V.length - 1]; public static final MetaTileEntityMiner[] MINER = new MetaTileEntityMiner[GTValues.V.length - 1]; - public static MetaTileEntitySimpleOreWasher SIMPLE_ORE_WASHER; - //GENERATORS SECTION public static final SimpleGeneratorMetaTileEntity[] COMBUSTION_GENERATOR = new SimpleGeneratorMetaTileEntity[4]; public static final SimpleGeneratorMetaTileEntity[] STEAM_TURBINE = new SimpleGeneratorMetaTileEntity[4]; public static final SimpleGeneratorMetaTileEntity[] GAS_TURBINE = new SimpleGeneratorMetaTileEntity[4]; - public static MetaTileEntityMagicEnergyAbsorber MAGIC_ENERGY_ABSORBER; - //MULTIBLOCK PARTS SECTION public static final MetaTileEntityItemBus[] ITEM_IMPORT_BUS = new MetaTileEntityItemBus[GTValues.UHV + 1]; // ULV-UHV public static final MetaTileEntityItemBus[] ITEM_EXPORT_BUS = new MetaTileEntityItemBus[GTValues.UHV + 1]; @@ -133,16 +158,53 @@ public class MetaTileEntities { public static final MetaTileEntityAdjustableEnergyHatch[] ENERGY_INPUT_HATCH_ADJUSTABLE = new MetaTileEntityAdjustableEnergyHatch[GTValues.V.length]; public static final MetaTileEntityEnergyHatch[] ENERGY_OUTPUT_HATCH = new MetaTileEntityEnergyHatch[GTValues.V.length]; public static final MetaTileEntityAdjustableEnergyHatch[] ENERGY_OUTPUT_HATCH_ADJUSTABLE = new MetaTileEntityAdjustableEnergyHatch[GTValues.V.length]; + public static final MetaTileEntityRotorHolder[] ROTOR_HOLDER = new MetaTileEntityRotorHolder[3]; //HV, LuV, MAX + public static final MetaTileEntityMufflerHatch[] MUFFLER_HATCH = new MetaTileEntityMufflerHatch[GTValues.UV]; // LV-UV + public static final MetaTileEntityFusionReactor[] FUSION_REACTOR = new MetaTileEntityFusionReactor[3]; + public static final MetaTileEntityQuantumChest[] QUANTUM_CHEST = new MetaTileEntityQuantumChest[10]; + public static final MetaTileEntityQuantumTank[] QUANTUM_TANK = new MetaTileEntityQuantumTank[10]; + public static final MetaTileEntityBuffer[] BUFFER = new MetaTileEntityBuffer[3]; + public static final MetaTileEntityPump[] PUMP = new MetaTileEntityPump[8]; + public static final MetaTileEntityBlockBreaker[] BLOCK_BREAKER = new MetaTileEntityBlockBreaker[4]; + public static final MetaTileEntityItemCollector[] ITEM_COLLECTOR = new MetaTileEntityItemCollector[4]; + public static final MetaTileEntityFisher[] FISHER = new MetaTileEntityFisher[4]; + public static final MetaTileEntityWorldAccelerator[] WORLD_ACCELERATOR = new MetaTileEntityWorldAccelerator[8]; // no ULV, no MAX + // Used for addons if they wish to disable certain tiers of machines + private static final Map MID_TIER = new HashMap<>(); + private static final Map HIGH_TIER = new HashMap<>(); + //STEAM AGE SECTION + public static SteamCoalBoiler STEAM_BOILER_COAL_BRONZE; + public static SteamCoalBoiler STEAM_BOILER_COAL_STEEL; + public static SteamSolarBoiler STEAM_BOILER_SOLAR_BRONZE; + public static SteamSolarBoiler STEAM_BOILER_SOLAR_STEEL; + public static SteamLavaBoiler STEAM_BOILER_LAVA_BRONZE; + public static SteamLavaBoiler STEAM_BOILER_LAVA_STEEL; + public static SteamExtractor STEAM_EXTRACTOR_BRONZE; + public static SteamExtractor STEAM_EXTRACTOR_STEEL; + public static SteamMacerator STEAM_MACERATOR_BRONZE; + public static SteamMacerator STEAM_MACERATOR_STEEL; + public static SteamCompressor STEAM_COMPRESSOR_BRONZE; + public static SteamCompressor STEAM_COMPRESSOR_STEEL; + public static SteamHammer STEAM_HAMMER_BRONZE; + public static SteamHammer STEAM_HAMMER_STEEL; + public static SteamFurnace STEAM_FURNACE_BRONZE; + public static SteamFurnace STEAM_FURNACE_STEEL; + public static SteamAlloySmelter STEAM_ALLOY_SMELTER_BRONZE; + public static SteamAlloySmelter STEAM_ALLOY_SMELTER_STEEL; + public static SteamRockBreaker STEAM_ROCK_BREAKER_BRONZE; + public static SteamRockBreaker STEAM_ROCK_BREAKER_STEEL; + public static SteamMiner STEAM_MINER; + public static MetaTileEntityPumpHatch PUMP_OUTPUT_HATCH; + public static MetaTileEntityPrimitiveWaterPump PRIMITIVE_WATER_PUMP; + public static MetaTileEntitySimpleOreWasher SIMPLE_ORE_WASHER; + public static MetaTileEntityMagicEnergyAbsorber MAGIC_ENERGY_ABSORBER; public static MetaTileEntityCokeOvenHatch COKE_OVEN_HATCH; public static MetaTileEntitySteamItemBus STEAM_EXPORT_BUS; public static MetaTileEntitySteamItemBus STEAM_IMPORT_BUS; public static MetaTileEntitySteamHatch STEAM_HATCH; - public static final MetaTileEntityRotorHolder[] ROTOR_HOLDER = new MetaTileEntityRotorHolder[3]; //HV, LuV, MAX public static MetaTileEntityMaintenanceHatch MAINTENANCE_HATCH; public static MetaTileEntityMaintenanceHatch CONFIGURABLE_MAINTENANCE_HATCH; public static MetaTileEntityAutoMaintenanceHatch AUTO_MAINTENANCE_HATCH; - public static final MetaTileEntityMufflerHatch[] MUFFLER_HATCH = new MetaTileEntityMufflerHatch[GTValues.UV]; // LV-UV - //MULTIBLOCKS SECTION public static MetaTileEntityPrimitiveBlastFurnace PRIMITIVE_BLAST_FURNACE; public static MetaTileEntityCokeOven COKE_OVEN; @@ -154,32 +216,22 @@ public class MetaTileEntities { public static MetaTileEntityCrackingUnit CRACKER; public static MetaTileEntityMultiSmelter MULTI_FURNACE; public static MetaTileEntityLargeCombustionEngine LARGE_COMBUSTION_ENGINE; - public static MetaTileEntityLargeTurbine LARGE_STEAM_TURBINE; public static MetaTileEntityLargeTurbine LARGE_GAS_TURBINE; public static MetaTileEntityLargeTurbine LARGE_PLASMA_TURBINE; - public static MetaTileEntityLargeBoiler LARGE_BRONZE_BOILER; public static MetaTileEntityLargeBoiler LARGE_STEEL_BOILER; public static MetaTileEntityLargeBoiler LARGE_TITANIUM_BOILER; public static MetaTileEntityLargeBoiler LARGE_TUNGSTENSTEEL_BOILER; - public static MetaTileEntityAssemblyLine ASSEMBLY_LINE; - public static final MetaTileEntityFusionReactor[] FUSION_REACTOR = new MetaTileEntityFusionReactor[3]; - public static MetaTileEntityLargeChemicalReactor LARGE_CHEMICAL_REACTOR; - public static MetaTileEntitySteamOven STEAM_OVEN; public static MetaTileEntitySteamGrinder STEAM_GRINDER; - public static MetaTileEntityLargeMiner BASIC_LARGE_MINER; public static MetaTileEntityLargeMiner LARGE_MINER; public static MetaTileEntityLargeMiner ADVANCED_LARGE_MINER; - - //STORAGE SECTION public static MetaTileEntityLockedSafe LOCKED_SAFE; - public static MetaTileEntityTank WOODEN_TANK; public static MetaTileEntityTank BRONZE_TANK; public static MetaTileEntityTank ALUMINIUM_TANK; @@ -187,7 +239,6 @@ public class MetaTileEntities { public static MetaTileEntityTank STAINLESS_STEEL_TANK; public static MetaTileEntityTank TITANIUM_TANK; public static MetaTileEntityTank TUNGSTENSTEEL_TANK; - public static MetaTileEntityDrum WOODEN_DRUM; public static MetaTileEntityDrum BRONZE_DRUM; public static MetaTileEntityDrum ALUMINIUM_DRUM; @@ -195,7 +246,6 @@ public class MetaTileEntities { public static MetaTileEntityDrum STAINLESS_STEEL_DRUM; public static MetaTileEntityDrum TITANIUM_DRUM; public static MetaTileEntityDrum TUNGSTENSTEEL_DRUM; - public static MetaTileEntityCrate WOODEN_CRATE; public static MetaTileEntityCrate BRONZE_CRATE; public static MetaTileEntityCrate ALUMINIUM_CRATE; @@ -203,22 +253,12 @@ public class MetaTileEntities { public static MetaTileEntityCrate STAINLESS_STEEL_CRATE; public static MetaTileEntityCrate TITANIUM_CRATE; public static MetaTileEntityCrate TUNGSTENSTEEL_CRATE; - - public static final MetaTileEntityQuantumChest[] QUANTUM_CHEST = new MetaTileEntityQuantumChest[10]; - public static final MetaTileEntityQuantumTank[] QUANTUM_TANK = new MetaTileEntityQuantumTank[10]; - public static final MetaTileEntityBuffer[] BUFFER = new MetaTileEntityBuffer[3]; - //MISC MACHINES SECTION public static MetaTileEntityWorkbench WORKBENCH; - public static final MetaTileEntityPump[] PUMP = new MetaTileEntityPump[8]; - public static final MetaTileEntityBlockBreaker[] BLOCK_BREAKER = new MetaTileEntityBlockBreaker[4]; - public static final MetaTileEntityItemCollector[] ITEM_COLLECTOR = new MetaTileEntityItemCollector[4]; - public static final MetaTileEntityFisher[] FISHER = new MetaTileEntityFisher[4]; - public static final MetaTileEntityWorldAccelerator[] WORLD_ACCELERATOR = new MetaTileEntityWorldAccelerator[8]; // no ULV, no MAX - public static MetaTileEntityCreativeEnergy CREATIVE_ENERGY; - public static MetaTileEntityClipboard CLIPBOARD_TILE; + public static MetaTileEntityMonitorScreen MONITOR_SCREEN; + public static MetaTileEntityCentralMonitor CENTRAL_MONITOR; public static void init() { GTLog.logger.info("Registering MetaTileEntities"); @@ -495,6 +535,8 @@ public static void init() { LARGE_MINER = registerMetaTileEntity(1026, new MetaTileEntityLargeMiner(gregtechId("large_miner.iv"), 5, Materials.Titanium, 4, 5, 16, 5)); ADVANCED_LARGE_MINER = registerMetaTileEntity(1027, new MetaTileEntityLargeMiner(gregtechId("large_miner.luv"), 6, Materials.TungstenSteel, 1, 7, 32, 6)); + CENTRAL_MONITOR = registerMetaTileEntity(1028, new MetaTileEntityCentralMonitor(gregtechId("central_monitor"))); + // MISC MTE's START: IDs 1150-2000 // Import/Export Buses/Hatches, IDs 1150-1209 @@ -730,6 +772,8 @@ public static void init() { CLIPBOARD_TILE = registerMetaTileEntity(1666, new MetaTileEntityClipboard(gregtechId("clipboard"))); + MONITOR_SCREEN = registerMetaTileEntity(1667, new MetaTileEntityMonitorScreen(gregtechId("monitor_screen"))); + /* * FOR ADDON DEVELOPERS: * @@ -797,10 +841,6 @@ private static ResourceLocation gregtechId(String name) { return new ResourceLocation(GTValues.MODID, name); } - // Used for addons if they wish to disable certain tiers of machines - private static final Map MID_TIER = new HashMap<>(); - private static final Map HIGH_TIER = new HashMap<>(); - @SuppressWarnings("unused") public static void setMidTier(String key, boolean enabled) { MID_TIER.put(key, enabled); diff --git a/src/main/java/gregtech/common/metatileentities/MetaTileEntityClipboard.java b/src/main/java/gregtech/common/metatileentities/MetaTileEntityClipboard.java index 71d9cf8db08..37f9e839f74 100644 --- a/src/main/java/gregtech/common/metatileentities/MetaTileEntityClipboard.java +++ b/src/main/java/gregtech/common/metatileentities/MetaTileEntityClipboard.java @@ -55,7 +55,7 @@ public class MetaTileEntityClipboard extends MetaTileEntity implements IFastRend public FakeModularGui guiCache; public FakeModularUIContainerClipboard guiContainerCache; private static final Cuboid6 pageBox = new Cuboid6(3 / 16.0, 0.25 / 16.0, 0.25 / 16.0, 13 / 16.0, 14.25 / 16.0, 0.3 / 16.0); - + private static boolean receivesData = false; private static final NBTBase NO_CLIPBOARD_SIG = new NBTTagInt(0); @@ -66,12 +66,16 @@ public MetaTileEntityClipboard(ResourceLocation metaTileEntityId) { @Override public void update() { super.update(); + if (guiCache == null || guiContainerCache == null) { + createFakeGui(); + scheduleRenderUpdate(); + } if (this.getWorld().isRemote) { if (guiCache != null) guiCache.updateScreen(); } else { - if (getOffsetTimer() % 20 == 0) - createFakeGui(); + if(!receivesData) + this.writeCustomData(DETECT_UPDATE_RECEIVED, buffer -> { }); // Doesn't do anything, just helps start updates quickly if (guiContainerCache != null) guiContainerCache.detectAndSendChanges(); } @@ -331,6 +335,7 @@ public void receiveInitialSyncData(PacketBuffer buf) { @Override public void receiveCustomData(int dataId, PacketBuffer buf) { super.receiveCustomData(dataId, buf); + receivesData = true; if (dataId == UPDATE_UI) { int windowID = buf.readVarInt(); int widgetID = buf.readVarInt(); diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/centralmonitor/MetaTileEntityCentralMonitor.java b/src/main/java/gregtech/common/metatileentities/multi/electric/centralmonitor/MetaTileEntityCentralMonitor.java new file mode 100644 index 00000000000..6b4bbea0709 --- /dev/null +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/centralmonitor/MetaTileEntityCentralMonitor.java @@ -0,0 +1,595 @@ +package gregtech.common.metatileentities.multi.electric.centralmonitor; + +import codechicken.lib.render.CCRenderState; +import codechicken.lib.render.pipeline.IVertexOperation; +import codechicken.lib.vec.Matrix4; +import gregtech.api.capability.GregtechCapabilities; +import gregtech.api.capability.GregtechDataCodes; +import gregtech.api.capability.IEnergyContainer; +import gregtech.api.capability.impl.EnergyContainerList; +import gregtech.api.cover.CoverBehavior; +import gregtech.api.gui.GuiTextures; +import gregtech.api.gui.ModularUI; +import gregtech.api.gui.Widget; +import gregtech.api.gui.widgets.AdvancedTextWidget; +import gregtech.api.gui.widgets.WidgetGroup; +import gregtech.api.metatileentity.IFastRenderMetaTileEntity; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.MetaTileEntityHolder; +import gregtech.api.metatileentity.multiblock.IMultiblockPart; +import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.metatileentity.multiblock.MultiblockWithDisplayBase; +import gregtech.api.multiblock.BlockPattern; +import gregtech.api.multiblock.FactoryBlockPattern; +import gregtech.api.multiblock.PatternMatchContext; +import gregtech.api.pipenet.tile.AttachmentType; +import gregtech.api.pipenet.tile.TileEntityPipeBase; +import gregtech.api.render.ICubeRenderer; +import gregtech.api.render.Textures; +import gregtech.api.util.BlockPosFace; +import gregtech.api.util.RenderUtil; +import gregtech.common.ConfigHolder; +import gregtech.common.blocks.BlockMetalCasing; +import gregtech.common.blocks.MetaBlocks; +import gregtech.common.covers.CoverDigitalInterface; +import gregtech.common.gui.widget.monitor.WidgetScreenGrid; +import gregtech.common.pipelike.cable.net.EnergyNet; +import gregtech.common.pipelike.cable.net.WorldENet; +import gregtech.common.pipelike.cable.tile.TileEntityCable; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.resources.I18n; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TextComponentString; +import net.minecraft.util.text.TextComponentTranslation; +import net.minecraft.world.World; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import org.lwjgl.opengl.GL11; + +import javax.annotation.Nullable; +import java.lang.ref.WeakReference; +import java.util.*; + +import static gregtech.api.util.RelativeDirection.*; + +public class MetaTileEntityCentralMonitor extends MultiblockWithDisplayBase implements IFastRenderMetaTileEntity { + private final static long ENERGY_COST = -ConfigHolder.centralMonitorEuCost; + public final static int MAX_HEIGHT = 9; + public final static int MAX_WIDTH = 14; + // run-time data + public int width; + private long lastUpdate; + private WeakReference currentEnergyNet; + private List activeNodes; + private Set netCovers; + private Set remoteCovers; + @SideOnly(Side.CLIENT) + public List parts; + public MetaTileEntityMonitorScreen[][] screens; + private boolean isActive; + private EnergyContainerList inputEnergy; + // persistent data + public int height = 3; + + public MetaTileEntityCentralMonitor(ResourceLocation metaTileEntityId) { + super(metaTileEntityId); + reinitializeStructurePattern(); + } + + private EnergyNet getEnergyNet() { + if (!this.getWorld().isRemote) { + TileEntity te = this.getWorld().getTileEntity(this.getPos().offset(frontFacing.getOpposite())); + if (te instanceof TileEntityPipeBase) { + TileEntityPipeBase tileEntityCable = (TileEntityCable) te; + EnergyNet currentEnergyNet = this.currentEnergyNet.get(); + if (currentEnergyNet != null && currentEnergyNet.isValid() && currentEnergyNet.containsNode(tileEntityCable.getPipePos())) { + return currentEnergyNet; //return current net if it is still valid + } + WorldENet worldENet = (WorldENet) tileEntityCable.getPipeBlock().getWorldPipeNet(tileEntityCable.getPipeWorld()); + currentEnergyNet = worldENet.getNetFromPos(tileEntityCable.getPipePos()); + if (currentEnergyNet != null) { + this.currentEnergyNet = new WeakReference<>(currentEnergyNet); + } + return currentEnergyNet; + } + } + return null; + } + + private void updateNodes() { + EnergyNet energyNet = getEnergyNet(); + if (energyNet == null) { + activeNodes.clear(); + return; + } + if (energyNet.getLastUpdate() == lastUpdate) { + return; + } + lastUpdate = energyNet.getLastUpdate(); + activeNodes.clear(); + energyNet.getAllNodes().forEach((pos, node) -> { + if (node.isActive) { + activeNodes.add(pos); + } + }); + } + + public void addRemoteCover(BlockPosFace cover) { + if (remoteCovers != null) { + if (remoteCovers.add(cover)) { + writeCustomData(GregtechDataCodes.UPDATE_COVERS, this::writeCovers); + } + } + } + + private boolean checkCovers() { + boolean dirty = false; + updateNodes(); + Set checkCovers = new HashSet<>(); + World world = this.getWorld(); + for (BlockPos pos : activeNodes) { + TileEntity tileEntityCable = world.getTileEntity(pos); + if (!(tileEntityCable instanceof TileEntityPipeBase)) { + continue; + } + for (EnumFacing facing : EnumFacing.VALUES) { + if (((TileEntityPipeBase) tileEntityCable).isConnectionOpen(AttachmentType.PIPE, facing)) { + TileEntity tileEntity = world.getTileEntity(pos.offset(facing)); + if (tileEntity instanceof MetaTileEntityHolder) { + MetaTileEntity metaTileEntity = ((MetaTileEntityHolder) tileEntity).getMetaTileEntity(); + if (metaTileEntity != null) { + CoverBehavior cover = metaTileEntity.getCoverAtSide(facing.getOpposite()); + if (cover instanceof CoverDigitalInterface && ((CoverDigitalInterface) cover).isProxy()) { + checkCovers.add(new BlockPosFace(metaTileEntity.getPos(), cover.attachedSide)); + } + } + } + } + } + } + Iterator iterator = remoteCovers.iterator(); + while (iterator.hasNext()) { + BlockPosFace blockPosFace = iterator.next(); + TileEntity tileEntity = world.getTileEntity(blockPosFace.pos); + if (tileEntity instanceof MetaTileEntityHolder) { + MetaTileEntity metaTileEntity = ((MetaTileEntityHolder) tileEntity).getMetaTileEntity(); + if (metaTileEntity != null) { + CoverBehavior cover = metaTileEntity.getCoverAtSide(blockPosFace.facing); + if (cover instanceof CoverDigitalInterface && ((CoverDigitalInterface) cover).isProxy()) { + continue; + } + } + } + iterator.remove(); + dirty = true; + } + if (checkCovers.size() != netCovers.size() || !netCovers.containsAll(checkCovers)) { + netCovers = checkCovers; + dirty = true; + } + return dirty; + } + + private void writeCovers(PacketBuffer buf) { + if(netCovers == null) { + buf.writeInt(0); + } else { + buf.writeInt(netCovers.size()); + for (BlockPosFace cover : netCovers){ + buf.writeBlockPos(cover.pos); + buf.writeByte(cover.facing.getIndex()); + } + } + if(remoteCovers == null) { + buf.writeInt(0); + } else { + buf.writeInt(remoteCovers.size()); + for (BlockPosFace cover : remoteCovers){ + buf.writeBlockPos(cover.pos); + buf.writeByte(cover.facing.getIndex()); + } + } + + } + + private void readCovers(PacketBuffer buf) { + netCovers = new HashSet<>(); + remoteCovers = new HashSet<>(); + int size = buf.readInt(); + for (int i = 0; i < size; i++) { + netCovers.add(new BlockPosFace(buf.readBlockPos(), EnumFacing.byIndex(buf.readByte()))); + } + size = buf.readInt(); + for (int i = 0; i < size; i++) { + remoteCovers.add(new BlockPosFace(buf.readBlockPos(), EnumFacing.byIndex(buf.readByte()))); + } + } + + private void writeParts(PacketBuffer buf) { + buf.writeInt(this.getMultiblockParts().size() - 1); + this.getMultiblockParts().forEach(part->{ + if (part instanceof MetaTileEntityMonitorScreen) { + buf.writeBlockPos(((MetaTileEntityMonitorScreen) part).getPos()); + } + }); + } + + private void readParts(PacketBuffer buf) { + parts = new ArrayList<>(); + clearScreens(); + int size = buf.readInt(); + for (int i = 0; i < size; i++) { + parts.add(buf.readBlockPos()); + } + } + + public void setHeight(int height) { + if(this.height == height || height < 2 || height > MAX_HEIGHT) return; + this.height = height; + reinitializeStructurePattern(); + checkStructurePattern(); + writeCustomData(GregtechDataCodes.UPDATE_HEIGHT, buf-> buf.writeInt(height)); + } + + private void setActive(boolean isActive) { + if(isActive == this.isActive) return; + this.isActive = isActive; + writeCustomData(GregtechDataCodes.UPDATE_ACTIVE, buf -> buf.writeBoolean(this.isActive)); + } + + public boolean isActive() { + return isStructureFormed() && isActive; + } + + private void clearScreens() { + if (screens != null) { + for (MetaTileEntityMonitorScreen[] screen : screens) { + for (MetaTileEntityMonitorScreen s : screen) { + if(s != null) s.removeFromMultiBlock(this); + } + } + } + screens = new MetaTileEntityMonitorScreen[width][height]; + } + + @Override + public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline) { + super.renderMetaTileEntity(renderState, translation, pipeline); + Textures.SCREEN.renderSided(getFrontFacing(), renderState, translation, pipeline); + Textures.COVER_INTERFACE_PROXY.renderSided(getFrontFacing().getOpposite(), renderState, translation, pipeline); + } + + @Override + protected void addDisplayText(List textList) { + super.addDisplayText(textList); + textList.add(new TextComponentTranslation("gregtech.multiblock.central_monitor.height", this.height)); + if (!isStructureFormed()) { + ITextComponent buttonText = new TextComponentTranslation("gregtech.multiblock.central_monitor.height_modify"); + buttonText.appendText(" "); + buttonText.appendSibling(AdvancedTextWidget.withButton(new TextComponentString("[-]"), "sub")); + buttonText.appendText(" "); + buttonText.appendSibling(AdvancedTextWidget.withButton(new TextComponentString("[+]"), "add")); + textList.add(buttonText); + } else { + textList.add(new TextComponentTranslation("gregtech.multiblock.central_monitor.width", this.width)); + textList.add(new TextComponentTranslation("gregtech.multiblock.central_monitor.low_power")); + } + } + + @Override + protected void handleDisplayClick(String componentData, Widget.ClickData clickData) { + super.handleDisplayClick(componentData, clickData); + int modifier = componentData.equals("add") ? 1 : -1; + setHeight(this.height + modifier); + } + + @Override + public void writeInitialSyncData(PacketBuffer buf) { + super.writeInitialSyncData(buf); + buf.writeInt(width); + buf.writeInt(height); + buf.writeBoolean(isActive); + writeCovers(buf); + writeParts(buf); + } + + @Override + public void receiveInitialSyncData(PacketBuffer buf) { + super.receiveInitialSyncData(buf); + this.width = buf.readInt(); + this.height = buf.readInt(); + this.isActive = buf.readBoolean(); + readCovers(buf); + readParts(buf); + } + + @Override + public void receiveCustomData(int id, PacketBuffer buf) { + super.receiveCustomData(id, buf); + if (id == GregtechDataCodes.UPDATE_ALL) { + this.width = buf.readInt(); + this.height = buf.readInt(); + readCovers(buf); + readParts(buf); + } else if (id == GregtechDataCodes.UPDATE_COVERS) { + readCovers(buf); + } else if (id == GregtechDataCodes.UPDATE_HEIGHT) { + this.height = buf.readInt(); + this.reinitializeStructurePattern(); + } else if (id == GregtechDataCodes.UPDATE_ACTIVE) { + this.isActive = buf.readBoolean(); + } else if (id == GregtechDataCodes.STRUCTURE_FORMED) { + if (!this.isStructureFormed()) { + clearScreens(); + } + } + } + + @Override + public NBTTagCompound writeToNBT(NBTTagCompound data) { + data.setInteger("screenH", this.height); + return super.writeToNBT(data); + } + + @Override + public void readFromNBT(NBTTagCompound data) { + super.readFromNBT(data); + this.height = data.hasKey("screenH") ? data.getInteger("screenH") : this.height; + reinitializeStructurePattern(); + } + + @Override + public MetaTileEntity createMetaTileEntity(MetaTileEntityHolder metaTileEntityHolder) { + return new MetaTileEntityCentralMonitor(metaTileEntityId); + } + + @Override + public void update() { + super.update(); + } + + @Override + protected void updateFormedValid() { + if (this.getOffsetTimer() % 20 ==0) { + setActive(inputEnergy.changeEnergy(ENERGY_COST * this.getMultiblockParts().size()) == ENERGY_COST * this.getMultiblockParts().size()); + if (checkCovers()) { + this.getMultiblockParts().forEach(part -> { + Set covers = getAllCovers(); + if (part instanceof MetaTileEntityMonitorScreen) { + ((MetaTileEntityMonitorScreen) part).updateCoverValid(covers); + } + }); + writeCustomData(GregtechDataCodes.UPDATE_COVERS, this::writeCovers); + } + } + } + + public Set getAllCovers() { + Set allCovers = new HashSet<>(); + if (netCovers != null) { + allCovers.addAll(netCovers); + } + if (remoteCovers != null) { + allCovers.addAll(remoteCovers); + } + return allCovers; + } + + @Override + protected BlockPattern createStructurePattern() { + StringBuilder start = new StringBuilder("AS"); + StringBuilder slice = new StringBuilder("BB"); + StringBuilder end = new StringBuilder("AA"); + for (int i = 0; i < height - 2; i++) { + start.append('A'); + slice.append('B'); + end.append('A'); + } + return FactoryBlockPattern.start(UP, BACK, RIGHT) + .aisle(start.toString()) + .aisle(slice.toString()).setRepeatable(3, MAX_WIDTH) + .aisle(end.toString()) + .where('S', selfPredicate()) + .where('A', statePredicate(MetaBlocks.METAL_CASING.getState(BlockMetalCasing.MetalCasingType.STEEL_SOLID)).or(abilityPartPredicate(MultiblockAbility.INPUT_ENERGY))) + .where('B', tilePredicate((state, tile) -> tile instanceof MetaTileEntityMonitorScreen)) + .build(); + } + + @Override + protected void formStructure(PatternMatchContext context) { + super.formStructure(context); + lastUpdate = 0; + currentEnergyNet = new WeakReference<>(null); + activeNodes = new ArrayList<>(); + netCovers = new HashSet<>(); + remoteCovers = new HashSet<>(); + inputEnergy = new EnergyContainerList(this.getAbilities(MultiblockAbility.INPUT_ENERGY)); + width = 0; + checkCovers(); + for (IMultiblockPart part : this.getMultiblockParts()) { + if (part instanceof MetaTileEntityMonitorScreen) { + width++; + } + } + width = width / height; + screens = new MetaTileEntityMonitorScreen[width][height]; + for (IMultiblockPart part : this.getMultiblockParts()) { + if (part instanceof MetaTileEntityMonitorScreen) { + MetaTileEntityMonitorScreen screen = (MetaTileEntityMonitorScreen) part; + screens[screen.getX()][screen.getY()] = screen; + } + } + writeCustomData(GregtechDataCodes.UPDATE_ALL, packetBuffer -> { + packetBuffer.writeInt(width); + packetBuffer.writeInt(height); + writeCovers(packetBuffer); + writeParts(packetBuffer); + }); + } + + @Override + public T getCapability(Capability capability, EnumFacing side) { + if(side == this.frontFacing.getOpposite() && capability == GregtechCapabilities.CAPABILITY_ENERGY_CONTAINER) { + return GregtechCapabilities.CAPABILITY_ENERGY_CONTAINER.cast(IEnergyContainer.DEFAULT); + } + return null; + } + + @Override + public ICubeRenderer getBaseTexture(IMultiblockPart iMultiblockPart) { + return Textures.SOLID_STEEL_CASING; + } + + @Override + public boolean shouldRenderInPass(int pass) { + if (this.isStructureFormed()) { + return pass == 0; + } + return false; + } + + @Override + @SideOnly(Side.CLIENT) + public boolean isGlobalRenderer() { + return true; + } + + @Override + @SideOnly(Side.CLIENT) + public void renderMetaTileEntity(double x, double y, double z, float partialTicks) { + if (!this.isStructureFormed()) return; + RenderUtil.useStencil(()->{ + GlStateManager.pushMatrix(); + RenderUtil.moveToFace(x, y, z, this.frontFacing); + RenderUtil.rotateToFace(this.frontFacing, EnumFacing.NORTH); + RenderUtil.renderRect(0.5f, -0.5f - (height - 2), width, height, 0.001f, 0xFF000000); + GlStateManager.popMatrix(); + }, ()->{ + if (isActive) { + GlStateManager.pushMatrix(); + /* hack the lightmap */ + GL11.glPushAttrib(GL11.GL_LIGHTING_BIT); + net.minecraft.client.renderer.RenderHelper.disableStandardItemLighting(); + float lastBrightnessX = OpenGlHelper.lastBrightnessX; + float lastBrightnessY = OpenGlHelper.lastBrightnessY; + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240.0F, 240.0F); + EntityPlayer player = Minecraft.getMinecraft().player; + RayTraceResult rayTraceResult = player == null ? null : player.rayTrace(Minecraft.getMinecraft().playerController.getBlockReachDistance(), partialTicks); + int size = 0; + for (int w = 0; w < width; w++) { + for (int h = 0; h < height; h++) { + MetaTileEntityMonitorScreen screen = screens[w][h]; + if (screen != null) { + size++; + if (screen.isActive()) { + BlockPos pos = screen.getPos(); + BlockPos pos2 = this.getPos(); + GlStateManager.pushMatrix(); + RenderUtil.moveToFace(x + pos.getX() - pos2.getX(), y + pos.getY() - pos2.getY(), z + pos.getZ() - pos2.getZ(), this.frontFacing); + RenderUtil.rotateToFace(this.frontFacing, EnumFacing.NORTH); + screen.renderScreen(partialTicks, rayTraceResult); + GlStateManager.popMatrix(); + } + } + } + } + + if (size != parts.size()) { + clearScreens(); + for (BlockPos pos : parts) { + TileEntity tileEntity = getWorld().getTileEntity(pos); + if(tileEntity instanceof MetaTileEntityHolder && ((MetaTileEntityHolder) tileEntity).getMetaTileEntity() instanceof MetaTileEntityMonitorScreen) { + MetaTileEntityMonitorScreen screen = (MetaTileEntityMonitorScreen) ((MetaTileEntityHolder) tileEntity).getMetaTileEntity(); + screen.addToMultiBlock(this); + int sx = screen.getX(), sy = screen.getY(); + if (sx < 0 || sx >= width || sy < 0 || sy >= height) { + parts.clear(); + clearScreens(); + break; + } + screens[sx][sy] = screen; + } + } + } + + /* restore the lightmap */ + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, lastBrightnessX, lastBrightnessY); + net.minecraft.client.renderer.RenderHelper.enableStandardItemLighting(); + GL11.glPopAttrib(); + GlStateManager.popMatrix(); + } + }, true); + } + + @Override + public AxisAlignedBB getRenderBoundingBox() { + BlockPos sp = this.getPos().offset(EnumFacing.DOWN); + BlockPos ep = sp.offset(this.frontFacing.rotateY(), -width - 2).offset(EnumFacing.UP, height); + return new AxisAlignedBB(sp, ep); + } + + @Override + protected ModularUI createUI(EntityPlayer entityPlayer) { + if (!isActive()) { + return super.createUI(entityPlayer); + } else { + WidgetScreenGrid[][] screenGrids = new WidgetScreenGrid[width][height]; + WidgetGroup group = new WidgetGroup(); + for (int i = 0; i < width; i++) { + for (int j = 0; j < height; j++) { + screenGrids[i][j] = new WidgetScreenGrid(4 * width, 4 * height, i, j); + group.addWidget(screenGrids[i][j]); + } + } + if (!this.getWorld().isRemote) { + this.getMultiblockParts().forEach(part->{ + if (part instanceof MetaTileEntityMonitorScreen) { + int x = ((MetaTileEntityMonitorScreen) part).getX(); + int y = ((MetaTileEntityMonitorScreen) part).getY(); + screenGrids[x][y].setScreen((MetaTileEntityMonitorScreen) part); + } + }); + } else { + parts.forEach(partPos->{ + TileEntity tileEntity = this.getWorld().getTileEntity(partPos); + if (tileEntity instanceof MetaTileEntityHolder && ((MetaTileEntityHolder) tileEntity).getMetaTileEntity() instanceof MetaTileEntityMonitorScreen) { + MetaTileEntityMonitorScreen part = (MetaTileEntityMonitorScreen) ((MetaTileEntityHolder) tileEntity).getMetaTileEntity(); + int x = part.getX(); + int y = part.getY(); + screenGrids[x][y].setScreen(part); + } + }); + } + return ModularUI.builder(GuiTextures.BOXED_BACKGROUND, 28 * width, 28 * height) + .widget(group) + .build(this.getHolder(), entityPlayer); + } + } + + @Override + public void addInformation(ItemStack stack, @Nullable World player, List tooltip, boolean advanced) { + super.addInformation(stack, player, tooltip, advanced); + tooltip.add(I18n.format("gregtech.multiblock.central_monitor.tooltip.1")); + tooltip.add(I18n.format("gregtech.multiblock.central_monitor.tooltip.2", MAX_WIDTH, MAX_HEIGHT)); + tooltip.add(I18n.format("gregtech.multiblock.central_monitor.tooltip.3")); + tooltip.add(I18n.format("gregtech.multiblock.central_monitor.tooltip.4", -ENERGY_COST)); + } + + @Override + public boolean hasMaintenanceMechanics() { + return false; + } +} diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/centralmonitor/MetaTileEntityMonitorScreen.java b/src/main/java/gregtech/common/metatileentities/multi/electric/centralmonitor/MetaTileEntityMonitorScreen.java new file mode 100644 index 00000000000..3da79f25057 --- /dev/null +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/centralmonitor/MetaTileEntityMonitorScreen.java @@ -0,0 +1,757 @@ +package gregtech.common.metatileentities.multi.electric.centralmonitor; + +import codechicken.lib.raytracer.CuboidRayTraceResult; +import gregtech.api.capability.GregtechCapabilities; +import gregtech.api.capability.GregtechDataCodes; +import gregtech.api.cover.CoverBehavior; +import gregtech.api.cover.ICoverable; +import gregtech.api.gui.GuiTextures; +import gregtech.api.gui.ModularUI; +import gregtech.api.gui.widgets.*; +import gregtech.api.items.behavior.MonitorPluginBaseBehavior; +import gregtech.api.items.behavior.ProxyHolderPluginBehavior; +import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.api.metatileentity.MetaTileEntityHolder; +import gregtech.api.metatileentity.MetaTileEntityUIFactory; +import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; +import gregtech.api.pipenet.tile.TileEntityPipeBase; +import gregtech.api.render.Textures; +import gregtech.api.util.BlockPosFace; +import gregtech.api.util.RenderUtil; +import gregtech.common.covers.CoverDigitalInterface; +import gregtech.common.gui.widget.WidgetARGB; +import gregtech.common.gui.widget.monitor.WidgetCoverList; +import gregtech.common.gui.widget.monitor.WidgetMonitorScreen; +import gregtech.common.gui.widget.monitor.WidgetPluginConfig; +import gregtech.common.metatileentities.MetaTileEntities; +import gregtech.common.metatileentities.electric.multiblockpart.MetaTileEntityMultiblockPart; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.resources.I18n; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTUtil; +import net.minecraft.network.PacketBuffer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.*; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.fluids.capability.CapabilityFluidHandler; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import net.minecraftforge.items.CapabilityItemHandler; +import net.minecraftforge.items.ItemStackHandler; +import org.apache.commons.lang3.tuple.Pair; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.io.IOException; +import java.util.*; + +public class MetaTileEntityMonitorScreen extends MetaTileEntityMultiblockPart { + + // run-time data + public CoverDigitalInterface coverTMP; + private long lastClickTime; + private UUID lastClickUUID; + public MonitorPluginBaseBehavior plugin; + // persistent data + public BlockPosFace coverPos; + public CoverDigitalInterface.MODE mode = CoverDigitalInterface.MODE.FLUID; + public int slot = 0; + public float scale = 1; + public int frameColor = 0XFF00FF00; + private ItemStackHandler inventory; + + public MetaTileEntityMonitorScreen(ResourceLocation metaTileEntityId) { + super(metaTileEntityId, 1); + } + + public void setMode(BlockPosFace cover, CoverDigitalInterface.MODE mode) { + CoverDigitalInterface last_cover = this.getCoverFromPosSide(coverPos); + CoverDigitalInterface now_cover = this.getCoverFromPosSide(cover); + if (this.mode == mode) { + if (Objects.equals(cover, coverPos) && last_cover == null && cover == null || last_cover != null && last_cover == now_cover) { + return; + } + } + if (last_cover != null && this.mode != CoverDigitalInterface.MODE.PROXY) { + last_cover.unSubProxyMode(this.mode); + } + if (cover != null && mode != CoverDigitalInterface.MODE.PROXY) { + now_cover.subProxyMode(mode); + } + this.coverPos = cover; + this.mode = mode; + updateProxyPlugin(); + writeCustomData(GregtechDataCodes.UPDATE_ALL, this::writeSync); + this.markDirty(); + } + + public void setMode(BlockPosFace cover) { + setMode(cover, this.mode); + } + + public void setMode(CoverDigitalInterface.MODE mode) { + this.setMode(this.coverPos, mode); + } + + public void setConfig(int slot, float scale, int color) { + if ((this.scale == scale || scale < 1 || scale > 8) && (this.slot == slot || slot < 0) && this.frameColor == color) + return; + this.slot = slot; + this.scale = scale; + this.frameColor = color; + writeCustomData(GregtechDataCodes.UPDATE_ALL, this::writeSync); + markDirty(); + } + + public CoverDigitalInterface getCoverFromPosSide(BlockPosFace posFacing) { + if (posFacing == null) return null; + ICoverable mte = null; + MetaTileEntityHolder holder = getHolderFromPos(posFacing.pos); + if (holder == null) { + TileEntity te = this.getWorld() == null ? null : this.getWorld().getTileEntity(posFacing.pos); + if (te instanceof TileEntityPipeBase) { + mte = ((TileEntityPipeBase) te).getCoverableImplementation(); + } + } else { + mte = holder.getMetaTileEntity(); + } + if (mte != null) { + CoverBehavior cover = mte.getCoverAtSide(posFacing.facing); + if (cover instanceof CoverDigitalInterface) { + return (CoverDigitalInterface) cover; + } + } + return null; + } + + public MetaTileEntityHolder getHolderFromPos(BlockPos pos) { + TileEntity te = this.getWorld() == null || pos == null ? null : this.getWorld().getTileEntity(pos); + if (te instanceof MetaTileEntityHolder && ((MetaTileEntityHolder) te).isValid()) { + return (MetaTileEntityHolder) te; + } + return null; + } + + public void updateCoverValid(Set covers) { + if (this.coverPos != null) { + if (!covers.contains(this.coverPos)) { + setMode(null, CoverDigitalInterface.MODE.PROXY); + } + } + } + + private void writeSync(PacketBuffer buf) { + buf.writeBoolean(this.coverPos != null); + if (this.coverPos != null) { + buf.writeBlockPos(coverPos.pos); + buf.writeByte(coverPos.facing.getIndex()); + } + buf.writeByte(this.mode.ordinal()); + buf.writeVarInt(this.slot); + buf.writeFloat(this.scale); + buf.writeVarInt(this.frameColor); + } + + private void readSync(PacketBuffer buf) { + if (buf.readBoolean()) { + BlockPos pos = buf.readBlockPos(); + EnumFacing side = EnumFacing.byIndex(buf.readByte()); + BlockPosFace pair = new BlockPosFace(pos, side); + if (!pair.equals(this.coverPos)) { + this.coverTMP = null; + this.coverPos = pair; + } + } else { + this.coverPos = null; + this.coverTMP = null; + } + this.mode = CoverDigitalInterface.MODE.VALUES[buf.readByte()]; + this.slot = buf.readVarInt(); + this.scale = buf.readFloat(); + this.frameColor = buf.readVarInt(); + updateProxyPlugin(); + } + + private void updateProxyPlugin() { + if (this.plugin instanceof ProxyHolderPluginBehavior) { + if (this.mode == CoverDigitalInterface.MODE.PROXY && coverPos != null) { + ((ProxyHolderPluginBehavior) this.plugin).onHolderPosUpdated(coverPos.pos); + } else { + ((ProxyHolderPluginBehavior) this.plugin).onHolderPosUpdated(null); + } + } + } + + public int getX() { + if (this.getController() != null) { + if (this.getController().getPos().getX() - this.getPos().getX() != 0) { + return Math.abs(this.getController().getPos().getX() - this.getPos().getX()) - 1; + } else { + return Math.abs(this.getController().getPos().getZ() - this.getPos().getZ()) - 1; + } + } + return -1; + } + + public int getY() { + if (this.getController() != null) { + return ((MetaTileEntityCentralMonitor) this.getController()).height - (this.getPos().getY() + 1 - this.getController().getPos().getY()) - 1; + } + return -1; + } + + + public boolean isActive() { + if (this.coverPos != null && this.mode != CoverDigitalInterface.MODE.PROXY) { + CoverDigitalInterface cover = coverTMP != null ? coverTMP : this.getCoverFromPosSide(this.coverPos); + if (cover != null) { + if (cover.isProxy()) { + coverTMP = cover; + return true; + } + } + this.coverPos = null; + } + return plugin != null; + } + + public void pluginDirty() { + if (plugin != null) { + plugin.writeToNBT(this.itemInventory.getStackInSlot(0).getOrCreateSubCompound("monitor_plugin")); + } + } + + private void loadPlugin(MonitorPluginBaseBehavior plugin) { + if (this.plugin == null) { + this.plugin = plugin.createPlugin(); + this.plugin.readFromNBT(this.itemInventory.getStackInSlot(0).getOrCreateSubCompound("monitor_plugin")); + this.plugin.onMonitorValid(this, true); + } + updateProxyPlugin(); + } + + private void unloadPlugin() { + if (plugin != null) { + this.plugin.onMonitorValid(null, false); + } + this.plugin = null; + } + + @Override + public void update() { + super.update(); + if (plugin != null && this.getController() != null && this.isActive()) { + plugin.update(); + } + } + + @SideOnly(Side.CLIENT) + public void renderScreen(float partialTicks, RayTraceResult rayTraceResult) { + EnumFacing side = getController().getFrontFacing(); + GlStateManager.translate((scale - 1) * 0.5, (scale - 1) * 0.5, 0); + GlStateManager.scale(this.scale, this.scale, 1); + + if (plugin != null) { + plugin.renderPlugin(partialTicks, rayTraceResult); + } + + if (coverTMP != null) { + boolean flag = true; + if (checkLookingAt(rayTraceResult) != null && plugin == null && this.mode != CoverDigitalInterface.MODE.PROXY) { + if (coverTMP.renderSneakingLookAt(rayTraceResult.getBlockPos(), side, slot, partialTicks)) { + flag = false; + } + } + if (this.mode == CoverDigitalInterface.MODE.PROXY) return; + if (flag) { + coverTMP.renderMode(this.mode, this.slot, partialTicks); + + TileEntity te = coverTMP.getCoveredTE(); + if (te != null) { + ItemStack itemStack; + if (te instanceof MetaTileEntityHolder) { + itemStack = ((MetaTileEntityHolder) te).getMetaTileEntity().getStackForm(); + } else { + BlockPos pos = te.getPos(); + itemStack = te.getBlockType().getPickBlock(te.getWorld().getBlockState(pos), new RayTraceResult(new Vec3d(0.5, 0.5, 0.5), coverTMP.getCoveredFacing(), pos), te.getWorld(), pos, Minecraft.getMinecraft().player); + } + String name = itemStack.getDisplayName(); + // render machine + RenderUtil.renderItemOverLay(-2.6f, -2.65f, 0.003f, 1 / 100f, itemStack); + // render name + RenderUtil.renderText(0, -3.5f / 16, 0, 1.0f / 200, 0XFFFFFFFF, name, true); + } + + } + // render frame + RenderUtil.renderRect(-7f / 16, -7f / 16, 14f / 16, 0.01f, 0.003f, frameColor); + RenderUtil.renderRect(-7f / 16, -4f / 16 - 0.01f, 14f / 16, 0.01f, 0.003f, frameColor); + RenderUtil.renderRect(-7f / 16, -7f / 16 + 0.01f, 0.01f, 3f / 16 - 0.02f, 0.003f, frameColor); + RenderUtil.renderRect(7f / 16 - 0.01f, -7f / 16 + 0.01f, 0.01f, 3f / 16 - 0.02f, 0.003f, frameColor); + + RenderUtil.renderRect(-7f / 16, -3f / 16, 14f / 16, 0.01f, 0.003f, frameColor); + RenderUtil.renderRect(-7f / 16, 7f / 16 - 0.01f, 14f / 16, 0.01f, 0.003f, frameColor); + RenderUtil.renderRect(-7f / 16, -3f / 16 + 0.01f, 0.01f, 10f / 16 - 0.02f, 0.003f, frameColor); + RenderUtil.renderRect(7f / 16 - 0.01f, -3f / 16 + 0.01f, 0.01f, 10f / 16 - 0.02f, 0.003f, frameColor); + } + } + + @Override + public void writeInitialSyncData(PacketBuffer buf) { + super.writeInitialSyncData(buf); + writeSync(buf); + buf.writeItemStack(this.inventory.getStackInSlot(0)); + if (plugin != null) { + plugin.writeInitialSyncData(buf); + } + } + + @Override + public void receiveInitialSyncData(PacketBuffer buf) { + super.receiveInitialSyncData(buf); + readSync(buf); + try { + ItemStack itemStack = buf.readItemStack(); + MonitorPluginBaseBehavior behavior = MonitorPluginBaseBehavior.getBehavior(itemStack); + if (behavior == null) { + unloadPlugin(); + } else { + this.inventory.setStackInSlot(0, itemStack); + loadPlugin(behavior); + plugin.receiveInitialSyncData(buf); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void receiveCustomData(int dataId, PacketBuffer buf) { + super.receiveCustomData(dataId, buf); + if (dataId == GregtechDataCodes.UPDATE_ALL) { + readSync(buf); + } else if (dataId == GregtechDataCodes.UPDATE_PLUGIN_DATA) { //plugin + if (plugin != null) { + plugin.readPluginData(buf.readVarInt(), buf); + } + } else if (dataId == GregtechDataCodes.UPDATE_PLUGIN_ITEM) { + try { + ItemStack itemStack = buf.readItemStack(); + MonitorPluginBaseBehavior behavior = MonitorPluginBaseBehavior.getBehavior(itemStack); + if (behavior == null) { + unloadPlugin(); + } else { + this.inventory.setStackInSlot(0, itemStack); + loadPlugin(behavior); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + @Override + public NBTTagCompound writeToNBT(NBTTagCompound data) { + if (this.coverPos != null) { + data.setTag("coverPos", NBTUtil.createPosTag(this.coverPos.pos)); + data.setByte("coverSide", (byte) this.coverPos.facing.getIndex()); + } + data.setByte("mode", (byte) this.mode.ordinal()); + data.setFloat("scale", this.scale); + data.setInteger("color", this.frameColor); + data.setInteger("slot", this.slot); + data.setTag("Inventory", this.inventory.serializeNBT()); + return super.writeToNBT(data); + } + + @Override + public void readFromNBT(NBTTagCompound data) { + super.readFromNBT(data); + this.frameColor = data.hasKey("color") ? data.getInteger("color") : 0XFF00Ff00; + this.scale = data.hasKey("scale") ? data.getFloat("scale") : 1; + this.slot = data.hasKey("slot") ? data.getInteger("slot") : 0; + this.mode = CoverDigitalInterface.MODE.VALUES[data.hasKey("mode") ? data.getByte("mode") : 0]; + this.inventory.deserializeNBT(data.getCompoundTag("Inventory")); + if (data.hasKey("coverPos") && data.hasKey("coverSide")) { + BlockPos pos = NBTUtil.getPosFromTag(data.getCompoundTag("coverPos")); + EnumFacing side = EnumFacing.byIndex(data.getByte("coverSide")); + this.coverPos = new BlockPosFace(pos, side); + } else { + this.coverPos = null; + } + MonitorPluginBaseBehavior behavior = MonitorPluginBaseBehavior.getBehavior(this.inventory.getStackInSlot(0)); + if (behavior == null) { + unloadPlugin(); + } else { + loadPlugin(behavior); + } + } + + @Override + protected void initializeInventory() { + super.initializeInventory(); + this.inventory = new ItemStackHandler() { + @Override + public int getSlotLimit(int slot) { + return 1; + } + + @Override + public boolean isItemValid(int slot, @Nonnull ItemStack stack) { + MonitorPluginBaseBehavior behavior = MonitorPluginBaseBehavior.getBehavior(stack); + return behavior != null; + } + + @Nonnull + @Override + public ItemStack extractItem(int slot, int amount, boolean simulate) { + if (!getWorld().isRemote && !getStackInSlot(slot).isEmpty() && !simulate) { + unloadPlugin(); + writeCustomData(GregtechDataCodes.UPDATE_PLUGIN_ITEM, packetBuffer -> { + packetBuffer.writeItemStack(ItemStack.EMPTY); + }); + } + return super.extractItem(slot, amount, simulate); + } + }; + this.itemInventory = this.inventory; + } + + @Override + public boolean shouldRenderOverlay() { + MultiblockControllerBase controller = this.getController(); + return controller instanceof MetaTileEntityCentralMonitor && ((MetaTileEntityCentralMonitor) controller).isActive(); + } + + @Override + public boolean canPlaceCoverOnSide(EnumFacing side) { + return this.getController() != null && this.getController().getFrontFacing() != side; + } + + @Override + public void onRemoval() { + super.onRemoval(); + if (!this.getWorld().isRemote) { + this.setMode(null, this.mode); + } + } + + @Override + public T getCapability(Capability capability, EnumFacing side) { + if (capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY || capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { + CoverBehavior coverBehavior = getCoverFromPosSide(this.coverPos); + if (coverBehavior != null && coverBehavior.coverHolder != null) { + return coverBehavior.coverHolder.getCapability(capability, coverBehavior.attachedSide); + } + } + return null; + } + + @Override + public MetaTileEntity createMetaTileEntity(MetaTileEntityHolder metaTileEntityHolder) { + return new MetaTileEntityMonitorScreen(this.metaTileEntityId); + } + + @Override + protected ModularUI createUI(EntityPlayer entityPlayer) { + MultiblockControllerBase controller = this.getController(); + if (controller instanceof MetaTileEntityCentralMonitor && ((MetaTileEntityCentralMonitor) controller).isActive()) { + int width = 330; + int height = 260; + ToggleButtonWidget[] buttons = new ToggleButtonWidget[5]; + buttons[0] = new ToggleButtonWidget(width - 135, 25, 20, 20, Textures.BUTTON_FLUID, () -> this.mode == CoverDigitalInterface.MODE.FLUID, (isPressed) -> { + if (isPressed) setMode(CoverDigitalInterface.MODE.FLUID); + }).setTooltipText("metaitem.cover.digital.mode.fluid"); + buttons[1] = new ToggleButtonWidget(width - 115, 25, 20, 20, Textures.BUTTON_ITEM, () -> this.mode == CoverDigitalInterface.MODE.ITEM, (isPressed) -> { + if (isPressed) setMode(CoverDigitalInterface.MODE.ITEM); + }).setTooltipText("metaitem.cover.digital.mode.item"); + buttons[2] = new ToggleButtonWidget(width - 95, 25, 20, 20, Textures.BUTTON_ENERGY, () -> this.mode == CoverDigitalInterface.MODE.ENERGY, (isPressed) -> { + if (isPressed) setMode(CoverDigitalInterface.MODE.ENERGY); + }).setTooltipText("metaitem.cover.digital.mode.energy"); + buttons[3] = new ToggleButtonWidget(width - 75, 25, 20, 20, Textures.BUTTON_MACHINE, () -> this.mode == CoverDigitalInterface.MODE.MACHINE, (isPressed) -> { + if (isPressed) setMode(CoverDigitalInterface.MODE.MACHINE); + }).setTooltipText("metaitem.cover.digital.mode.machine"); + buttons[4] = new ToggleButtonWidget(width - 35, 25, 20, 20, Textures.BUTTON_INTERFACE, () -> this.mode == CoverDigitalInterface.MODE.PROXY, (isPressed) -> { + if (isPressed) setMode(CoverDigitalInterface.MODE.PROXY); + }).setTooltipText("metaitem.cover.digital.mode.proxy"); + List covers = new ArrayList<>(); + ((MetaTileEntityCentralMonitor) controller).getAllCovers().forEach(coverPos -> covers.add(getCoverFromPosSide(coverPos))); + WidgetPluginConfig pluginWidget = new WidgetPluginConfig(); + WidgetPluginConfig mainGroup = new WidgetPluginConfig().setSize(width, height); + mainGroup.widget(new LabelWidget(15, 55, "monitor.gui.title.scale", 0xFFFFFFFF)) + .widget(new ClickButtonWidget(50, 50, 20, 20, "-1", (data) -> setConfig(this.slot, ((float) Math.round((scale - (data.isShiftClick ? 1.0f : 0.1f)) * 10) / 10), this.frameColor))) + .widget(new ClickButtonWidget(130, 50, 20, 20, "+1", (data) -> setConfig(this.slot, ((float) Math.round((scale + (data.isShiftClick ? 1.0f : 0.1f)) * 10) / 10), this.frameColor))) + .widget(new ImageWidget(70, 50, 60, 20, GuiTextures.DISPLAY)) + .widget(new SimpleTextWidget(100, 60, "", 16777215, () -> Float.toString(scale))) + + .widget(new LabelWidget(15, 85, "monitor.gui.title.argb", 0xFFFFFFFF)) + .widget(new WidgetARGB(50, 80, 20, this.frameColor, (color) -> setConfig(this.slot, this.scale, color))) + + .widget(new LabelWidget(15, 110, "monitor.gui.title.slot", 0xFFFFFFFF)) + .widget(new ClickButtonWidget(50, 105, 20, 20, "-1", (data) -> setConfig(this.slot - 1, this.scale, this.frameColor))) + .widget(new ClickButtonWidget(130, 105, 20, 20, "+1", (data) -> setConfig(this.slot + 1, this.scale, this.frameColor))) + .widget(new ImageWidget(70, 105, 60, 20, GuiTextures.DISPLAY)) + .widget(new SimpleTextWidget(100, 115, "", 16777215, () -> Integer.toString(slot))) + + .widget(new LabelWidget(15, 135, "monitor.gui.title.plugin", 0xFFFFFFFF)) + .widget(new SlotWidget(inventory, 0, 50, 130, true, true) + .setBackgroundTexture(GuiTextures.SLOT) + .setChangeListener(() -> { + if (this.getWorld() != null && !this.getWorld().isRemote) { + MonitorPluginBaseBehavior behavior = MonitorPluginBaseBehavior.getBehavior(inventory.getStackInSlot(0)); + if (behavior == null) { + unloadPlugin(); + } else { + loadPlugin(behavior); + } + writeCustomData(GregtechDataCodes.UPDATE_PLUGIN_ITEM, packetBuffer -> packetBuffer.writeItemStack(inventory.getStackInSlot(0))); + } + })) + .widget(new ClickButtonWidget(80, 130, 40, 20, "monitor.gui.title.config", (data) -> { + if (plugin != null && mainGroup.isVisible()) { + plugin.customUI(pluginWidget, this.getHolder(), entityPlayer); + mainGroup.setVisible(false); + } + }) { + @Override + protected void triggerButton() { + super.triggerButton(); + if (plugin != null && mainGroup.isVisible()) { + plugin.customUI(pluginWidget, getHolder(), entityPlayer); + mainGroup.setVisible(false); + } + } + }) + + .widget(new WidgetCoverList(width - 140, 50, 120, 11, covers, getCoverFromPosSide(this.coverPos), (coverPos) -> { + if (coverPos == null) { + this.setMode(null, this.mode); + } else { + this.setMode(new BlockPosFace(coverPos.coverHolder.getPos(), coverPos.attachedSide)); + } + })) + + .widget(buttons[0]) + .widget(buttons[1]) + .widget(buttons[2]) + .widget(buttons[3]) + .widget(buttons[4]) + .bindPlayerInventory(entityPlayer.inventory, GuiTextures.SLOT, 15, 170); + + return ModularUI.builder(GuiTextures.BOXED_BACKGROUND, width, height) + .widget(pluginWidget) + .widget(mainGroup) + .widget(new WidgetMonitorScreen(330, 0, 150, this)) + .widget(new LabelWidget(15, 13, "gregtech.machine.monitor_screen.name", 0XFFFFFFFF)) + .widget(new ClickButtonWidget(15, 25, 40, 20, "monitor.gui.title.back", data -> { + if (mainGroup.isVisible() && ((MetaTileEntityCentralMonitor) controller).isActive() && controller.isValid()) { + MetaTileEntityUIFactory.INSTANCE.openUI(controller.getHolder(), (EntityPlayerMP) entityPlayer); + } else if (!mainGroup.isVisible()) { + pluginWidget.removePluginWidget(); + mainGroup.setVisible(true); + if (plugin != null) { + plugin.markAsDirty(); + } + } + }) { + @Override + protected void triggerButton() { + super.triggerButton(); + if (!mainGroup.isVisible()) { + pluginWidget.removePluginWidget(); + mainGroup.setVisible(true); + if (plugin != null) { + plugin.markAsDirty(); + } + } + } + }) + .bindCloseListener(() -> { + if (plugin != null) { + plugin.markAsDirty(); + } + }) + .build(this.getHolder(), entityPlayer); + } + return null; + } + + // adaptive click, supports scaling. x and y is the pos of the origin screen (scale = 1). this func must be called when screen is active. + public boolean onClickLogic(EntityPlayer playerIn, EnumHand hand, EnumFacing facing, boolean isRight, double x, double y) { + if (this.plugin != null) { + boolean flag = this.plugin.onClickLogic(playerIn, hand, facing, isRight, x, y); + if (flag) return true; + } + if (this.getWorld().isRemote) return true; + CoverDigitalInterface coverBehavior = getCoverFromPosSide(this.coverPos); + if (isRight) { + if (coverBehavior != null && coverBehavior.isProxy() && coverBehavior.coverHolder != null && this.mode != CoverDigitalInterface.MODE.PROXY) { + if (playerIn.isSneaking() && playerIn.getHeldItemMainhand().isEmpty() && this.plugin == null) { + if (1f / 16 < x && x < 4f / 16 && 1f / 16 < y && y < 4f / 16) { + this.setConfig(this.slot - 1, this.scale, this.frameColor); + return true; + } else if (12f / 16 < x && x < 15f / 16 && 1f / 16 < y && y < 4f / 16) { + this.setConfig(this.slot + 1, this.scale, this.frameColor); + return true; + } + } + if (coverBehavior.modeRightClick(playerIn, hand, this.mode, this.slot) == EnumActionResult.PASS) { + if (!playerIn.isSneaking() && this.openGUIOnRightClick()) { + TileEntity te = coverBehavior.getCoveredTE(); + if (te != null) { + BlockPos pos = te.getPos(); + IBlockState state = te.getWorld().getBlockState(pos); + state.getBlock().onBlockActivated(coverBehavior.coverHolder.getWorld(), pos, state, playerIn, hand, coverBehavior.getCoveredFacing(), 0.5f, 0.5f, 0.5f); + } + return true; + } else { + return false; + } + } + return true; + } + } else { + if (coverBehavior != null && coverBehavior.isProxy() && coverBehavior.coverHolder != null && this.mode != CoverDigitalInterface.MODE.PROXY) { + return coverBehavior.modeLeftClick(playerIn, this.mode, this.slot); + } + } + return false; + } + + private double[] handleRayTraceResult(RayTraceResult rayTraceResult) { + double dX = rayTraceResult.sideHit.getAxis() == EnumFacing.Axis.X + ? rayTraceResult.hitVec.z - rayTraceResult.getBlockPos().getZ() + : rayTraceResult.hitVec.x - rayTraceResult.getBlockPos().getX(); + double dY = rayTraceResult.sideHit.getAxis() == EnumFacing.Axis.Y + ? rayTraceResult.hitVec.z - rayTraceResult.getBlockPos().getZ() + : rayTraceResult.hitVec.y - rayTraceResult.getBlockPos().getY(); + dX = 1 - dX; + dY = 1 - dY; + if(rayTraceResult.sideHit.getYOffset() < 0) { + dY = 1 - dY; + } + if (rayTraceResult.sideHit == EnumFacing.WEST || rayTraceResult.sideHit == EnumFacing.SOUTH) { + dX = 1 - dX; + } else if (rayTraceResult.sideHit == EnumFacing.UP) { + dX = 1 - dX; + dY = 1 - dY; + } + return new double[]{dX, dY}; + } + + private boolean handleHitResultWithScale(EntityPlayer playerIn, EnumHand hand, EnumFacing facing, boolean isRight, CuboidRayTraceResult rayTraceResult) { + boolean flag = false; + if (rayTraceResult != null && rayTraceResult.typeOfHit == RayTraceResult.Type.BLOCK && this.getController() != null) { + double[] pos = handleRayTraceResult(rayTraceResult); + MetaTileEntityMonitorScreen[][] screens = ((MetaTileEntityCentralMonitor) this.getController()).screens; + int mX = this.getX(), mY = this.getY(); + int max = Math.max(mX, mY); + for (int i = 0; i <= max && mX - i >= 0; i++) { + for (int j = 0; j <= max && mY - j >= 0; j++) { + MetaTileEntityMonitorScreen screen = screens[mX - i][mY - j]; + if (screen != null && screen.isActive()) { + double xR = (pos[0] + i) / screen.scale; + double yR = (pos[1] + j) / screen.scale; + if (xR >= 0 && xR <= 1 && yR >= 0 && yR <= 1) + if (screen.onClickLogic(playerIn, hand, facing, isRight, xR, yR)) { + flag = true; + } + } + } + } + } + return flag; + } + + @SideOnly(Side.CLIENT) + public double[] checkLookingAt(RayTraceResult rayTraceResult) { + if (this.getWorld() != null) { + MultiblockControllerBase controller = this.getController(); + if (rayTraceResult != null && rayTraceResult.typeOfHit == RayTraceResult.Type.BLOCK && controller != null && rayTraceResult.sideHit == controller.getFrontFacing()) { + int i, j; + TileEntity tileEntity = this.getWorld().getTileEntity(rayTraceResult.getBlockPos()); + if (tileEntity instanceof MetaTileEntityHolder && ((MetaTileEntityHolder) tileEntity).getMetaTileEntity() instanceof MetaTileEntityMonitorScreen) { + MetaTileEntityMonitorScreen screenHit = (MetaTileEntityMonitorScreen) ((MetaTileEntityHolder) tileEntity).getMetaTileEntity(); + if (controller == screenHit.getController()) { + i = ((MetaTileEntityMonitorScreen) ((MetaTileEntityHolder) tileEntity).getMetaTileEntity()).getX() - this.getX(); + j = ((MetaTileEntityMonitorScreen) ((MetaTileEntityHolder) tileEntity).getMetaTileEntity()).getY() - this.getY(); + double[] pos = handleRayTraceResult(rayTraceResult); + if ((i >= 0 && j >= 0)) { + pos[0] = (pos[0] + i) / this.scale; + pos[1] = (pos[1] + j) / this.scale; + if (pos[0] >= 0 && pos[0] <= 1 && pos[1] >= 0 && pos[1] <= 1) + return new double[]{pos[0], pos[1]}; + } + } + } + } + } + return null; + } + + @Override + public boolean onRightClick(EntityPlayer playerIn, EnumHand hand, EnumFacing facing, CuboidRayTraceResult hitResult) { + if (!(!playerIn.isSneaking() && playerIn.getHeldItemMainhand().hasCapability(GregtechCapabilities.CAPABILITY_SCREWDRIVER, (EnumFacing) null)) + && !MetaTileEntities.MONITOR_SCREEN.getStackForm().isItemEqual(playerIn.getHeldItemMainhand())) { + if (playerIn.world.getTotalWorldTime() - lastClickTime < 2 && + playerIn.getPersistentID().equals(lastClickUUID)) { + return true; + } + lastClickTime = playerIn.world.getTotalWorldTime(); + lastClickUUID = playerIn.getPersistentID(); + + MultiblockControllerBase controller = this.getController(); + if (controller instanceof MetaTileEntityCentralMonitor && + ((MetaTileEntityCentralMonitor) controller).isActive() && controller.getFrontFacing() == facing) { + return handleHitResultWithScale(playerIn, hand, facing, true, hitResult); + } + } + return false; + } + + @Override + public boolean onScrewdriverClick(EntityPlayer playerIn, EnumHand hand, EnumFacing facing, CuboidRayTraceResult hitResult) { + if (!playerIn.isSneaking() && this.getWorld() != null && !this.getWorld().isRemote) { + MetaTileEntityUIFactory.INSTANCE.openUI(this.getHolder(), (EntityPlayerMP) playerIn); + return true; + } else { + return false; + } + } + + @Override + public void onLeftClick(EntityPlayer playerIn, EnumFacing facing, CuboidRayTraceResult hitResult) { + if (playerIn.world.getTotalWorldTime() - lastClickTime < 2 && playerIn.getPersistentID().equals(lastClickUUID)) { + return; + } + lastClickTime = playerIn.world.getTotalWorldTime(); + lastClickUUID = playerIn.getPersistentID(); + MultiblockControllerBase controller = this.getController(); + if (controller != null && controller.getFrontFacing() == facing) { + handleHitResultWithScale(playerIn, null, facing, false, hitResult); + } + } + + @Override + public void addInformation(ItemStack stack, @Nullable World player, List tooltip, boolean advanced) { + super.addInformation(stack, player, tooltip, advanced); + tooltip.add(I18n.format("gregtech.multiblock.monitor_screen.tooltip.1")); + tooltip.add(I18n.format("gregtech.multiblock.monitor_screen.tooltip.2")); + tooltip.add(I18n.format("gregtech.multiblock.monitor_screen.tooltip.3")); + } + + @Override + public Pair getParticleTexture() { + return Pair.of(null, -1); + } +} diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeEnergy.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeEnergy.java index ca00c345807..e4b4580b6f3 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeEnergy.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityCreativeEnergy.java @@ -5,6 +5,7 @@ import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; +import com.google.common.collect.Lists; import gregtech.api.GTValues; import gregtech.api.capability.GregtechCapabilities; import gregtech.api.capability.IEnergyContainer; @@ -28,6 +29,7 @@ import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.tuple.Pair; +import java.util.List; import java.util.function.Function; public class MetaTileEntityCreativeEnergy extends MetaTileEntity implements IEnergyContainer { @@ -38,6 +40,11 @@ public class MetaTileEntityCreativeEnergy extends MetaTileEntity implements IEne private int setTier = 0; private boolean active = false; + private long lastEnergyOutputPerSec = 0; + private long energyOutputPerSec = 0; + + private final List ALLOWED_CHARS = Lists.newArrayList('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'); + public MetaTileEntityCreativeEnergy() { super(new ResourceLocation(GTValues.MODID, "infinite_energy")); } @@ -99,9 +106,18 @@ protected ModularUI createUI(EntityPlayer entityPlayer) { return builder.build(getHolder(), entityPlayer); } + @Override + public long getOutputPerSec() { + return lastEnergyOutputPerSec; + } + @Override public void update() { super.update(); + if (getOffsetTimer() % 20 == 0) { + lastEnergyOutputPerSec = energyOutputPerSec; + energyOutputPerSec = 0; + } if (getWorld().isRemote || !active || voltage <= 0 || amps <= 0) return; int ampsUsed = 0; for (EnumFacing facing : EnumFacing.values()) { @@ -116,6 +132,7 @@ public void update() { break; } } + energyOutputPerSec += ampsUsed * voltage; } @Override diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java index 8cc7c47d337..779782983b4 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityWorkbench.java @@ -20,9 +20,9 @@ import gregtech.api.unification.material.Materials; import gregtech.api.util.GTUtility; import gregtech.api.util.Position; -import gregtech.common.gui.widget.CraftingSlotWidget; -import gregtech.common.gui.widget.ItemListGridWidget; -import gregtech.common.gui.widget.MemorizedRecipeWidget; +import gregtech.common.gui.widget.craftingstation.CraftingSlotWidget; +import gregtech.common.gui.widget.craftingstation.ItemListGridWidget; +import gregtech.common.gui.widget.craftingstation.MemorizedRecipeWidget; import gregtech.common.inventory.IItemList; import gregtech.common.inventory.handlers.SingleItemStackHandler; import gregtech.common.inventory.handlers.ToolItemStackHandler; @@ -45,7 +45,6 @@ import java.util.function.Supplier; public class MetaTileEntityWorkbench extends MetaTileEntity { - private final ItemStackHandler internalInventory = new ItemStackHandler(18); private final ItemStackHandler craftingGrid = new SingleItemStackHandler(9); private final ItemStackHandler toolInventory = new ToolItemStackHandler(9); @@ -59,6 +58,40 @@ public MetaTileEntityWorkbench(ResourceLocation metaTileEntityId) { this.setPaintingColor(0xFFFFFF); } + public static AbstractWidgetGroup createWorkbenchTab(CraftingRecipeResolver recipeResolver, ItemStackHandler craftingGrid, CraftingRecipeMemory recipeMemory, + ItemStackHandler toolInventory, ItemStackHandler internalInventory) { + WidgetGroup widgetGroup = new WidgetGroup(); + widgetGroup.addWidget(new ImageWidget(88 - 13, 44 - 14, 26, 26, GuiTextures.SLOT)); + widgetGroup.addWidget(new CraftingSlotWidget(recipeResolver, 0, 88 - 9, 44 - 9)); + + //crafting grid + widgetGroup.addWidget(new CraftingStationInputWidgetGroup(4, 7, craftingGrid, recipeResolver)); + + Supplier textSupplier = () -> Integer.toString(recipeResolver.getItemsCrafted()); + widgetGroup.addWidget(new SimpleTextWidget(88, 44 + 19, "", textSupplier)); + + Consumer clearAction = (clickData) -> recipeResolver.clearCraftingGrid(); + widgetGroup.addWidget(new ClickButtonWidget(8 + 18 * 3 + 3, 16, 8, 8, "", clearAction).setButtonTexture(GuiTextures.BUTTON_CLEAR_GRID)); + + widgetGroup.addWidget(new ImageWidget(168 - 18 * 3, 44 - 19 * 3 / 2, 18 * 3, 18 * 3, TextureArea.fullImage("textures/gui/base/darkened_slot.png"))); + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + widgetGroup.addWidget(new MemorizedRecipeWidget(recipeMemory, j + i * 3, craftingGrid, 168 - 18 * 3 / 2 - 27 + j * 18, 44 - 28 + i * 18)); + } + } + //tool inventory + for (int i = 0; i < 9; i++) { + widgetGroup.addWidget(new SlotWidget(toolInventory, i, 7 + i * 18, 75).setBackgroundTexture(GuiTextures.SLOT, GuiTextures.TOOL_SLOT_OVERLAY)); + } + //internal inventory + for (int i = 0; i < 2; ++i) { + for (int j = 0; j < 9; ++j) { + widgetGroup.addWidget(new SlotWidget(internalInventory, j + i * 9, 7 + j * 18, 98 + i * 18).setBackgroundTexture(GuiTextures.SLOT)); + } + } + return widgetGroup; + } + @Override public MetaTileEntity createMetaTileEntity(MetaTileEntityHolder holder) { return new MetaTileEntityWorkbench(metaTileEntityId); @@ -146,40 +179,6 @@ public void clearMachineInventory(NonNullList itemBuffer) { clearInventory(itemBuffer, toolInventory); } - public static AbstractWidgetGroup createWorkbenchTab(CraftingRecipeResolver recipeResolver, ItemStackHandler craftingGrid, CraftingRecipeMemory recipeMemory, - ItemStackHandler toolInventory, ItemStackHandler internalInventory) { - WidgetGroup widgetGroup = new WidgetGroup(); - widgetGroup.addWidget(new ImageWidget(88 - 13, 44 - 14, 26, 26, GuiTextures.SLOT)); - widgetGroup.addWidget(new CraftingSlotWidget(recipeResolver, 0, 88 - 9, 44 - 9)); - - //crafting grid - widgetGroup.addWidget(new CraftingStationInputWidgetGroup(4, 7, craftingGrid, recipeResolver)); - - Supplier textSupplier = () -> Integer.toString(recipeResolver.getItemsCrafted()); - widgetGroup.addWidget(new SimpleTextWidget(88, 44 + 19, "", textSupplier)); - - Consumer clearAction = (clickData) -> recipeResolver.clearCraftingGrid(); - widgetGroup.addWidget(new ClickButtonWidget(8 + 18 * 3 + 3, 16, 8, 8, "", clearAction).setButtonTexture(GuiTextures.BUTTON_CLEAR_GRID)); - - widgetGroup.addWidget(new ImageWidget(168 - 18 * 3, 44 - 19 * 3 / 2, 18 * 3, 18 * 3, TextureArea.fullImage("textures/gui/base/darkened_slot.png"))); - for (int i = 0; i < 3; ++i) { - for (int j = 0; j < 3; ++j) { - widgetGroup.addWidget(new MemorizedRecipeWidget(recipeMemory, j + i * 3, craftingGrid, 168 - 18 * 3 / 2 - 27 + j * 18, 44 - 28 + i * 18)); - } - } - //tool inventory - for (int i = 0; i < 9; i++) { - widgetGroup.addWidget(new SlotWidget(toolInventory, i, 7 + i * 18, 75).setBackgroundTexture(GuiTextures.SLOT, GuiTextures.TOOL_SLOT_OVERLAY)); - } - //internal inventory - for (int i = 0; i < 2; ++i) { - for (int j = 0; j < 9; ++j) { - widgetGroup.addWidget(new SlotWidget(internalInventory, j + i * 9, 7 + j * 18, 98 + i * 18).setBackgroundTexture(GuiTextures.SLOT)); - } - } - return widgetGroup; - } - private AbstractWidgetGroup createItemListTab() { WidgetGroup widgetGroup = new WidgetGroup(); widgetGroup.addWidget(new LabelWidget(5, 20, "gregtech.machine.workbench.storage_note_1")); diff --git a/src/main/java/gregtech/common/pipelike/cable/net/EnergyNet.java b/src/main/java/gregtech/common/pipelike/cable/net/EnergyNet.java index db5bc4c03ba..0655958bb4a 100644 --- a/src/main/java/gregtech/common/pipelike/cable/net/EnergyNet.java +++ b/src/main/java/gregtech/common/pipelike/cable/net/EnergyNet.java @@ -7,6 +7,8 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraftforge.fml.common.FMLCommonHandler; import java.util.Comparator; import java.util.HashMap; @@ -15,6 +17,10 @@ public class EnergyNet extends PipeNet { + private long lastEnergyFluxPerSec; + private long energyFluxPerSec; + private long lastTime; + private final Map> NET_DATA = new HashMap<>(); protected EnergyNet(WorldPipeNet world) { @@ -35,6 +41,24 @@ public void nodeNeighbourChanged(BlockPos pos) { NET_DATA.clear(); } + public long getEnergyFluxPerSec() { + World world = getWorldData(); + if (world != null && !world.isRemote && (world.getWorldTime() - lastTime) >= 20) { + lastTime = world.getWorldTime(); + clearCache(); + } + return lastEnergyFluxPerSec; + } + + public void addEnergyFluxPerSec(long energy) { + energyFluxPerSec += energy; + } + + public void clearCache() { + lastEnergyFluxPerSec = energyFluxPerSec; + energyFluxPerSec = 0; + } + @Override protected void updateBlockedConnections(BlockPos nodePos, EnumFacing facing, boolean isBlocked) { super.updateBlockedConnections(nodePos, facing, isBlocked); diff --git a/src/main/java/gregtech/common/pipelike/cable/net/EnergyNetHandler.java b/src/main/java/gregtech/common/pipelike/cable/net/EnergyNetHandler.java index 09d16ade961..4362cf39b3a 100644 --- a/src/main/java/gregtech/common/pipelike/cable/net/EnergyNetHandler.java +++ b/src/main/java/gregtech/common/pipelike/cable/net/EnergyNetHandler.java @@ -26,6 +26,16 @@ public EnergyNetHandler(EnergyNet net, TileEntityCable cable, EnumFacing facing) this.facing = facing; } + @Override + public long getInputPerSec() { + return net.getEnergyFluxPerSec(); + } + + @Override + public long getOutputPerSec() { + return net.getEnergyFluxPerSec(); + } + @Override public long acceptEnergyFromNetwork(EnumFacing side, long voltage, long amperage) { if (side == null) { @@ -70,6 +80,7 @@ public long acceptEnergyFromNetwork(EnumFacing side, long voltage, long amperage if (amperage == amperesUsed) break; } + net.addEnergyFluxPerSec(amperesUsed * voltage); return amperesUsed; } diff --git a/src/main/java/gregtech/common/render/WorldRenderEventRenderer.java b/src/main/java/gregtech/common/render/WorldRenderEventRenderer.java new file mode 100644 index 00000000000..5ab69d3203d --- /dev/null +++ b/src/main/java/gregtech/common/render/WorldRenderEventRenderer.java @@ -0,0 +1,67 @@ +package gregtech.common.render; + +import gregtech.api.util.RenderBufferHelper; +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.EntityPlayerSP; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.util.math.BlockPos; +import net.minecraftforge.client.event.RenderWorldLastEvent; +import org.lwjgl.opengl.GL11; + +public class WorldRenderEventRenderer { + + private static BlockPos posHighLight; + private static long hlEndTime; + + public static void renderBlockBoxHighLight(BlockPos blockpos, long durTimeMillis) { + posHighLight = blockpos; + hlEndTime = System.currentTimeMillis() + durTimeMillis; + } + + public static void renderWorldLastEvent(RenderWorldLastEvent evt) { + if (posHighLight != null) { + long time = System.currentTimeMillis(); + if (time > hlEndTime) { + posHighLight = null; + hlEndTime = 0; + return; + } + if (((time / 500) & 1) == 0) { + return; + } + EntityPlayerSP p = Minecraft.getMinecraft().player; + double doubleX = p.lastTickPosX + (p.posX - p.lastTickPosX) * evt.getPartialTicks(); + double doubleY = p.lastTickPosY + (p.posY - p.lastTickPosY) * evt.getPartialTicks(); + double doubleZ = p.lastTickPosZ + (p.posZ - p.lastTickPosZ) * evt.getPartialTicks(); + + GlStateManager.pushMatrix(); + GlStateManager.color(1.0f, 0, 0); + GlStateManager.translate(-doubleX, -doubleY, -doubleZ); + + GlStateManager.disableDepth(); + GlStateManager.disableTexture2D(); + GlStateManager.enableBlend(); + GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE); + + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder buffer = tessellator.getBuffer(); + + buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR); + + RenderBufferHelper.renderCubeFace(buffer, posHighLight.getX(), posHighLight.getY(), posHighLight.getZ(), posHighLight.getX() + 1, posHighLight.getY() + 1, posHighLight.getZ() + 1, 1.0f, 0.0f, 0.0f, 0.8f); + + tessellator.draw(); + + GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GlStateManager.disableBlend(); + GlStateManager.enableTexture2D(); + GlStateManager.enableDepth(); + GlStateManager.color(1, 1, 1); + GlStateManager.popMatrix(); + } + } + +} diff --git a/src/main/java/gregtech/common/render/WrenchOverlayRenderer.java b/src/main/java/gregtech/common/render/WrenchOverlayRenderer.java index a92ab32e93e..d96fd90d6d8 100644 --- a/src/main/java/gregtech/common/render/WrenchOverlayRenderer.java +++ b/src/main/java/gregtech/common/render/WrenchOverlayRenderer.java @@ -9,6 +9,7 @@ import gregtech.api.metatileentity.MetaTileEntityHolder; import gregtech.api.pipenet.tile.TileEntityPipeBase; import gregtech.api.util.GTUtility; +import gregtech.common.metatileentities.multi.electric.centralmonitor.MetaTileEntityMonitorScreen; import gregtech.common.pipelike.cable.Insulation; import gregtech.common.pipelike.fluidpipe.FluidPipeType; import gregtech.common.pipelike.itempipe.ItemPipeType; @@ -45,6 +46,13 @@ public static void onDrawBlockHighlight(DrawBlockHighlightEvent event) { TileEntity tileEntity = world.getTileEntity(pos); ItemStack heldItem = player.getHeldItem(EnumHand.MAIN_HAND); + if (tileEntity instanceof MetaTileEntityHolder) { + if (((MetaTileEntityHolder) tileEntity).getMetaTileEntity() instanceof MetaTileEntityMonitorScreen) { + event.setCanceled(true); + return; + } + } + if (tileEntity != null && shouldDrawOverlayForItem(heldItem, tileEntity)) { EnumFacing facing = target.sideHit; GlStateManager.enableBlend(); diff --git a/src/main/java/gregtech/common/terminal/app/prospector/ProspectingTexture.java b/src/main/java/gregtech/common/terminal/app/prospector/ProspectingTexture.java index 14979a6bbce..362b736ee8c 100644 --- a/src/main/java/gregtech/common/terminal/app/prospector/ProspectingTexture.java +++ b/src/main/java/gregtech/common/terminal/app/prospector/ProspectingTexture.java @@ -1,9 +1,9 @@ package gregtech.common.terminal.app.prospector; -import gregtech.api.gui.resources.RenderUtil; import gregtech.api.net.SProspectingPacket; import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.stack.MaterialStack; +import gregtech.api.util.RenderUtil; import net.minecraft.client.gui.Gui; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.texture.AbstractTexture; diff --git a/src/main/java/gregtech/integration/jei/JEIOptional.java b/src/main/java/gregtech/integration/jei/JEIOptional.java new file mode 100644 index 00000000000..83dd56a052e --- /dev/null +++ b/src/main/java/gregtech/integration/jei/JEIOptional.java @@ -0,0 +1,31 @@ +package gregtech.integration.jei; + +import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; +import gregtech.api.render.scene.WorldSceneRenderer; +import gregtech.integration.jei.multiblock.MultiblockInfoRecipeWrapper; +import mezz.jei.api.IRecipeRegistry; +import mezz.jei.api.recipe.IFocus; +import mezz.jei.api.recipe.IRecipeCategory; +import mezz.jei.api.recipe.IRecipeWrapper; +import net.minecraft.item.ItemStack; +import net.minecraftforge.fml.common.Optional; + +import java.util.List; + +public class JEIOptional { + @Optional.Method(modid = "jei") + public static WorldSceneRenderer getWorldSceneRenderer(MultiblockControllerBase controllerBase){ + IRecipeRegistry rr = GTJeiPlugin.jeiRuntime.getRecipeRegistry(); + IFocus focus = rr.createFocus(IFocus.Mode.INPUT, controllerBase.getStackForm()); + return rr.getRecipeCategories(focus) + .stream() + .map(c -> (IRecipeCategory) c) + .map(c -> rr.getRecipeWrappers(c, focus)) + .flatMap(List::stream) + .filter(MultiblockInfoRecipeWrapper.class::isInstance) + .findFirst() + .map(MultiblockInfoRecipeWrapper.class::cast) + .map(MultiblockInfoRecipeWrapper::getCurrentRenderer) + .orElse(null); + } +} diff --git a/src/main/java/gregtech/integration/jei/multiblock/MultiblockInfoCategory.java b/src/main/java/gregtech/integration/jei/multiblock/MultiblockInfoCategory.java index 0a662ce5212..692397e9ba0 100644 --- a/src/main/java/gregtech/integration/jei/multiblock/MultiblockInfoCategory.java +++ b/src/main/java/gregtech/integration/jei/multiblock/MultiblockInfoCategory.java @@ -60,6 +60,7 @@ public MultiblockInfoCategory(IJeiHelpers helpers) { put("primitive_water_pump", new MultiblockInfoRecipeWrapper(new PrimitivePumpInfo())); put("steam_grinder", new MultiblockInfoRecipeWrapper(new SteamGrinderInfo())); put("steam_oven", new MultiblockInfoRecipeWrapper(new SteamOvenInfo())); + put("central_monitor", new MultiblockInfoRecipeWrapper(new CentralMonitorInfo())); put("basic_large_miner", new MultiblockInfoRecipeWrapper(new LargeMinerInfo(BASIC_LARGE_MINER))); put("large_miner", new MultiblockInfoRecipeWrapper(new LargeMinerInfo(LARGE_MINER))); put("advanced_large_miner", new MultiblockInfoRecipeWrapper(new LargeMinerInfo(ADVANCED_LARGE_MINER))); @@ -105,6 +106,6 @@ public void setRecipe(IRecipeLayout recipeLayout, MultiblockInfoRecipeWrapper re recipeWrapper.setRecipeLayout((RecipeLayout) recipeLayout, this.guiHelper); IGuiItemStackGroup itemStackGroup = recipeLayout.getItemStacks(); - itemStackGroup.addTooltipCallback(recipeWrapper::addBlockTooltips); + itemStackGroup.addTooltipCallback((a,b,itemStack,list)->recipeWrapper.addBlockTooltips(itemStack,list)); } } diff --git a/src/main/java/gregtech/integration/jei/multiblock/MultiblockInfoRecipeWrapper.java b/src/main/java/gregtech/integration/jei/multiblock/MultiblockInfoRecipeWrapper.java index 33cb87bb4b0..175842bbcf7 100755 --- a/src/main/java/gregtech/integration/jei/multiblock/MultiblockInfoRecipeWrapper.java +++ b/src/main/java/gregtech/integration/jei/multiblock/MultiblockInfoRecipeWrapper.java @@ -6,7 +6,6 @@ import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Translation; import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.resources.RenderUtil; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.MetaTileEntityHolder; import gregtech.api.metatileentity.multiblock.MultiblockControllerBase; @@ -16,6 +15,7 @@ import gregtech.api.util.BlockInfo; import gregtech.api.util.GTUtility; import gregtech.api.util.ItemStackKey; +import gregtech.api.util.RenderUtil; import mezz.jei.api.IGuiHelper; import mezz.jei.api.gui.IDrawable; import mezz.jei.api.gui.IGuiItemStackGroup; @@ -147,7 +147,7 @@ public void setRecipeLayout(RecipeLayout layout, IGuiHelper guiHelper) { this.buttonPreviousPattern.enabled = false; this.buttonNextPattern.enabled = patterns.length > 1; - this.zoom = infoPage.getDefaultZoom() * 15; + this.zoom = 8 / infoPage.getDefaultZoom(); this.rotationYaw = 20.0f; this.rotationPitch = 135.0f; this.currentRendererPage = 0; @@ -156,8 +156,9 @@ public void setRecipeLayout(RecipeLayout layout, IGuiHelper guiHelper) { zoom = (float) MathHelper.clamp(zoom + (Mouse.getEventDWheel() < 0 ? 0.5 : -0.5), 3, 999); setNextLayer(getLayerIndex()); } - if (center != null) { - getCurrentRenderer().setCameraLookAt(center, zoom, Math.toRadians(rotationPitch), Math.toRadians(rotationYaw)); + if (getCurrentRenderer() != null) { + TrackedDummyWorld world = (TrackedDummyWorld) getCurrentRenderer().world; + resetCenter(world); } updateParts(); } @@ -187,6 +188,7 @@ private void setNextLayer(int newLayer) { WorldSceneRenderer renderer = getCurrentRenderer(); if (renderer != null) { TrackedDummyWorld world = ((TrackedDummyWorld)renderer.world); + resetCenter(world); renderer.renderedBlocksMap.clear(); int minY = (int) world.getMinPos().getY(); Collection renderBlocks; @@ -199,6 +201,13 @@ private void setNextLayer(int newLayer) { } } + private void resetCenter(TrackedDummyWorld world) { + Vector3f size = world.getSize(); + Vector3f minPos = world.getMinPos(); + center = new Vector3f(minPos.x + size.x / 2, minPos.y + size.y / 2, minPos.z + size.z / 2); + getCurrentRenderer().setCameraLookAt(center, zoom, Math.toRadians(rotationPitch), Math.toRadians(rotationYaw)); + } + private void switchRenderPage(int amount) { int maxIndex = patterns.length - 1; int newIndex = Math.max(0, Math.min(currentRendererPage + amount, maxIndex)); @@ -234,7 +243,7 @@ public void drawInfo(@Nonnull Minecraft minecraft, int recipeWidth, int recipeHe WorldSceneRenderer renderer = getCurrentRenderer(); int sceneHeight = recipeHeight - PARTS_HEIGHT; - renderer.render(recipeLayout.getPosX(), recipeLayout.getPosY(), recipeWidth, sceneHeight, Mouse.getX(), Mouse.getY()); + renderer.render(recipeLayout.getPosX(), recipeLayout.getPosY(), recipeWidth, sceneHeight, mouseX + recipeLayout.getPosX(), mouseY + recipeLayout.getPosY()); drawMultiblockName(recipeWidth); //reset colors (so any elements render after this point are not dark) @@ -346,20 +355,13 @@ public List getTooltipStrings(int mouseX, int mouseY) { tooltip.set(k, TextFormatting.GRAY + tooltip.get(k)); } } - Map> blockTooltipMap = infoPage.getBlockTooltipMap(); - if (blockTooltipMap.containsKey(tooltipBlockStack)) { - List tooltips = blockTooltipMap.get(tooltipBlockStack); - for (int i = 0; i < tooltips.size(); i++) { - //Start at i+1 due to ItemStack name - tooltip.add(i + 1, tooltips.get(i).getFormattedText()); - } - } + addBlockTooltips(tooltipBlockStack, tooltip); return tooltip; } return Collections.emptyList(); } - public void addBlockTooltips(int slotIndex, boolean input, ItemStack itemStack, List tooltip) { + public void addBlockTooltips(ItemStack itemStack, List tooltip) { Map> blockTooltipMap = infoPage.getBlockTooltipMap(); if (blockTooltipMap.containsKey(itemStack)) { List tooltips = blockTooltipMap.get(itemStack); @@ -467,16 +469,17 @@ private MBPattern initializePattern(MultiblockShapeInfo shapeInfo, Set getMatchingShapes() { + List shapes = new ArrayList<>(); + for (int i = 3; i <= MetaTileEntityCentralMonitor.MAX_WIDTH; i++) { + int height = 3; + MultiblockShapeInfo.Builder builder = MultiblockShapeInfo.builder(); + String[] start = new String[height]; + String[] slice = new String[height]; + String[] end = new String[height]; + for (int j = 0; j < height; j++) { + start[j] = "A"; + slice[j] = "B"; + end[j] = "A"; + } + start[0] = "E"; + start[1] = "S"; + builder.aisle(start); + for (int num = 0; num < i; num++) { + builder.aisle(slice); + } + builder.aisle(end) + .where('S', MetaTileEntities.CENTRAL_MONITOR, EnumFacing.NORTH) + .where('E', MetaTileEntities.ENERGY_INPUT_HATCH[GTValues.HV], EnumFacing.NORTH) + .where('A', MetaBlocks.METAL_CASING.getState(BlockMetalCasing.MetalCasingType.STEEL_SOLID)) + .where('B', MetaTileEntities.MONITOR_SCREEN, EnumFacing.WEST); + shapes.add(builder.build()); + } + return shapes; + } + + @Override + public String[] getDescription() { + return new String[]{I18n.format("gregtech.multiblock.central_monitor.tooltip.2", MetaTileEntityCentralMonitor.MAX_WIDTH, MetaTileEntityCentralMonitor.MAX_HEIGHT), I18n.format("gregtech.multiblock.central_monitor.tooltip.3")}; + } +} diff --git a/src/main/java/gregtech/integration/jei/utils/render/FluidStackTextRenderer.java b/src/main/java/gregtech/integration/jei/utils/render/FluidStackTextRenderer.java index cbe943edb42..613658433ea 100644 --- a/src/main/java/gregtech/integration/jei/utils/render/FluidStackTextRenderer.java +++ b/src/main/java/gregtech/integration/jei/utils/render/FluidStackTextRenderer.java @@ -1,6 +1,6 @@ package gregtech.integration.jei.utils.render; -import gregtech.api.gui.resources.RenderUtil; +import gregtech.api.util.RenderUtil; import gregtech.api.util.TextFormattingUtil; import mezz.jei.api.gui.IDrawable; import mezz.jei.plugins.vanilla.ingredients.fluid.FluidStackRenderer; diff --git a/src/main/java/gregtech/loaders/recipe/MiscRecipeLoader.java b/src/main/java/gregtech/loaders/recipe/MiscRecipeLoader.java index 84cd9204149..c95ab10176a 100644 --- a/src/main/java/gregtech/loaders/recipe/MiscRecipeLoader.java +++ b/src/main/java/gregtech/loaders/recipe/MiscRecipeLoader.java @@ -3,14 +3,12 @@ import gregtech.api.recipes.ModHandler; import gregtech.api.recipes.RecipeMaps; import gregtech.api.unification.OreDictUnifier; -import gregtech.api.unification.material.Material; +import gregtech.api.unification.material.MarkerMaterials; import gregtech.api.unification.material.Materials; import gregtech.api.unification.ore.OrePrefix; -import gregtech.api.unification.stack.MaterialStack; import gregtech.api.unification.stack.UnificationEntry; import gregtech.common.blocks.BlockTransparentCasing; import gregtech.common.blocks.MetaBlocks; -import gregtech.common.items.MetaItems; import gregtech.common.metatileentities.MetaTileEntities; import net.minecraft.init.Blocks; import net.minecraft.init.Items; @@ -304,6 +302,109 @@ public static void init() { .outputs(ADVANCED_QUARK_TECH_SUITE_CHESTPLATE.getStackForm()) .buildAndRegister(); + ASSEMBLER_RECIPES.recipeBuilder().duration(200).EUt(300) + .inputs(DIODE.getStackForm(32)) + .input(dust, Glass, 1) + .input(dye, MarkerMaterials.Color.Red, 1) + .input(dye, MarkerMaterials.Color.Green, 1) + .input(dye, MarkerMaterials.Color.Blue, 1) + .input(wireFine, Aluminium, 8) + .fluidInputs(SolderingAlloy.getFluid(72)) + .outputs(COLOURED_LEDS.getStackForm(32)) + .buildAndRegister(); + ASSEMBLER_RECIPES.recipeBuilder().duration(160).EUt(300) + .inputs(SMD_DIODE.getStackForm(16)) + .input(dust, Glass, 1) + .input(dye, MarkerMaterials.Color.Red, 1) + .input(dye, MarkerMaterials.Color.Green, 1) + .input(dye, MarkerMaterials.Color.Blue, 1) + .input(wireFine, Aluminium, 8) + .fluidInputs(SolderingAlloy.getFluid(72)) + .outputs(COLOURED_LEDS.getStackForm(32)) + .buildAndRegister(); + CIRCUIT_ASSEMBLER_RECIPES.recipeBuilder().duration(120).EUt(300) + .inputs(COLOURED_LEDS.getStackForm(4)) + .inputs(PLASTIC_BOARD.getStackForm()) + .input(wireFine, Aluminium, 4) + .fluidInputs(SolderingAlloy.getFluid(144)) + .outputs(DISPLAY.getStackForm()) + .buildAndRegister(); + ASSEMBLER_RECIPES.recipeBuilder().duration(80).EUt(480) + .inputs(DISPLAY.getStackForm()) + .inputs((ItemStack) CraftingComponent.HULL.getIngredient(3)) + .input(wireFine, AnnealedCopper, 8) + .fluidInputs(SolderingAlloy.getFluid(288)) + .outputs(MetaTileEntities.MONITOR_SCREEN.getStackForm()) + .buildAndRegister(); + ASSEMBLER_RECIPES.recipeBuilder().duration(100).EUt(500) + .inputs(DISPLAY.getStackForm()) + .inputs((ItemStack) CraftingComponent.HULL.getIngredient(3)) + .input(circuit, MarkerMaterials.Tier.Advanced, 2) + .fluidInputs(SolderingAlloy.getFluid(432)) + .outputs(MetaTileEntities.CENTRAL_MONITOR.getStackForm()) + .buildAndRegister(); + ASSEMBLER_RECIPES.recipeBuilder().duration(100).EUt(120) + .inputs(DISPLAY.getStackForm()) + .input(plate, Aluminium) + .input(circuit, MarkerMaterials.Tier.Good) + .input(screw, StainlessSteel, 4) + .fluidInputs(SolderingAlloy.getFluid(144)) + .outputs(COVER_DIGITAL_INTERFACE.getStackForm()) + .buildAndRegister(); + ASSEMBLER_RECIPES.recipeBuilder().duration(100).EUt(500) + .inputs(COVER_DIGITAL_INTERFACE.getStackForm()) + .inputs(WIRELESS.getStackForm()) + .fluidInputs(SolderingAlloy.getFluid(144)) + .outputs(COVER_DIGITAL_INTERFACE_WIRELESS.getStackForm()) + .buildAndRegister(); + ASSEMBLER_RECIPES.recipeBuilder().duration(80).EUt(400) + .inputs(DISPLAY.getStackForm()) + .input(circuit, MarkerMaterials.Tier.Basic) + .input(wireFine, Copper, 2) + .fluidInputs(SolderingAlloy.getFluid(72)) + .outputs(PLUGIN_TEXT.getStackForm()) + .buildAndRegister(); + ASSEMBLER_RECIPES.recipeBuilder().duration(80).EUt(400) + .inputs(DISPLAY.getStackForm()) + .input(circuit, MarkerMaterials.Tier.Basic) + .input(wireFine, Iron, 2) + .fluidInputs(SolderingAlloy.getFluid(72)) + .outputs(PLUGIN_ONLINE_PIC.getStackForm()) + .buildAndRegister(); + ASSEMBLER_RECIPES.recipeBuilder().duration(80).EUt(400) + .inputs(DISPLAY.getStackForm()) + .input(circuit, MarkerMaterials.Tier.Basic) + .input(wireFine, Gold, 2) + .fluidInputs(SolderingAlloy.getFluid(144)) + .outputs(PLUGIN_FAKE_GUI.getStackForm()) + .buildAndRegister(); + ASSEMBLER_RECIPES.recipeBuilder().duration(80).EUt(400) + .inputs(DISPLAY.getStackForm()) + .input(circuit, MarkerMaterials.Tier.Advanced) + .input(wireFine, Aluminium, 2) + .fluidInputs(SolderingAlloy.getFluid(144)) + .outputs(PLUGIN_ADVANCED_MONITOR.getStackForm()) + .buildAndRegister(); + + // terminal + ASSEMBLER_RECIPES.recipeBuilder().duration(100).EUt(120) + .input(circuit, Good, 4) + .input(ELECTRIC_MOTOR_MV, 2) + .input(ELECTRIC_PISTON_MV, 2) + .input(ROBOT_ARM_MV, 2) + .fluidInputs(SolderingAlloy.getFluid(144)) + .outputs(WIRELESS.getStackForm()) + .buildAndRegister(); + ASSEMBLER_RECIPES.recipeBuilder().duration(100).EUt(30) + .input(ELECTRIC_PISTON_MV, 2) + .input(ELECTRIC_PISTON_MV) + .input(lens, Glass) + .input(lens, Diamond) + .input(circuit, Basic, 4) + .fluidInputs(SolderingAlloy.getFluid(144)) + .outputs(CAMERA.getStackForm()) + .buildAndRegister(); + // Tempered Glass in Arc Furnace ARC_FURNACE_RECIPES.recipeBuilder().duration(60).EUt(30) .input(block, Glass) diff --git a/src/main/resources/assets/gregtech/blockstates/boiler_firebox_casing.json b/src/main/resources/assets/gregtech/blockstates/boiler_firebox_casing.json index d2351d3d6f3..3af850e9653 100644 --- a/src/main/resources/assets/gregtech/blockstates/boiler_firebox_casing.json +++ b/src/main/resources/assets/gregtech/blockstates/boiler_firebox_casing.json @@ -27,23 +27,23 @@ }, "steel_firebox": { "textures": { - "bottom": "gregtech:blocks/casings/solid/machine_bronze_plated_bricks", - "top": "gregtech:blocks/casings/solid/machine_bronze_plated_bricks", - "side": "gregtech:blocks/casings/firebox/machine_casing_firebox_bronze" + "bottom": "gregtech:blocks/casings/solid/machine_casing_solid_steel", + "top": "gregtech:blocks/casings/solid/machine_casing_solid_steel", + "side": "gregtech:blocks/casings/firebox/machine_casing_firebox_steel" } }, "titanium_firebox": { "textures": { - "bottom": "gregtech:blocks/casings/solid/machine_bronze_plated_bricks", - "top": "gregtech:blocks/casings/solid/machine_bronze_plated_bricks", - "side": "gregtech:blocks/casings/firebox/machine_casing_firebox_bronze" + "bottom": "gregtech:blocks/casings/solid/machine_casing_stable_titanium", + "top": "gregtech:blocks/casings/solid/machine_casing_stable_titanium", + "side": "gregtech:blocks/casings/firebox/machine_casing_firebox_titanium" } }, "tungstensteel_firebox": { "textures": { - "bottom": "gregtech:blocks/casings/solid/machine_bronze_plated_bricks", - "top": "gregtech:blocks/casings/solid/machine_bronze_plated_bricks", - "side": "gregtech:blocks/casings/firebox/machine_casing_firebox_bronze" + "bottom": "gregtech:blocks/casings/solid/machine_casing_robust_tungstensteel", + "top": "gregtech:blocks/casings/solid/machine_casing_robust_tungstensteel", + "side": "gregtech:blocks/casings/firebox/machine_casing_firebox_tungstensteel" } } } diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index 88c8eaa25ac..83cb65ac04c 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -748,6 +748,9 @@ metaitem.cover.infinite_water.tooltip=Creates 16 Buckets of Water every second ( metaitem.cover.ender_fluid_link.name=Ender Fluid Link Cover metaitem.cover.ender_fluid_link.tooltip=Link your fluid tanks to the Ender! (as Cover) +metaitem.cover.drain=Drain Cover + + metaitem.gelled_toluene.name=Gelled Toluene metaitem.gelled_toluene.tooltip=Raw Explosive @@ -2075,6 +2078,17 @@ metaitem.terminal.tooltip.hardware=§aHardware: %d metaitem.wireless.name=Wireless Transmitter metaitem.camera.name=Camera +metaitem.plugin.tooltips.1=Plugins can be added to the screen for more functionality. +metaitem.plugin.proxy.tooltips.1=(Please adjust to proxy mode in the screen) +metaitem.plugin.text.name=Text Plugin +metaitem.plugin.online_pic.name=Online Picture Plugin +metaitem.plugin.fake_gui.name=GUI Proxy Plugin +metaitem.plugin.advanced_monitor.name=Advanced Monitor Proxy Plugin +metaitem.cover.digital.name=Digital Interface Cover +metaitem.cover.digital.wireless.name=Wireless Digital Interface Cover +metaitem.coloured.leds.name=Coloured LEDs +metaitem.display.name=Display + tile.casing.ulv=ULV Machine Casing tile.casing.lv=LV Machine Casing tile.casing.mv=MV Machine Casing @@ -3590,6 +3604,23 @@ gregtech.machine.miner.overclock=Requires §e%s§7 power. Overclocks up to §e%s gregtech.machine.large_chemical_reactor.name=Large Chemical Reactor +gregtech.machine.central_monitor.name=Central Monitor +gregtech.multiblock.central_monitor.low_power=Low Power +gregtech.multiblock.central_monitor.height=Screen Height: +gregtech.multiblock.central_monitor.width=Screen Width: %d +gregtech.multiblock.central_monitor.height_modify=Modify Height: %d +gregtech.multiblock.central_monitor.tooltip.1=This is a screen that monitors machines proxied by the Digital Interface Cover. You can easily monitor the Fluids, Items, Energy, and States of machines proxied in Energy Network. +gregtech.multiblock.central_monitor.tooltip.2=You can build the central monitor screen from 3X2 to %dX%d (width X height). +gregtech.multiblock.central_monitor.tooltip.3=The default height is 3. You can adjust the screen height in the GUI before the structure is formed. +gregtech.multiblock.central_monitor.tooltip.4=Energy consumption: %d EU/s for each screen. +gregtech.multiblock.monitor_screen.tooltip.1=The GUI can be opened with a right-click of a screwdriver. +gregtech.multiblock.monitor_screen.tooltip.2=The proxy mode of Digital Interface Cover can delegate machines' capabilities and GUI. (Yes, you can connect pipes directly on the screen.) +gregtech.multiblock.monitor_screen.tooltip.3=The screen also supports plugins. + + +gregtech.machine.monitor_screen.name=Monitor Screen + + # Multiblock Tooltips gregtech.machine.primitive_blast_furnace.bronze.tooltip=Structure: 3x3x4 (WxLxH) The entire structure is made out of Primitive Bricks (32 in total)./nFirst Layer is a 3x3 square./nSecond, third, and fourth layers are hollow, without the middle block./nThis block goes on the middle of any side in the second layer./nThe sides of Blast Furnaces can be shared, if the side does not have a controller./n gregtech.machine.multiblock.universal.controller_information=Controller block for the §e%s§7. @@ -4178,3 +4209,15 @@ terminal.world_prospector.color=Select box color terminal.vtank_viewer.description=Never lose any fluids to changing ender link frequencies again! Here's a scrollable list of every virtual tank that you have access to in your world. terminal.vtank_viewer.title=Virtual Tank Viewer terminal.vtank_viewer.refresh=Refresh tank index + +metaitem.cover.digital.title.mode=Mode: +metaitem.cover.digital.title.spin=Spin: +metaitem.cover.digital.wireless.tooltip.1=§eRight click on the central monitor to bind remotely to it. +metaitem.cover.digital.wireless.tooltip.2=§eShift Right click to remove the current binding. +metaitem.cover.digital.wireless.tooltip.3=§cBinding: (%s) +monitor.gui.title.back=Back +monitor.gui.title.scale=Scale: +monitor.gui.title.argb=ARGB: +monitor.gui.title.slot=Slot: +monitor.gui.title.plugin=Plugin: +monitor.gui.title.config=Config diff --git a/src/main/resources/assets/gregtech/models/item/metaitems/coloured.leds.json b/src/main/resources/assets/gregtech/models/item/metaitems/coloured.leds.json new file mode 100644 index 00000000000..171ec957f56 --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/metaitems/coloured.leds.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "gregtech:items/metaitems/coloured.leds" + } +} diff --git a/src/main/resources/assets/gregtech/models/item/metaitems/cover.digital.json b/src/main/resources/assets/gregtech/models/item/metaitems/cover.digital.json new file mode 100644 index 00000000000..fe6f7ce9aac --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/metaitems/cover.digital.json @@ -0,0 +1,7 @@ + +{ + "parent": "item/generated", + "textures": { + "layer0": "gregtech:items/metaitems/cover.digital.interface" + } +} diff --git a/src/main/resources/assets/gregtech/models/item/metaitems/cover.digital.wireless.json b/src/main/resources/assets/gregtech/models/item/metaitems/cover.digital.wireless.json new file mode 100644 index 00000000000..fd9a874b9c6 --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/metaitems/cover.digital.wireless.json @@ -0,0 +1,7 @@ + +{ + "parent": "item/generated", + "textures": { + "layer0": "gregtech:items/metaitems/cover.digital.interface.wireless" + } +} diff --git a/src/main/resources/assets/gregtech/models/item/metaitems/display.json b/src/main/resources/assets/gregtech/models/item/metaitems/display.json new file mode 100644 index 00000000000..47f002a0c1c --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/metaitems/display.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "gregtech:items/metaitems/display" + } +} diff --git a/src/main/resources/assets/gregtech/models/item/metaitems/plugin.advanced_monitor.json b/src/main/resources/assets/gregtech/models/item/metaitems/plugin.advanced_monitor.json new file mode 100644 index 00000000000..bdc7e2641c8 --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/metaitems/plugin.advanced_monitor.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "gregtech:items/metaitems/plugin.advanced_monitor" + } +} diff --git a/src/main/resources/assets/gregtech/models/item/metaitems/plugin.fake_gui.json b/src/main/resources/assets/gregtech/models/item/metaitems/plugin.fake_gui.json new file mode 100644 index 00000000000..2ccc7a013bc --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/metaitems/plugin.fake_gui.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "gregtech:items/metaitems/plugin.fake_gui" + } +} diff --git a/src/main/resources/assets/gregtech/models/item/metaitems/plugin.online_pic.json b/src/main/resources/assets/gregtech/models/item/metaitems/plugin.online_pic.json new file mode 100644 index 00000000000..afdf658c985 --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/metaitems/plugin.online_pic.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "gregtech:items/metaitems/plugin.online_pic" + } +} diff --git a/src/main/resources/assets/gregtech/models/item/metaitems/plugin.text.json b/src/main/resources/assets/gregtech/models/item/metaitems/plugin.text.json new file mode 100644 index 00000000000..60fe2a72235 --- /dev/null +++ b/src/main/resources/assets/gregtech/models/item/metaitems/plugin.text.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "gregtech:items/metaitems/plugin.text" + } +} diff --git a/src/main/resources/assets/gregtech/shaders/bloom_combine.frag b/src/main/resources/assets/gregtech/shaders/bloom_combine.frag index a0028cef8e1..406a3a4692b 100644 --- a/src/main/resources/assets/gregtech/shaders/bloom_combine.frag +++ b/src/main/resources/assets/gregtech/shaders/bloom_combine.frag @@ -1,13 +1,12 @@ -#version 140 +#version 120 -in vec2 textureCoords; +varying vec2 textureCoords; -out vec4 out_colour; uniform sampler2D buffer_a; uniform sampler2D buffer_b; uniform float intensive; void main(void){ - out_colour = vec4(texture(buffer_a, textureCoords).rgb + texture(buffer_b, textureCoords).rgb * intensive, 1.); + gl_FragColor = vec4(texture2D(buffer_a, textureCoords).rgb + texture2D(buffer_b, textureCoords).rgb * intensive, 1.); } diff --git a/src/main/resources/assets/gregtech/shaders/blur.frag b/src/main/resources/assets/gregtech/shaders/blur.frag index 0780ff74c4a..1d4ed5c2879 100644 --- a/src/main/resources/assets/gregtech/shaders/blur.frag +++ b/src/main/resources/assets/gregtech/shaders/blur.frag @@ -1,8 +1,6 @@ -#version 140 +#version 120 -in vec2 textureCoords; - -out vec4 out_colour; +varying vec2 textureCoords; uniform sampler2D originalTexture; uniform vec2 u_resolution; @@ -10,18 +8,18 @@ uniform vec2 blurDir; void main(void){ vec2 pixelSize = blurDir.xy / u_resolution.xy; - out_colour = vec4(0.0); + vec4 out_colour = vec4(0.0); - out_colour += texture(originalTexture, textureCoords + pixelSize * -5.) * 0.0093; - out_colour += texture(originalTexture, textureCoords + pixelSize * -4.) * 0.028002; - out_colour += texture(originalTexture, textureCoords + pixelSize * -3.) * 0.065984; - out_colour += texture(originalTexture, textureCoords + pixelSize * -2.) * 0.121703; - out_colour += texture(originalTexture, textureCoords + pixelSize * -1.) * 0.175713; - out_colour += texture(originalTexture, textureCoords + pixelSize * 0.) * 0.198596; - out_colour += texture(originalTexture, textureCoords + pixelSize * 1.) * 0.175713; - out_colour += texture(originalTexture, textureCoords + pixelSize * 2.) * 0.121703; - out_colour += texture(originalTexture, textureCoords + pixelSize * 3.) * 0.065984; - out_colour += texture(originalTexture, textureCoords + pixelSize * 4.) * 0.028002; - out_colour += texture(originalTexture, textureCoords + pixelSize * 5.) * 0.0093; - out_colour = vec4(out_colour.rgb, 1.); + out_colour += texture2D(originalTexture, textureCoords + pixelSize * -5.) * 0.0093; + out_colour += texture2D(originalTexture, textureCoords + pixelSize * -4.) * 0.028002; + out_colour += texture2D(originalTexture, textureCoords + pixelSize * -3.) * 0.065984; + out_colour += texture2D(originalTexture, textureCoords + pixelSize * -2.) * 0.121703; + out_colour += texture2D(originalTexture, textureCoords + pixelSize * -1.) * 0.175713; + out_colour += texture2D(originalTexture, textureCoords + pixelSize * 0.) * 0.198596; + out_colour += texture2D(originalTexture, textureCoords + pixelSize * 1.) * 0.175713; + out_colour += texture2D(originalTexture, textureCoords + pixelSize * 2.) * 0.121703; + out_colour += texture2D(originalTexture, textureCoords + pixelSize * 3.) * 0.065984; + out_colour += texture2D(originalTexture, textureCoords + pixelSize * 4.) * 0.028002; + out_colour += texture2D(originalTexture, textureCoords + pixelSize * 5.) * 0.0093; + gl_FragColor = vec4(out_colour.rgb, 1.); } diff --git a/src/main/resources/assets/gregtech/shaders/composite.frag b/src/main/resources/assets/gregtech/shaders/composite.frag index 8fde0ac795f..22cbfb9361e 100644 --- a/src/main/resources/assets/gregtech/shaders/composite.frag +++ b/src/main/resources/assets/gregtech/shaders/composite.frag @@ -1,8 +1,6 @@ -#version 140 +#version 120 -in vec2 textureCoords; - -out vec4 out_colour; +varying vec2 textureCoords; uniform sampler2D blurTexture1; uniform sampler2D blurTexture2; @@ -19,9 +17,9 @@ float lerpBloomFactor(const in float factor) { return mix(factor, mirrorFactor, bloomRadius); } void main() { - out_colour = bloomStrength * ( lerpBloomFactor(1.) * texture(blurTexture1, textureCoords) + - lerpBloomFactor(0.8) * texture(blurTexture2, textureCoords) + - lerpBloomFactor(0.6) * texture(blurTexture3, textureCoords) + - lerpBloomFactor(0.4) * texture(blurTexture4, textureCoords) + - lerpBloomFactor(0.2) * texture(blurTexture5, textureCoords) ); + gl_FragColor = bloomStrength * ( lerpBloomFactor(1.) * texture2D(blurTexture1, textureCoords) + + lerpBloomFactor(0.8) * texture2D(blurTexture2, textureCoords) + + lerpBloomFactor(0.6) * texture2D(blurTexture3, textureCoords) + + lerpBloomFactor(0.4) * texture2D(blurTexture4, textureCoords) + + lerpBloomFactor(0.2) * texture2D(blurTexture5, textureCoords) ); } diff --git a/src/main/resources/assets/gregtech/shaders/down_sampling.frag b/src/main/resources/assets/gregtech/shaders/down_sampling.frag index e3cf023a866..719a0d660c0 100644 --- a/src/main/resources/assets/gregtech/shaders/down_sampling.frag +++ b/src/main/resources/assets/gregtech/shaders/down_sampling.frag @@ -1,25 +1,23 @@ -#version 140 +#version 120 -in vec2 textureCoords; - -out vec4 out_colour; +varying vec2 textureCoords; uniform sampler2D originalTexture; uniform vec2 u_resolution; uniform vec2 u_resolution2; vec4 four_k(vec3 textel, vec2 uv) { - return (texture(originalTexture, uv + textel.xx) //1 1 - + texture(originalTexture, uv + textel.xy) // 1 -1 - + texture(originalTexture, uv + textel.yx) // -1 1 - + texture(originalTexture, uv + textel.yy)) * 0.25; // -1 -1 + return (texture2D(originalTexture, uv + textel.xx) //1 1 + + texture2D(originalTexture, uv + textel.xy) // 1 -1 + + texture2D(originalTexture, uv + textel.yx) // -1 1 + + texture2D(originalTexture, uv + textel.yy)) * 0.25; // -1 -1 } void main(void) { vec3 textel1 = vec3(1., -1., 0.) / u_resolution2.xyx; vec3 textel2 = vec3(1., -1., 0.) / u_resolution.xyx; - out_colour = (four_k(textel1, textureCoords + textel2.yy) + vec4 out_colour = (four_k(textel1, textureCoords + textel2.yy) + four_k(textel1, textureCoords + textel2.zy) + four_k(textel1, textureCoords + textel2.yz) + four_k(textel1, textureCoords)) * 0.25 * 0.125; @@ -44,5 +42,5 @@ void main(void) { + four_k(textel1, textureCoords + textel1.yx) + four_k(textel1, textureCoords + textel1.yy)) * 0.25 * 0.5; - out_colour = vec4(out_colour.rgb, 1.); + gl_FragColor = vec4(out_colour.rgb, 1.); } diff --git a/src/main/resources/assets/gregtech/shaders/image.frag b/src/main/resources/assets/gregtech/shaders/image.frag index a847f21e5c6..32a8d800fe5 100644 --- a/src/main/resources/assets/gregtech/shaders/image.frag +++ b/src/main/resources/assets/gregtech/shaders/image.frag @@ -1,13 +1,11 @@ -#version 140 +#version 120 -in vec2 textureCoords; - -out vec4 out_Colour; +varying vec2 textureCoords; uniform sampler2D colourTexture; void main(void){ - out_Colour = texture(colourTexture, textureCoords).rgba; + gl_FragColor = texture2D(colourTexture, textureCoords).rgba; } diff --git a/src/main/resources/assets/gregtech/shaders/image.vert b/src/main/resources/assets/gregtech/shaders/image.vert index 0705737c921..879ace44f6b 100644 --- a/src/main/resources/assets/gregtech/shaders/image.vert +++ b/src/main/resources/assets/gregtech/shaders/image.vert @@ -1,8 +1,8 @@ -#version 140 +#version 120 -in vec2 position; +attribute vec2 position; -out vec2 textureCoords; +varying vec2 textureCoords; void main(void){ gl_Position = vec4(position, 0.0, 1.0); diff --git a/src/main/resources/assets/gregtech/shaders/scanning.frag b/src/main/resources/assets/gregtech/shaders/scanning.frag index 063c0382884..3a01011c3f7 100644 --- a/src/main/resources/assets/gregtech/shaders/scanning.frag +++ b/src/main/resources/assets/gregtech/shaders/scanning.frag @@ -1,4 +1,4 @@ -#version 130 +#version 120 uniform float u_time; uniform float radius; @@ -9,7 +9,7 @@ uniform vec2 u_resolution; uniform float u_zFar; // mc.gameSettings.renderDistanceChunks * 16 * MathHelper.SQRT_2 uniform float u_FOV; -in vec2 textureCoords; +varying vec2 textureCoords; const float zNear = 0.05; // default of entity view const float width = 10; diff --git a/src/main/resources/assets/gregtech/shaders/seperable_blur.frag b/src/main/resources/assets/gregtech/shaders/seperable_blur.frag index 6da7669a664..f8b457e9f19 100644 --- a/src/main/resources/assets/gregtech/shaders/seperable_blur.frag +++ b/src/main/resources/assets/gregtech/shaders/seperable_blur.frag @@ -1,8 +1,6 @@ -#version 140 +#version 120 -in vec2 textureCoords; - -out vec4 out_colour; +varying vec2 textureCoords; uniform sampler2D colorTexture; uniform vec2 u_resolution; @@ -19,15 +17,15 @@ void main(void){ vec2 invSize = 1.0 / texSize; float fSigma = float(kernel_radius); float weightSum = gaussianPdf(0.0, fSigma); - vec3 diffuseSum = texture(colorTexture, textureCoords).rgb * weightSum; + vec3 diffuseSum = texture2D(colorTexture, textureCoords).rgb * weightSum; for( int i = 1; i < kernel_radius; i ++ ) { float x = float(i); float w = gaussianPdf(x, fSigma); vec2 uvOffset = blurDir * invSize * x; - vec3 sample1 = texture(colorTexture, textureCoords + uvOffset).rgb; - vec3 sample2 = texture(colorTexture, textureCoords - uvOffset).rgb; + vec3 sample1 = texture2D(colorTexture, textureCoords + uvOffset).rgb; + vec3 sample2 = texture2D(colorTexture, textureCoords - uvOffset).rgb; diffuseSum += (sample1 + sample2) * w; weightSum += 2.0 * w; } - out_colour = vec4(diffuseSum/weightSum, 1.0); + gl_FragColor = vec4(diffuseSum/weightSum, 1.0); } diff --git a/src/main/resources/assets/gregtech/shaders/up_sampling.frag b/src/main/resources/assets/gregtech/shaders/up_sampling.frag index 57a4144bf97..c43dc50a0f0 100644 --- a/src/main/resources/assets/gregtech/shaders/up_sampling.frag +++ b/src/main/resources/assets/gregtech/shaders/up_sampling.frag @@ -1,8 +1,6 @@ -#version 140 +#version 120 -in vec2 textureCoords; - -out vec4 out_colour; +varying vec2 textureCoords; uniform sampler2D upTexture; uniform sampler2D downTexture; @@ -10,29 +8,29 @@ uniform vec2 u_resolution; uniform vec2 u_resolution2; vec4 four_k(vec3 textel, vec2 uv) { - return (texture(upTexture, uv + textel.xx) //1 1 - + texture(upTexture, uv + textel.xy) // 1 -1 - + texture(upTexture, uv + textel.yx) // -1 1 - + texture(upTexture, uv + textel.yy)) * 0.25; // -1 -1 + return (texture2D(upTexture, uv + textel.xx) //1 1 + + texture2D(upTexture, uv + textel.xy) // 1 -1 + + texture2D(upTexture, uv + textel.yx) // -1 1 + + texture2D(upTexture, uv + textel.yy)) * 0.25; // -1 -1 } vec4 up_sampling(vec3 textel, vec2 uv) { - return vec4(four_k(textel, uv).rgb + texture(downTexture, uv).rgb, 1.); + return vec4(four_k(textel, uv).rgb + texture2D(downTexture, uv).rgb, 1.); } void main(void) { vec3 textel = vec3(1., -1., 0.) / u_resolution.xyx; // out_colour = up_sampling(textel, textureCoords); - out_colour = texture(upTexture, textureCoords + textel.xx); - out_colour += texture(upTexture, textureCoords + textel.xz) * 2.0; - out_colour += texture(upTexture, textureCoords + textel.xy); - out_colour += texture(upTexture, textureCoords + textel.yz) * 2.0; - out_colour += texture(upTexture, textureCoords) * 4.0; - out_colour += texture(upTexture, textureCoords + textel.zx) * 2.0; - out_colour += texture(upTexture, textureCoords + textel.yy); - out_colour += texture(upTexture, textureCoords + textel.zy) * 2.0; - out_colour += texture(upTexture, textureCoords + textel.yx); - - out_colour = vec4(out_colour.rgb * 0.8 / 16. + texture(downTexture, textureCoords).rgb * 0.8, 1.); + vec4 out_colour = texture2D(upTexture, textureCoords + textel.xx); + out_colour += texture2D(upTexture, textureCoords + textel.xz) * 2.0; + out_colour += texture2D(upTexture, textureCoords + textel.xy); + out_colour += texture2D(upTexture, textureCoords + textel.yz) * 2.0; + out_colour += texture2D(upTexture, textureCoords) * 4.0; + out_colour += texture2D(upTexture, textureCoords + textel.zx) * 2.0; + out_colour += texture2D(upTexture, textureCoords + textel.yy); + out_colour += texture2D(upTexture, textureCoords + textel.zy) * 2.0; + out_colour += texture2D(upTexture, textureCoords + textel.yx); + + gl_FragColor = vec4(out_colour.rgb * 0.8 / 16. + texture2D(downTexture, textureCoords).rgb * 0.8, 1.); } diff --git a/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_computer_button.png b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_computer_button.png new file mode 100644 index 00000000000..667427c2109 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_computer_button.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_energy.png b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_energy.png new file mode 100644 index 00000000000..2b865c2fc51 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_energy.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_energy_button.png b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_energy_button.png new file mode 100644 index 00000000000..06ba9e7b55e Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_energy_button.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_fluid.png b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_fluid.png new file mode 100644 index 00000000000..ecdf5d3f50e Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_fluid.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_fluid_button.png b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_fluid_button.png new file mode 100644 index 00000000000..8e73d7ee037 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_fluid_button.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_fluid_glass.png b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_fluid_glass.png new file mode 100644 index 00000000000..58e94d00bc6 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_fluid_glass.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_item.png b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_item.png new file mode 100644 index 00000000000..756d263314c Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_item.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_item_button.png b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_item_button.png new file mode 100644 index 00000000000..641e36ff1df Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_item_button.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_machine_button.png b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_machine_button.png new file mode 100644 index 00000000000..2093fb61552 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_machine_button.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_machine_off.png b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_machine_off.png new file mode 100644 index 00000000000..299897252dc Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_machine_off.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_machine_off_proxy.png b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_machine_off_proxy.png new file mode 100644 index 00000000000..f76533e9ad8 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_machine_off_proxy.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_machine_on.png b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_machine_on.png new file mode 100644 index 00000000000..2a8e4c399d4 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_machine_on.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_machine_on_proxy.png b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_machine_on_proxy.png new file mode 100644 index 00000000000..fa633e046dd Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_machine_on_proxy.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_proxy.png b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_proxy.png new file mode 100644 index 00000000000..c20c3c884ab Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_proxy.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_proxy_emissive.png b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_proxy_emissive.png new file mode 100644 index 00000000000..6072b6ce410 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_proxy_emissive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_proxy_emissive.png.mcmeta b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_proxy_emissive.png.mcmeta new file mode 100644 index 00000000000..60af678259b --- /dev/null +++ b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_proxy_emissive.png.mcmeta @@ -0,0 +1,5 @@ +{ + "animation":{ + "frametime":4 + } +} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_wireless.png b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_wireless.png new file mode 100644 index 00000000000..c9b8df5797b Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_wireless.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_wireless_emissive.png b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_wireless_emissive.png new file mode 100644 index 00000000000..56f6cced60e Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_wireless_emissive.png differ diff --git a/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_wireless_emissive.png.mcmeta b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_wireless_emissive.png.mcmeta new file mode 100644 index 00000000000..5e86a7cd5fb --- /dev/null +++ b/src/main/resources/assets/gregtech/textures/blocks/cover/cover_interface_wireless_emissive.png.mcmeta @@ -0,0 +1,5 @@ +{ + "animation":{ + "frametime":8 + } +} \ No newline at end of file diff --git a/src/main/resources/assets/gregtech/textures/items/metaitems/coloured.leds.png b/src/main/resources/assets/gregtech/textures/items/metaitems/coloured.leds.png new file mode 100644 index 00000000000..f35ac3f5dd3 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/metaitems/coloured.leds.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/metaitems/cover.digital.interface.png b/src/main/resources/assets/gregtech/textures/items/metaitems/cover.digital.interface.png new file mode 100644 index 00000000000..13124e56779 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/metaitems/cover.digital.interface.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/metaitems/cover.digital.interface.wireless.png b/src/main/resources/assets/gregtech/textures/items/metaitems/cover.digital.interface.wireless.png new file mode 100644 index 00000000000..df58125ab35 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/metaitems/cover.digital.interface.wireless.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/metaitems/display.png b/src/main/resources/assets/gregtech/textures/items/metaitems/display.png new file mode 100644 index 00000000000..691efd8a842 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/metaitems/display.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/metaitems/plugin.advanced_monitor.png b/src/main/resources/assets/gregtech/textures/items/metaitems/plugin.advanced_monitor.png new file mode 100644 index 00000000000..81c7bd58847 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/metaitems/plugin.advanced_monitor.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/metaitems/plugin.fake_gui.png b/src/main/resources/assets/gregtech/textures/items/metaitems/plugin.fake_gui.png new file mode 100644 index 00000000000..defeff13d80 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/metaitems/plugin.fake_gui.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/metaitems/plugin.online_pic.png b/src/main/resources/assets/gregtech/textures/items/metaitems/plugin.online_pic.png new file mode 100644 index 00000000000..8b532f20234 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/metaitems/plugin.online_pic.png differ diff --git a/src/main/resources/assets/gregtech/textures/items/metaitems/plugin.text.png b/src/main/resources/assets/gregtech/textures/items/metaitems/plugin.text.png new file mode 100644 index 00000000000..ad997f1a0ab Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/items/metaitems/plugin.text.png differ diff --git a/src/test/java/gregtech/api/capability/impl/AbstractRecipeLogicTest.java b/src/test/java/gregtech/api/capability/impl/AbstractRecipeLogicTest.java index 69edae824b8..28684113f96 100644 --- a/src/test/java/gregtech/api/capability/impl/AbstractRecipeLogicTest.java +++ b/src/test/java/gregtech/api/capability/impl/AbstractRecipeLogicTest.java @@ -60,6 +60,11 @@ public void trySearchNewRecipe() { .buildAndRegister(); AbstractRecipeLogic arl = new AbstractRecipeLogic(atte, map) { + @Override + protected long getEnergyInputPerSecond() { + return Long.MAX_VALUE; + } + @Override protected long getEnergyStored() { return Long.MAX_VALUE;