removed debug
This commit is contained in:
parent
0ca9680fb2
commit
676ce13d34
5 changed files with 311 additions and 25 deletions
BIN
resources/assets/dark/textures/gui/gui_coder_icons.png
Normal file
BIN
resources/assets/dark/textures/gui/gui_coder_icons.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8 KiB |
|
@ -1,6 +1,11 @@
|
|||
package dark.core.client.gui;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL12;
|
||||
|
||||
import cpw.mods.fml.client.FMLClientHandler;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.client.renderer.RenderHelper;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import dark.core.common.DarkMain;
|
||||
|
@ -9,7 +14,7 @@ import dark.core.prefab.invgui.GuiButtonImage;
|
|||
import dark.core.prefab.machine.TileEntityMachine;
|
||||
|
||||
/** To be used with all machine that have a gui to allow generic settings and feature all all devices
|
||||
*
|
||||
*
|
||||
* @author DarkGuardsman */
|
||||
public class GuiMachineBase extends GuiBase
|
||||
{
|
||||
|
@ -19,12 +24,16 @@ public class GuiMachineBase extends GuiBase
|
|||
protected static final int MAX_BUTTON_ID = 3;
|
||||
protected TileEntityMachine tileEntity;
|
||||
protected EntityPlayer entityPlayer;
|
||||
protected Object mod;
|
||||
protected int guiID = -1, guiID2 = -1, guiID3 = -1;
|
||||
protected String invName = "Home", invName2 = "2", invName3 = "3";
|
||||
|
||||
public GuiMachineBase(EntityPlayer player, TileEntityMachine tileEntity)
|
||||
public GuiMachineBase(Object mod, EntityPlayer player, TileEntityMachine tileEntity)
|
||||
{
|
||||
this.tileEntity = tileEntity;
|
||||
this.entityPlayer = player;
|
||||
this.guiSize.y = 380 / 2;
|
||||
this.mod = mod;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -32,12 +41,17 @@ public class GuiMachineBase extends GuiBase
|
|||
{
|
||||
super.initGui();
|
||||
this.buttonList.clear();
|
||||
|
||||
// Inventory, Should be the Gui the machine opens to unless it has no inventory
|
||||
this.buttonList.add(new GuiButtonImage(0, (this.width - this.guiSize.intX()) / 2 - 22, (this.height - this.guiSize.intY()) / 2 + 0, 3));
|
||||
if (guiID != -1)
|
||||
this.buttonList.add(new GuiButtonImage(0, (this.width - this.guiSize.intX()) / 2 - 22, (this.height - this.guiSize.intY()) / 2 + 0, 3));
|
||||
|
||||
// Machine settings
|
||||
this.buttonList.add(new GuiButtonImage(1, (this.width - this.guiSize.intX()) / 2 - 22, (this.height - this.guiSize.intY()) / 2 + 22, 0));
|
||||
// About page, should display information about the machines power needs, help information, and tips
|
||||
this.buttonList.add(new GuiButtonImage(2, (this.width - this.guiSize.intX()) / 2 - 22, (this.height - this.guiSize.intY()) / 2 + 44, 2));
|
||||
if (guiID2 != -1)
|
||||
this.buttonList.add(new GuiButtonImage(1, (this.width - this.guiSize.intX()) / 2 - 22, (this.height - this.guiSize.intY()) / 2 + 22, 0));
|
||||
|
||||
if (guiID3 != -1)
|
||||
this.buttonList.add(new GuiButtonImage(2, (this.width - this.guiSize.intX()) / 2 - 22, (this.height - this.guiSize.intY()) / 2 + 44, 2));
|
||||
|
||||
}
|
||||
|
||||
|
@ -48,34 +62,126 @@ public class GuiMachineBase extends GuiBase
|
|||
{
|
||||
case 0:
|
||||
{
|
||||
//TODO open main GUI
|
||||
if (guiID != -1)
|
||||
entityPlayer.openGui(mod, guiID, tileEntity.worldObj, tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
//TODO open second GUI
|
||||
if (guiID2 != -1)
|
||||
entityPlayer.openGui(mod, guiID2, tileEntity.worldObj, tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
//TODO open third GUI
|
||||
if (guiID3 != -1)
|
||||
entityPlayer.openGui(mod, guiID3, tileEntity.worldObj, tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Draw the foreground layer for the GuiContainer (everything in front of the items) */
|
||||
@Override
|
||||
protected void drawForegroundLayer(int var2, int var3, float var1)
|
||||
protected void drawForegroundLayer(int x, int y, float var1)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
this.fontRenderer.drawString("\u00a77" + tileEntity.getInvName(), (int) (this.guiSize.intX() / 2 - 7 * 2.5), 4, 4210752);
|
||||
/** Render Tool Tips */
|
||||
if (((GuiButtonImage) this.buttonList.get(0)).isIntersect(x, y) && guiID != -1)
|
||||
{
|
||||
this.drawTooltip(x - this.guiTopLeftCorner.intX(), y - this.guiTopLeftCorner.intY() + 10, invName);
|
||||
}
|
||||
else if (((GuiButtonImage) this.buttonList.get(1)).isIntersect(x, y) && guiID2 != -1)
|
||||
{
|
||||
this.drawTooltip(x - this.guiTopLeftCorner.intX(), y - this.guiTopLeftCorner.intY() + 10, invName2);
|
||||
}
|
||||
else if (((GuiButtonImage) this.buttonList.get(2)).isIntersect(x, y) && guiID3 != -1)
|
||||
{
|
||||
this.drawTooltip(x - this.guiTopLeftCorner.intX(), y - this.guiTopLeftCorner.intY() + 10, invName3);
|
||||
}
|
||||
}
|
||||
|
||||
/** Draw the background layer for the GuiContainer (everything behind the items) */
|
||||
@Override
|
||||
protected void drawBackgroundLayer(int x, int y, float var1)
|
||||
{
|
||||
FMLClientHandler.instance().getClient().renderEngine.bindTexture(TEXTURE);
|
||||
|
||||
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
|
||||
int containerWidth = (this.width - this.guiSize.intX()) / 2;
|
||||
int containerHeight = (this.height - this.guiSize.intY()) / 2;
|
||||
this.drawTexturedModalRect(containerWidth, containerHeight, 0, 0, this.guiSize.intX(), this.guiSize.intY());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawBackgroundLayer(int var2, int var3, float var1)
|
||||
public void drawTooltip(int x, int y, String... toolTips)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
GL11.glDisable(GL12.GL_RESCALE_NORMAL);
|
||||
RenderHelper.disableStandardItemLighting();
|
||||
GL11.glDisable(GL11.GL_LIGHTING);
|
||||
GL11.glDisable(GL11.GL_DEPTH_TEST);
|
||||
|
||||
if (toolTips != null)
|
||||
{
|
||||
int var5 = 0;
|
||||
int var6;
|
||||
int var7;
|
||||
|
||||
for (var6 = 0; var6 < toolTips.length; ++var6)
|
||||
{
|
||||
var7 = this.fontRenderer.getStringWidth(toolTips[var6]);
|
||||
|
||||
if (var7 > var5)
|
||||
{
|
||||
var5 = var7;
|
||||
}
|
||||
}
|
||||
|
||||
var6 = x + 12;
|
||||
var7 = y - 12;
|
||||
int var9 = 8;
|
||||
|
||||
if (toolTips.length > 1)
|
||||
{
|
||||
var9 += 2 + (toolTips.length - 1) * 10;
|
||||
}
|
||||
|
||||
if (this.guiTopLeftCorner.intY() + var7 + var9 + 6 > this.height)
|
||||
{
|
||||
var7 = this.height - var9 - this.guiTopLeftCorner.intY() - 6;
|
||||
}
|
||||
|
||||
this.zLevel = 300.0F;
|
||||
int var10 = -267386864;
|
||||
this.drawGradientRect(var6 - 3, var7 - 4, var6 + var5 + 3, var7 - 3, var10, var10);
|
||||
this.drawGradientRect(var6 - 3, var7 + var9 + 3, var6 + var5 + 3, var7 + var9 + 4, var10, var10);
|
||||
this.drawGradientRect(var6 - 3, var7 - 3, var6 + var5 + 3, var7 + var9 + 3, var10, var10);
|
||||
this.drawGradientRect(var6 - 4, var7 - 3, var6 - 3, var7 + var9 + 3, var10, var10);
|
||||
this.drawGradientRect(var6 + var5 + 3, var7 - 3, var6 + var5 + 4, var7 + var9 + 3, var10, var10);
|
||||
int var11 = 1347420415;
|
||||
int var12 = (var11 & 16711422) >> 1 | var11 & -16777216;
|
||||
this.drawGradientRect(var6 - 3, var7 - 3 + 1, var6 - 3 + 1, var7 + var9 + 3 - 1, var11, var12);
|
||||
this.drawGradientRect(var6 + var5 + 2, var7 - 3 + 1, var6 + var5 + 3, var7 + var9 + 3 - 1, var11, var12);
|
||||
this.drawGradientRect(var6 - 3, var7 - 3, var6 + var5 + 3, var7 - 3 + 1, var11, var11);
|
||||
this.drawGradientRect(var6 - 3, var7 + var9 + 2, var6 + var5 + 3, var7 + var9 + 3, var12, var12);
|
||||
|
||||
for (int var13 = 0; var13 < toolTips.length; ++var13)
|
||||
{
|
||||
String var14 = "\u00a77" + toolTips[var13];
|
||||
|
||||
this.fontRenderer.drawStringWithShadow(var14, var6, var7, -1);
|
||||
|
||||
if (var13 == 0)
|
||||
{
|
||||
var7 += 2;
|
||||
}
|
||||
|
||||
var7 += 10;
|
||||
}
|
||||
|
||||
this.zLevel = 0.0F;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
181
src/dark/core/client/gui/GuiMachineContainer.java
Normal file
181
src/dark/core/client/gui/GuiMachineContainer.java
Normal file
|
@ -0,0 +1,181 @@
|
|||
package dark.core.client.gui;
|
||||
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.client.renderer.RenderHelper;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.inventory.Container;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL12;
|
||||
|
||||
import cpw.mods.fml.client.FMLClientHandler;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import dark.core.prefab.invgui.GuiButtonImage;
|
||||
import dark.core.prefab.machine.TileEntityMachine;
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public abstract class GuiMachineContainer extends GuiContainer
|
||||
{
|
||||
protected static final int MAX_BUTTON_ID = 3;
|
||||
protected TileEntityMachine tileEntity;
|
||||
protected EntityPlayer entityPlayer;
|
||||
protected Object mod;
|
||||
protected int guiID = -1, guiID2 = -1, guiID3 = -1;
|
||||
protected String invName = "Home", invName2 = "2", invName3 = "3";
|
||||
|
||||
public GuiMachineContainer(Object mod, Container container, InventoryPlayer inventoryPlayer, TileEntityMachine tileEntity)
|
||||
{
|
||||
super(container);
|
||||
this.tileEntity = tileEntity;
|
||||
this.entityPlayer = inventoryPlayer.player;
|
||||
this.ySize = 380 / 2;
|
||||
this.mod = mod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initGui()
|
||||
{
|
||||
super.initGui();
|
||||
this.buttonList.clear();
|
||||
|
||||
if (guiID != -1)
|
||||
this.buttonList.add(new GuiButtonImage(0, (this.width - this.xSize) / 2 - 22, (this.height - this.ySize) / 2 + 0, 3));
|
||||
if (guiID2 != -1)
|
||||
this.buttonList.add(new GuiButtonImage(1, (this.width - this.xSize) / 2 - 22, (this.height - this.ySize) / 2 + 22, 0));
|
||||
if (guiID3 != -1)
|
||||
this.buttonList.add(new GuiButtonImage(2, (this.width - this.xSize) / 2 - 22, (this.height - this.ySize) / 2 + 44, 2));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void actionPerformed(GuiButton button)
|
||||
{
|
||||
switch (button.id)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
if (guiID != -1)
|
||||
this.entityPlayer.openGui(mod, guiID, this.tileEntity.worldObj, this.tileEntity.xCoord, this.tileEntity.yCoord, this.tileEntity.zCoord);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
if (guiID2 != -1)
|
||||
this.entityPlayer.openGui(mod, guiID2, this.tileEntity.worldObj, this.tileEntity.xCoord, this.tileEntity.yCoord, this.tileEntity.zCoord);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
if (guiID3 != -1)
|
||||
this.entityPlayer.openGui(mod, guiID3, this.tileEntity.worldObj, this.tileEntity.xCoord, this.tileEntity.yCoord, this.tileEntity.zCoord);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Draw the foreground layer for the GuiContainer (everything in front of the items) */
|
||||
@Override
|
||||
protected void drawGuiContainerForegroundLayer(int x, int y)
|
||||
{
|
||||
this.fontRenderer.drawString("\u00a77" + tileEntity.getInvName(), (int) (this.xSize / 2 - 7 * 2.5), 4, 4210752);
|
||||
|
||||
/** Render Tool Tips */
|
||||
if (((GuiButtonImage) this.buttonList.get(0)).isIntersect(x, y))
|
||||
{
|
||||
this.drawTooltip(x - this.guiLeft, y - this.guiTop + 10, invName);
|
||||
}
|
||||
else if (((GuiButtonImage) this.buttonList.get(1)).isIntersect(x, y))
|
||||
{
|
||||
this.drawTooltip(x - this.guiLeft, y - this.guiTop + 10, invName2);
|
||||
}
|
||||
else if (((GuiButtonImage) this.buttonList.get(2)).isIntersect(x, y))
|
||||
{
|
||||
this.drawTooltip(x - this.guiLeft, y - this.guiTop + 10, invName3);
|
||||
}
|
||||
}
|
||||
|
||||
/** Draw the background layer for the GuiContainer (everything behind the items) */
|
||||
@Override
|
||||
protected void drawGuiContainerBackgroundLayer(float par1, int x, int y)
|
||||
{
|
||||
FMLClientHandler.instance().getClient().renderEngine.bindTexture(GuiMachineBase.TEXTURE);
|
||||
|
||||
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
|
||||
int containerWidth = (this.width - this.xSize) / 2;
|
||||
int containerHeight = (this.height - this.ySize) / 2;
|
||||
this.drawTexturedModalRect(containerWidth, containerHeight, 0, 0, this.xSize, this.ySize);
|
||||
}
|
||||
|
||||
public void drawTooltip(int x, int y, String... toolTips)
|
||||
{
|
||||
GL11.glDisable(GL12.GL_RESCALE_NORMAL);
|
||||
RenderHelper.disableStandardItemLighting();
|
||||
GL11.glDisable(GL11.GL_LIGHTING);
|
||||
GL11.glDisable(GL11.GL_DEPTH_TEST);
|
||||
|
||||
if (toolTips != null)
|
||||
{
|
||||
int var5 = 0;
|
||||
int var6;
|
||||
int var7;
|
||||
|
||||
for (var6 = 0; var6 < toolTips.length; ++var6)
|
||||
{
|
||||
var7 = this.fontRenderer.getStringWidth(toolTips[var6]);
|
||||
|
||||
if (var7 > var5)
|
||||
{
|
||||
var5 = var7;
|
||||
}
|
||||
}
|
||||
|
||||
var6 = x + 12;
|
||||
var7 = y - 12;
|
||||
int var9 = 8;
|
||||
|
||||
if (toolTips.length > 1)
|
||||
{
|
||||
var9 += 2 + (toolTips.length - 1) * 10;
|
||||
}
|
||||
|
||||
if (this.guiTop + var7 + var9 + 6 > this.height)
|
||||
{
|
||||
var7 = this.height - var9 - this.guiTop - 6;
|
||||
}
|
||||
|
||||
this.zLevel = 300.0F;
|
||||
int var10 = -267386864;
|
||||
this.drawGradientRect(var6 - 3, var7 - 4, var6 + var5 + 3, var7 - 3, var10, var10);
|
||||
this.drawGradientRect(var6 - 3, var7 + var9 + 3, var6 + var5 + 3, var7 + var9 + 4, var10, var10);
|
||||
this.drawGradientRect(var6 - 3, var7 - 3, var6 + var5 + 3, var7 + var9 + 3, var10, var10);
|
||||
this.drawGradientRect(var6 - 4, var7 - 3, var6 - 3, var7 + var9 + 3, var10, var10);
|
||||
this.drawGradientRect(var6 + var5 + 3, var7 - 3, var6 + var5 + 4, var7 + var9 + 3, var10, var10);
|
||||
int var11 = 1347420415;
|
||||
int var12 = (var11 & 16711422) >> 1 | var11 & -16777216;
|
||||
this.drawGradientRect(var6 - 3, var7 - 3 + 1, var6 - 3 + 1, var7 + var9 + 3 - 1, var11, var12);
|
||||
this.drawGradientRect(var6 + var5 + 2, var7 - 3 + 1, var6 + var5 + 3, var7 + var9 + 3 - 1, var11, var12);
|
||||
this.drawGradientRect(var6 - 3, var7 - 3, var6 + var5 + 3, var7 - 3 + 1, var11, var11);
|
||||
this.drawGradientRect(var6 - 3, var7 + var9 + 2, var6 + var5 + 3, var7 + var9 + 3, var12, var12);
|
||||
|
||||
for (int var13 = 0; var13 < toolTips.length; ++var13)
|
||||
{
|
||||
String var14 = "\u00a77" + toolTips[var13];
|
||||
|
||||
this.fontRenderer.drawStringWithShadow(var14, var6, var7, -1);
|
||||
|
||||
if (var13 == 0)
|
||||
{
|
||||
var7 += 2;
|
||||
}
|
||||
|
||||
var7 += 10;
|
||||
}
|
||||
|
||||
this.zLevel = 0.0F;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -75,9 +75,7 @@ public class RayTraceHelper
|
|||
@SuppressWarnings("unchecked")
|
||||
public static MovingObjectPosition raytraceEntities(World world, Vec3 start, Vec3 end, double range, boolean collisionFlag, Entity exclude)
|
||||
{
|
||||
AxisAlignedBB boxToScan = AxisAlignedBB.getBoundingBox(start.xCoord, start.yCoord, start.zCoord, end.xCoord, end.yCoord, end.zCoord);
|
||||
System.out.println("Start: " + start.toString());
|
||||
System.out.println("End: " + end.toString());
|
||||
AxisAlignedBB boxToScan = AxisAlignedBB.getBoundingBox(start.xCoord, start.yCoord, start.zCoord, end.xCoord, end.yCoord, end.zCoord);
|
||||
List<Entity> entitiesHit = null;
|
||||
if (exclude != null)
|
||||
{
|
||||
|
@ -95,18 +93,15 @@ public class RayTraceHelper
|
|||
return null;
|
||||
}
|
||||
for (Entity entityHit : entitiesHit)
|
||||
{
|
||||
System.out.println("---NextEntity" + entityHit.toString());
|
||||
{
|
||||
if (entityHit != null && entityHit.canBeCollidedWith() && entityHit.boundingBox != null)
|
||||
{
|
||||
System.out.println("---canCollide");
|
||||
{
|
||||
float border = entityHit.getCollisionBorderSize();
|
||||
AxisAlignedBB aabb = entityHit.boundingBox.expand(border, border, border);
|
||||
MovingObjectPosition hitMOP = aabb.calculateIntercept(start, end);
|
||||
|
||||
if (hitMOP != null)
|
||||
{
|
||||
System.out.println("---Hit");
|
||||
if (aabb.isVecInside(start))
|
||||
{
|
||||
if (0.0D < closestEntity || closestEntity == 0.0D)
|
||||
|
|
|
@ -30,12 +30,13 @@ import dark.core.registration.ModObjectRegistry.BlockBuildData;
|
|||
/** Basic TileEntity Container class designed to be used by generic machines. It is suggested that
|
||||
* each mod using this create there own basic block extending this to reduce need to use build data
|
||||
* per block.
|
||||
*
|
||||
*
|
||||
* @author Darkguardsman */
|
||||
public abstract class BlockMachine extends BlockTile implements IExtraBlockInfo
|
||||
{
|
||||
|
||||
public boolean zeroAnimation, zeroSound, zeroRendering;
|
||||
public int guiID = -1;
|
||||
|
||||
public BlockMachine(BlockBuildData data)
|
||||
{
|
||||
|
@ -112,7 +113,7 @@ public abstract class BlockMachine extends BlockTile implements IExtraBlockInfo
|
|||
super.breakBlock(world, x, y, z, par5, par6);
|
||||
world.notifyBlockChange(x, y, z, world.getBlockId(x, y, z));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getComparatorInputOverride(World world, int x, int y, int z, int side)
|
||||
{
|
||||
|
@ -154,14 +155,13 @@ public abstract class BlockMachine extends BlockTile implements IExtraBlockInfo
|
|||
{
|
||||
this.zeroAnimation = config.get("Effects--Not_Supported_By_All_Blocks", "disableAnimation", false, "Turns off animations of the block").getBoolean(false);
|
||||
this.zeroRendering = config.get("Effects--Not_Supported_By_All_Blocks", "disableRender", false, "Turns off the block render replacing it with a normal block").getBoolean(false);
|
||||
this.zeroSound = config.get("Effects--Not_Supported_By_All_Blocks", "disableSound", false, "Turns of sound of the block for any or its actions").getBoolean(false);
|
||||
this.zeroSound = config.get("Effects--Not_Supported_By_All_Blocks", "disableSound", false, "Turns of sound of the block for any of its actions").getBoolean(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadOreNames()
|
||||
{
|
||||
OreDictionary.registerOre(this.getUnlocalizedName().replace("tile.", ""), this);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -172,6 +172,10 @@ public abstract class BlockMachine extends BlockTile implements IExtraBlockInfo
|
|||
{
|
||||
return true;
|
||||
}
|
||||
if (!world.isRemote && guiID != -1)
|
||||
{
|
||||
entityPlayer.openGui(DarkMain.getInstance(), guiID, world, x, y, z);
|
||||
}
|
||||
return super.onBlockActivated(world, x, y, z, entityPlayer, side, hitX, hitY, hitZ);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue