mirror of
https://github.com/Ellpeck/ActuallyAdditions.git
synced 2024-11-26 08:48:34 +01:00
All that cloudy goodness & bunch of people added!
This commit is contained in:
parent
9c06ade0d9
commit
3a2a0c74be
8 changed files with 226 additions and 156 deletions
|
@ -4,13 +4,10 @@ import cpw.mods.fml.client.registry.RenderingRegistry;
|
|||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import ellpeck.actuallyadditions.ActuallyAdditions;
|
||||
import ellpeck.actuallyadditions.gadget.cloud.ISmileyCloudEasterEgg;
|
||||
import ellpeck.actuallyadditions.gadget.cloud.SmileyCloudEasterEggs;
|
||||
import ellpeck.actuallyadditions.inventory.GuiHandler;
|
||||
import ellpeck.actuallyadditions.tile.TileEntitySmileyCloud;
|
||||
import ellpeck.actuallyadditions.util.BlockUtil;
|
||||
import ellpeck.actuallyadditions.util.INameableItem;
|
||||
import ellpeck.actuallyadditions.util.StringUtil;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.client.renderer.texture.IIconRegister;
|
||||
|
@ -58,30 +55,13 @@ public class BlockSmileyCloud extends BlockContainerBase implements INameableIte
|
|||
|
||||
@Override
|
||||
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int f6, float f7, float f8, float f9){
|
||||
TileEntity tile = world.getTileEntity(x, y, z);
|
||||
if(tile instanceof TileEntitySmileyCloud){
|
||||
TileEntitySmileyCloud cloud = (TileEntitySmileyCloud)tile;
|
||||
|
||||
if(player.isSneaking()){
|
||||
if(!world.isRemote){
|
||||
player.openGui(ActuallyAdditions.instance, GuiHandler.GuiTypes.CLOUD.ordinal(), world, x, y, z);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
for(ISmileyCloudEasterEgg egg : SmileyCloudEasterEggs.cloudStuff){
|
||||
for(String triggerName : egg.getTriggerNames()){
|
||||
if(StringUtil.equalsToLowerCase(triggerName, cloud.name)){
|
||||
if(egg.hasSpecialRightClick()){
|
||||
egg.specialRightClick(world, x, y, z, world.getBlock(x, y, z), world.getBlockMetadata(x, y, z));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!world.isRemote){
|
||||
TileEntity tile = world.getTileEntity(x, y, z);
|
||||
if(tile instanceof TileEntitySmileyCloud){
|
||||
player.openGui(ActuallyAdditions.instance, GuiHandler.GuiTypes.CLOUD.ordinal(), world, x, y, z);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package ellpeck.actuallyadditions.blocks.render;
|
||||
|
||||
import ellpeck.actuallyadditions.gadget.cloud.ISmileyCloudEasterEgg;
|
||||
import ellpeck.actuallyadditions.gadget.cloud.SmileyCloudEasterEggs;
|
||||
import net.minecraft.client.model.ModelRenderer;
|
||||
|
||||
public class ModelSmileyCloud extends ModelBaseAA{
|
||||
|
@ -128,10 +126,6 @@ public class ModelSmileyCloud extends ModelBaseAA{
|
|||
s16.setTextureSize(64, 64);
|
||||
s16.mirror = true;
|
||||
setRotation(s16, 0F, 0F, 0F);
|
||||
|
||||
for(ISmileyCloudEasterEgg cloud : SmileyCloudEasterEggs.cloudStuff){
|
||||
cloud.registerExtraRendering(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -4,8 +4,11 @@ import ellpeck.actuallyadditions.gadget.cloud.ISmileyCloudEasterEgg;
|
|||
import ellpeck.actuallyadditions.gadget.cloud.SmileyCloudEasterEggs;
|
||||
import ellpeck.actuallyadditions.tile.TileEntitySmileyCloud;
|
||||
import ellpeck.actuallyadditions.util.StringUtil;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.OpenGlHelper;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.entity.RenderManager;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
public class RenderSmileyCloud extends RenderTileEntity{
|
||||
|
@ -16,48 +19,83 @@ public class RenderSmileyCloud extends RenderTileEntity{
|
|||
|
||||
@Override
|
||||
public void renderTileEntityAt(TileEntity tile, double x, double y, double z, float par5){
|
||||
if(!(tile instanceof TileEntitySmileyCloud)) return;
|
||||
TileEntitySmileyCloud theCloud = (TileEntitySmileyCloud)tile;
|
||||
|
||||
GL11.glPushMatrix();
|
||||
GL11.glTranslatef((float)x+0.5F, (float)y-0.5F, (float)z+0.5F);
|
||||
GL11.glRotatef(180F, 0.0F, 0.0F, 1.0F);
|
||||
GL11.glTranslatef(0.0F, -2.0F, 0.0F);
|
||||
{
|
||||
GL11.glTranslatef((float)x+0.5F, (float)y-0.5F, (float)z+0.5F);
|
||||
GL11.glRotatef(180F, 0.0F, 0.0F, 1.0F);
|
||||
GL11.glTranslatef(0.0F, -2.0F, 0.0F);
|
||||
|
||||
if(theModel.doesRotate()){
|
||||
int meta = tile.getWorldObj().getBlockMetadata(tile.xCoord, tile.yCoord, tile.zCoord);
|
||||
if(meta == 0) GL11.glRotatef(180F, 0F, 1F, 0F);
|
||||
if(meta == 1) GL11.glRotatef(90F, 0F, 1F, 0F);
|
||||
if(meta == 3) GL11.glRotatef(270F, 0F, 1F, 0F);
|
||||
}
|
||||
GL11.glPushMatrix();
|
||||
{
|
||||
if(theModel.doesRotate()){
|
||||
int meta = tile.getWorldObj().getBlockMetadata(tile.xCoord, tile.yCoord, tile.zCoord);
|
||||
if(meta == 0) GL11.glRotatef(180F, 0F, 1F, 0F);
|
||||
if(meta == 1) GL11.glRotatef(90F, 0F, 1F, 0F);
|
||||
if(meta == 3) GL11.glRotatef(270F, 0F, 1F, 0F);
|
||||
}
|
||||
|
||||
this.bindTexture(resLoc);
|
||||
this.bindTexture(resLoc);
|
||||
|
||||
if(tile instanceof TileEntitySmileyCloud){
|
||||
boolean hasRendered = false;
|
||||
theModel.render(0.0625F);
|
||||
|
||||
TileEntitySmileyCloud theCloud = (TileEntitySmileyCloud)tile;
|
||||
if(theCloud.name != null && !theCloud.name.isEmpty()){
|
||||
for(ISmileyCloudEasterEgg cloud : SmileyCloudEasterEggs.cloudStuff){
|
||||
for(String triggerName : cloud.getTriggerNames()){
|
||||
if(StringUtil.equalsToLowerCase(triggerName, theCloud.name)){
|
||||
|
||||
if(cloud.shouldRenderOriginal()){
|
||||
theModel.render(0.0625F);
|
||||
if(theCloud.name != null && !theCloud.name.isEmpty()){
|
||||
for(ISmileyCloudEasterEgg cloud : SmileyCloudEasterEggs.cloudStuff){
|
||||
boolean canBreak = false;
|
||||
for(String triggerName : cloud.getTriggerNames()){
|
||||
if(StringUtil.equalsToLowerCase(triggerName, theCloud.name)){
|
||||
cloud.renderExtra(0.0625F);
|
||||
canBreak = true;
|
||||
break;
|
||||
}
|
||||
|
||||
ResourceLocation resLoc = cloud.getResLoc();
|
||||
if(resLoc != null){
|
||||
this.bindTexture(resLoc);
|
||||
}
|
||||
|
||||
cloud.renderExtra(0.0625F);
|
||||
|
||||
hasRendered = true;
|
||||
break;
|
||||
}
|
||||
if(canBreak) break;
|
||||
}
|
||||
if(hasRendered) break;
|
||||
}
|
||||
}
|
||||
if(!hasRendered) theModel.render(0.0625F);
|
||||
GL11.glPopMatrix();
|
||||
|
||||
if(theCloud.name != null && !theCloud.name.isEmpty() && !Minecraft.getMinecraft().gameSettings.hideGUI){
|
||||
GL11.glPushMatrix();
|
||||
{
|
||||
GL11.glTranslatef(0F, 0.1F, 0F);
|
||||
GL11.glRotatef(180F, 1F, 0F, 0F);
|
||||
GL11.glRotatef(180F, 0F, 1F, 0F);
|
||||
|
||||
GL11.glRotatef(-RenderManager.instance.playerViewY, 0.0F, 1.0F, 0.0F);
|
||||
GL11.glRotatef(RenderManager.instance.playerViewX, 1.0F, 0.0F, 0.0F);
|
||||
float f = 1.6F;
|
||||
float f1 = 0.016666668F*f;
|
||||
GL11.glScalef(-f1, -f1, f1);
|
||||
GL11.glDisable(GL11.GL_LIGHTING);
|
||||
GL11.glTranslatef(0.0F, 0F/f1, 0.0F);
|
||||
GL11.glDepthMask(false);
|
||||
GL11.glEnable(GL11.GL_BLEND);
|
||||
OpenGlHelper.glBlendFunc(770, 771, 1, 0);
|
||||
Tessellator tessellator = Tessellator.instance;
|
||||
GL11.glDisable(GL11.GL_TEXTURE_2D);
|
||||
tessellator.startDrawingQuads();
|
||||
int i = Minecraft.getMinecraft().fontRenderer.getStringWidth(theCloud.name)/2;
|
||||
tessellator.setColorRGBA_F(0.0F, 0.0F, 0.0F, 0.25F);
|
||||
tessellator.addVertex(-i-1, -1.0D, 0.0D);
|
||||
tessellator.addVertex(-i-1, 8.0D, 0.0D);
|
||||
tessellator.addVertex(i+1, 8.0D, 0.0D);
|
||||
tessellator.addVertex(i+1, -1.0D, 0.0D);
|
||||
tessellator.draw();
|
||||
GL11.glEnable(GL11.GL_TEXTURE_2D);
|
||||
GL11.glDepthMask(true);
|
||||
|
||||
Minecraft.getMinecraft().fontRenderer.drawString(theCloud.name, -Minecraft.getMinecraft().fontRenderer.getStringWidth(theCloud.name)/2, 0, 0xFFFFFF);
|
||||
|
||||
GL11.glEnable(GL11.GL_LIGHTING);
|
||||
GL11.glDisable(GL11.GL_BLEND);
|
||||
GL11.glColor4f(1F, 1F, 1F, 1F);
|
||||
GL11.glScalef(1F/-f1, 1F/-f1, 1F/f1);
|
||||
}
|
||||
GL11.glPopMatrix();
|
||||
}
|
||||
}
|
||||
GL11.glPopMatrix();
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ public class RenderPlayerEventAA{
|
|||
//dqmhose
|
||||
if(event.entityPlayer.getUniqueID().equals(UUID.fromString("cb7b293a-5031-484e-b5be-b4f2f4e92726"))){
|
||||
hoseRender.render(event.entityPlayer, event.partialRenderTick, 0.5F, 1.3F);
|
||||
//return;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
package ellpeck.actuallyadditions.gadget.cloud;
|
||||
|
||||
import ellpeck.actuallyadditions.blocks.render.ModelBaseAA;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public interface ISmileyCloudEasterEgg{
|
||||
|
||||
/**
|
||||
|
@ -12,37 +7,8 @@ public interface ISmileyCloudEasterEgg{
|
|||
*/
|
||||
void renderExtra(float f);
|
||||
|
||||
/**
|
||||
* Registers extra rendering
|
||||
*/
|
||||
void registerExtraRendering(ModelBaseAA model);
|
||||
|
||||
/**
|
||||
* If the Original cloud should be rendered
|
||||
*/
|
||||
boolean shouldRenderOriginal();
|
||||
|
||||
boolean hasSpecialRightClick();
|
||||
|
||||
/**
|
||||
* If something special happens on right-click of the cloud
|
||||
*/
|
||||
void specialRightClick(World world, int x, int y, int z, Block block, int meta);
|
||||
|
||||
/**
|
||||
* Something in addition to the default name in the name tag
|
||||
*/
|
||||
String displayNameExtra();
|
||||
|
||||
/**
|
||||
* If the original name should be rendered
|
||||
*/
|
||||
boolean shouldRenderOriginalName();
|
||||
|
||||
/**
|
||||
* The name the cloud has to have for this effect to occur
|
||||
*/
|
||||
String[] getTriggerNames();
|
||||
|
||||
ResourceLocation getResLoc();
|
||||
}
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
package ellpeck.actuallyadditions.gadget.cloud;
|
||||
|
||||
import ellpeck.actuallyadditions.blocks.render.ModelBaseAA;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public abstract class SmileyCloudEasterEgg implements ISmileyCloudEasterEgg{
|
||||
|
||||
@Override
|
||||
public void renderExtra(float f){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getResLoc(){
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRenderOriginal(){
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSpecialRightClick(){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void specialRightClick(World world, int x, int y, int z, Block block, int meta){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerExtraRendering(ModelBaseAA model){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String displayNameExtra(){
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRenderOriginalName(){
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,10 @@
|
|||
package ellpeck.actuallyadditions.gadget.cloud;
|
||||
|
||||
import ellpeck.actuallyadditions.blocks.InitBlocks;
|
||||
import ellpeck.actuallyadditions.items.InitItems;
|
||||
import ellpeck.actuallyadditions.util.AssetUtil;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
@ -13,19 +17,125 @@ public class SmileyCloudEasterEggs{
|
|||
|
||||
static{
|
||||
//Glenthor
|
||||
register(new SmileyCloudEasterEgg(){
|
||||
register(new ISmileyCloudEasterEgg(){
|
||||
@Override
|
||||
public String[] getTriggerNames(){
|
||||
return new String[]{"glenthor"};
|
||||
return new String[]{"glenthor", "glenthorlp", "twoofeight"};
|
||||
}
|
||||
@Override
|
||||
public void renderExtra(float f){
|
||||
GL11.glTranslatef(f*8F, f*24F, f*-4F);
|
||||
GL11.glRotatef(180F, 0F, 0F, 1F);
|
||||
GL11.glRotatef(85F, 0F, 1F, 0F);
|
||||
GL11.glRotatef(70F, 0F, 0F, 1F);
|
||||
GL11.glScalef(0.75F, 0.75F, 0.75F);
|
||||
AssetUtil.renderItem(new ItemStack(Items.dye, 1, 2), 0);
|
||||
renderHoldingItem(true, new ItemStack(Items.dye, 1, 2));
|
||||
renderHeadBlock(InitBlocks.blockHeatCollector, 0, 5F);
|
||||
}
|
||||
});
|
||||
//Ellpeck
|
||||
register(new ISmileyCloudEasterEgg(){
|
||||
@Override
|
||||
public String[] getTriggerNames(){
|
||||
return new String[]{"ellpeck", "ellopecko", "peck"};
|
||||
}
|
||||
@Override
|
||||
public void renderExtra(float f){
|
||||
renderHoldingItem(false, new ItemStack(InitItems.itemPhantomConnector));
|
||||
renderHeadBlock(InitBlocks.blockPhantomLiquiface, 0, 25F);
|
||||
}
|
||||
});
|
||||
//Tyrex
|
||||
register(new ISmileyCloudEasterEgg(){
|
||||
@Override
|
||||
public String[] getTriggerNames(){
|
||||
return new String[]{"tyrex", "lord_tobinho", "tobinho"};
|
||||
}
|
||||
@Override
|
||||
public void renderExtra(float f){
|
||||
renderHoldingItem(false, new ItemStack(Items.fishing_rod));
|
||||
renderHoldingItem(true, new ItemStack(Items.fish));
|
||||
}
|
||||
});
|
||||
//Hose
|
||||
register(new ISmileyCloudEasterEgg(){
|
||||
@Override
|
||||
public String[] getTriggerNames(){
|
||||
return new String[]{"dqmhose", "xdqmhose", "hose"};
|
||||
}
|
||||
@Override
|
||||
public void renderExtra(float f){
|
||||
renderHoldingItem(false, new ItemStack(Items.reeds));
|
||||
renderHeadBlock(Blocks.torch, 0, 15F);
|
||||
}
|
||||
});
|
||||
//Tobi
|
||||
register(new ISmileyCloudEasterEgg(){
|
||||
@Override
|
||||
public String[] getTriggerNames(){
|
||||
return new String[]{"jemx", "jemxx", "jemxxx", "spielertobi200"};
|
||||
}
|
||||
@Override
|
||||
public void renderExtra(float f){
|
||||
renderHoldingItem(true, new ItemStack(Items.milk_bucket));
|
||||
renderHeadBlock(Blocks.lit_redstone_lamp, 0, 35F);
|
||||
}
|
||||
});
|
||||
//Vazkii
|
||||
register(new ISmileyCloudEasterEgg(){
|
||||
@Override
|
||||
public String[] getTriggerNames(){
|
||||
return new String[]{"vazkii", "vaski", "waskie"};
|
||||
}
|
||||
@Override
|
||||
public void renderExtra(float f){
|
||||
renderHoldingItem(true, new ItemStack(Items.dye, 1, 15));
|
||||
renderHeadBlock(Blocks.red_flower, 5, 20F);
|
||||
}
|
||||
});
|
||||
//Kitty
|
||||
register(new ISmileyCloudEasterEgg(){
|
||||
@Override
|
||||
public String[] getTriggerNames(){
|
||||
return new String[]{"kitty", "kiddy", "kittyvancat", "kittyvancatlp"};
|
||||
}
|
||||
@Override
|
||||
public void renderExtra(float f){
|
||||
renderHoldingItem(true, new ItemStack(Items.fish));
|
||||
renderHoldingItem(false, new ItemStack(Items.milk_bucket));
|
||||
renderHeadBlock(Blocks.wool, 10, 15F);
|
||||
}
|
||||
});
|
||||
//Canitzp
|
||||
register(new ISmileyCloudEasterEgg(){
|
||||
@Override
|
||||
public String[] getTriggerNames(){
|
||||
return new String[]{"canitz", "canitzp", "kannnichts", "kannnichtsp"};
|
||||
}
|
||||
@Override
|
||||
public void renderExtra(float f){
|
||||
renderHoldingItem(false, new ItemStack(Items.wooden_sword));
|
||||
renderHeadBlock(Blocks.chest, 10, 70F);
|
||||
}
|
||||
});
|
||||
//Lari
|
||||
register(new ISmileyCloudEasterEgg(){
|
||||
@Override
|
||||
public String[] getTriggerNames(){
|
||||
return new String[]{"lari", "larixine", "xine", "laxi", "lachsirine", "lala", "lalilu"};
|
||||
}
|
||||
@Override
|
||||
public void renderExtra(float f){
|
||||
renderHoldingItem(false, new ItemStack(Items.iron_helmet));
|
||||
renderHeadBlock(Blocks.cake, 0, 28F);
|
||||
}
|
||||
});
|
||||
//RotesDing
|
||||
register(new ISmileyCloudEasterEgg(){
|
||||
@Override
|
||||
public String[] getTriggerNames(){
|
||||
return new String[]{"rotesding", "dotesring"};
|
||||
}
|
||||
@Override
|
||||
public void renderExtra(float f){
|
||||
renderHoldingItem(false, new ItemStack(Items.milk_bucket));
|
||||
renderHoldingItem(true, new ItemStack(Items.dye, 1, 1));
|
||||
renderHeadBlock(Blocks.wool, 14, 18F);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -33,4 +143,32 @@ public class SmileyCloudEasterEggs{
|
|||
private static void register(ISmileyCloudEasterEgg egg){
|
||||
cloudStuff.add(egg);
|
||||
}
|
||||
|
||||
private static void renderHoldingItem(boolean leftHand, ItemStack stack){
|
||||
GL11.glPushMatrix();
|
||||
|
||||
GL11.glRotatef(180F, 0F, 0F, 1F);
|
||||
GL11.glRotatef(270F, 0F, 1F, 0F);
|
||||
GL11.glTranslatef(0F, -1.5F, 0F);
|
||||
GL11.glTranslatef(-0.5F, 0.2F, leftHand ? 0.55F : -0.5F);
|
||||
GL11.glScalef(0.75F, 0.75F, 0.75F);
|
||||
|
||||
AssetUtil.renderItem(stack, 0);
|
||||
|
||||
GL11.glPopMatrix();
|
||||
}
|
||||
|
||||
private static void renderHeadBlock(Block block, int meta, float rotation){
|
||||
GL11.glPushMatrix();
|
||||
GL11.glDisable(GL11.GL_LIGHTING);
|
||||
GL11.glTranslatef(-0.015F, 0.6F, 0.075F);
|
||||
GL11.glScalef(0.3F, 0.3F, 0.3F);
|
||||
GL11.glRotatef(180F, 1F, 0F, 0F);
|
||||
GL11.glRotatef(rotation, 0F, 1F, 0F);
|
||||
|
||||
AssetUtil.renderBlock(block, meta);
|
||||
|
||||
GL11.glEnable(GL11.GL_LIGHTING);
|
||||
GL11.glPopMatrix();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -567,6 +567,9 @@ tooltip.actuallyadditions.itemPantsObsidian.desc="Pants" is "Hose" in German!
|
|||
item.actuallyadditions.itemBootsObsidian.name=Obsidian Boots
|
||||
tooltip.actuallyadditions.itemBootsObsidian.desc=I hope they fit good.. I hate it when boots don't fit..
|
||||
|
||||
tile.actuallyadditions.blockSmileyCloud.name=Smiley Cloud
|
||||
tooltip.actuallyadditions.blockSmileyCloud.desc=It smiles! Give it a name by right-clicking.
|
||||
|
||||
item.actuallyadditions.itemHelmEmerald.name=Emerald Helm
|
||||
tooltip.actuallyadditions.itemHelmEmerald.desc=I like the color.. it's so SHINY!
|
||||
item.actuallyadditions.itemChestEmerald.name=Emerald Chestplate
|
||||
|
|
Loading…
Reference in a new issue