From f74984a014e33a9fddfe738b1d4e3020dbdbd05b Mon Sep 17 00:00:00 2001 From: Kam Date: Wed, 12 Feb 2025 21:58:44 -0500 Subject: [PATCH] NPC Tool --- src/main/java/noppes/npcs/CustomItems.java | 23 ++- .../renderer/items/NpcItemToolRenderer.java | 162 ++++++++++++++++++ .../java/noppes/npcs/items/ItemNpcTool.java | 84 +++++++++ 3 files changed, 261 insertions(+), 8 deletions(-) create mode 100644 src/main/java/noppes/npcs/client/renderer/items/NpcItemToolRenderer.java create mode 100644 src/main/java/noppes/npcs/items/ItemNpcTool.java diff --git a/src/main/java/noppes/npcs/CustomItems.java b/src/main/java/noppes/npcs/CustomItems.java index 02537f95d..8763f7b93 100644 --- a/src/main/java/noppes/npcs/CustomItems.java +++ b/src/main/java/noppes/npcs/CustomItems.java @@ -27,6 +27,7 @@ public class CustomItems { public static Item moving; public static Item mount; public static Item teleporter; + public static Item tool; public static Item scripted_item; public static Item soulstoneEmpty; @@ -169,6 +170,7 @@ public class CustomItems { public static Block banner; public static Block wallBanner; public static Block tallLamp; + public static Block shortLamp; public static Block blood; public static Block book; public static Block chair; @@ -215,6 +217,7 @@ public class CustomItems { if(!ConfigMain.DisableExtraBlock){ GameRegistry.registerTileEntity(TileWallBanner.class, "TileNPCWallBanner"); GameRegistry.registerTileEntity(TileTallLamp.class, "TileNPCTallLamp"); + GameRegistry.registerTileEntity(TileShortLamp.class, "TileNPCShortLamp"); GameRegistry.registerTileEntity(TileChair.class, "TileNPCChair"); GameRegistry.registerTileEntity(TileCrate.class, "TileNPCCrate"); GameRegistry.registerTileEntity(TileWeaponRack.class, "TileNPCWeaponRack"); @@ -242,9 +245,10 @@ public class CustomItems { mount = new ItemMounter().setUnlocalizedName("npcMounter").setFull3D(); teleporter = new ItemTeleporter().setUnlocalizedName("npcTeleporter").setFull3D(); scripted_item = new ItemScripted().setUnlocalizedName("scripted_item").setFull3D(); + tool = new ItemNpcTool().setUnlocalizedName("npcTool").setFull3D(); redstoneBlock = new BlockNpcRedstone().setHardness(50.0F).setResistance(2000).setBlockName("npcRedstoneBlock").setBlockTextureName("customnpcs:npcRedstoneBlock").setCreativeTab(tab); - carpentyBench = new BlockCarpentryBench().setBlockName("npcCarpentyBench").setHardness(5.0F).setResistance(10.0F).setStepSound(Block.soundTypeWood).setCreativeTab(tabBlocks); + carpentyBench = new BlockCarpentryBench().setBlockName("npcCarpentyBench").setHardness(5.0F).setResistance(10.0F).setStepSound(Block.soundTypePiston).setCreativeTab(tabBlocks); mailbox = new BlockMailbox().setBlockName("npcMailbox").setHardness(5.0F).setResistance(10.0F).setStepSound(Block.soundTypeMetal).setCreativeTab(tabBlocks); waypoint = new BlockWaypoint().setBlockName("npcLocationBlock").setHardness(5.0F).setResistance(10.0F).setStepSound(Block.soundTypeMetal).setBlockTextureName("customnpcs:npcWaypoint").setCreativeTab(tab); border = new BlockBorder().setBlockName("npcBorder").setHardness(5.0F).setResistance(10.0F).setStepSound(Block.soundTypeWood).setCreativeTab(tab).setBlockTextureName("customnpcs:npcBorder"); @@ -279,17 +283,18 @@ public class CustomItems { if(!ConfigMain.DisableExtraBlock){ blood = new BlockBlood().setBlockName("npcBloodBlock").setBlockTextureName("customnpcs:npcBloodBlock").setCreativeTab(tabBlocks); - banner = new BlockBanner().setBlockName("npcBanner").setHardness(5.0F).setResistance(10.0F).setStepSound(Block.soundTypeMetal).setCreativeTab(tabBlocks); - wallBanner = new BlockWallBanner().setBlockName("npcWallBanner").setHardness(5.0F).setResistance(10.0F).setStepSound(Block.soundTypeMetal).setCreativeTab(tabBlocks); + banner = new BlockBanner().setBlockName("npcBanner").setHardness(5.0F).setResistance(10.0F).setStepSound(Block.soundTypeCloth).setCreativeTab(tabBlocks); + wallBanner = new BlockWallBanner().setBlockName("npcWallBanner").setHardness(5.0F).setResistance(10.0F).setStepSound(Block.soundTypeCloth).setCreativeTab(tabBlocks); tallLamp = new BlockTallLamp().setBlockName("npcTallLamp").setHardness(5.0F).setResistance(10.0F).setStepSound(Block.soundTypeMetal).setCreativeTab(tabBlocks); - chair = new BlockChair().setBlockName("npcChair").setHardness(5.0F).setResistance(10.0F).setStepSound(Block.soundTypeWood).setCreativeTab(tabBlocks); + shortLamp = new BlockShortLamp().setBlockName("npcShortLamp").setHardness(5.0F).setResistance(10.0F).setStepSound(Block.soundTypeMetal).setCreativeTab(tabBlocks); + chair = new BlockChair().setBlockName("npcChair").setHardness(5.0F).setResistance(10.0F).setStepSound(Block.soundTypeWood).setCreativeTab(tabBlocks); crate = new BlockCrate().setBlockName("npcCrate").setHardness(5.0F).setResistance(10.0F).setStepSound(Block.soundTypeWood).setCreativeTab(tabBlocks); weaponsRack = new BlockWeaponRack().setBlockName("npcWeaponRack").setHardness(5.0F).setResistance(10.0F).setStepSound(Block.soundTypeWood).setCreativeTab(tabBlocks); couchWool = new BlockCouchWool().setBlockName("npcCouchWool").setHardness(5.0F).setResistance(10.0F).setStepSound(Block.soundTypeWood).setCreativeTab(tabBlocks); table = new BlockTable().setBlockName("npcTable").setHardness(5.0F).setResistance(10.0F).setStepSound(Block.soundTypeWood).setCreativeTab(tabBlocks); couchWood = new BlockCouchWood().setBlockName("npcCouchWood").setHardness(5.0F).setResistance(10.0F).setStepSound(Block.soundTypeWood).setCreativeTab(tabBlocks); - lantern = new BlockLantern(true).setBlockName("npcLamp").setHardness(5.0F).setResistance(10.0F).setStepSound(Block.soundTypeWood).setCreativeTab(tabBlocks); - candle = new BlockCandle(true).setBlockName("npcCandle").setHardness(5.0F).setResistance(10.0F).setStepSound(Block.soundTypeWood).setCreativeTab(tabBlocks); + lantern = new BlockLantern(true).setBlockName("npcLamp").setHardness(5.0F).setResistance(10.0F).setStepSound(Block.soundTypeMetal).setCreativeTab(tabBlocks).setBlockTextureName("customnpcs:lantern");; + candle = new BlockCandle(true).setBlockName("npcCandle").setHardness(5.0F).setResistance(10.0F).setStepSound(Block.soundTypeStone).setCreativeTab(tabBlocks).setBlockTextureName("customnpcs:candle");; stool = new BlockStool().setBlockName("npcStool").setHardness(5.0F).setResistance(10.0F).setStepSound(Block.soundTypeWood).setCreativeTab(tabBlocks); Block placeholder = new BlockPlaceholder().setBlockName("npcPlaceholder").setHardness(5.0F).setResistance(10.0F).setStepSound(Block.soundTypeWood).setCreativeTab(tabMisc); bigsign = new BlockBigSign().setBlockName("npcBigSign").setHardness(5.0F).setResistance(10.0F).setStepSound(Block.soundTypeWood).setCreativeTab(tabBlocks); @@ -304,13 +309,14 @@ public class CustomItems { crystal = new BlockCrystal().setBlockName("npcCrystal").setBlockTextureName("customnpcs:npcCrystal").setHardness(5.0F).setResistance(10.0F).setStepSound(Block.soundTypeGlass).setCreativeTab(tabBlocks); campfire_unlit = new BlockCampfire(false).setBlockName("npcCampfire").setHardness(5.0F).setResistance(10.0F).setStepSound(Block.soundTypeStone); - lantern_unlit = new BlockLantern(false).setBlockName("npcLamp").setHardness(5.0F).setResistance(10.0F).setStepSound(Block.soundTypeWood); - candle_unlit = new BlockCandle(false).setBlockName("npcCandle").setHardness(5.0F).setResistance(10.0F).setStepSound(Block.soundTypeWood); + lantern_unlit = new BlockLantern(false).setBlockName("npcLamp").setHardness(5.0F).setResistance(10.0F).setStepSound(Block.soundTypeMetal).setBlockTextureName("customnpcs:lantern"); + candle_unlit = new BlockCandle(false).setBlockName("npcCandle").setHardness(5.0F).setResistance(10.0F).setStepSound(Block.soundTypeStone).setBlockTextureName("customnpcs:candle"); GameRegistry.registerBlock(blood, "npcBloodBlock"); GameRegistry.registerBlock(banner, ItemBlock.class, "npcBanner"); GameRegistry.registerBlock(wallBanner, ItemBlock.class, "npcWallBanner"); GameRegistry.registerBlock(tallLamp, ItemBlock.class, "npcTallLamp"); + GameRegistry.registerBlock(shortLamp, ItemBlock.class, "npcShortLamp"); GameRegistry.registerBlock(chair, ItemBlock.class, "npcChair"); GameRegistry.registerBlock(crate, ItemBlock.class, "npcCrate"); GameRegistry.registerBlock(weaponsRack, ItemBlock.class, "npcWeaponRack"); @@ -338,6 +344,7 @@ public class CustomItems { Item.getItemFromBlock(banner).setHasSubtypes(true); Item.getItemFromBlock(wallBanner).setHasSubtypes(true); Item.getItemFromBlock(tallLamp).setHasSubtypes(true); + Item.getItemFromBlock(shortLamp).setHasSubtypes(true); Item.getItemFromBlock(chair).setHasSubtypes(true); Item.getItemFromBlock(crate).setHasSubtypes(true); Item.getItemFromBlock(weaponsRack).setHasSubtypes(true); diff --git a/src/main/java/noppes/npcs/client/renderer/items/NpcItemToolRenderer.java b/src/main/java/noppes/npcs/client/renderer/items/NpcItemToolRenderer.java new file mode 100644 index 000000000..24118d854 --- /dev/null +++ b/src/main/java/noppes/npcs/client/renderer/items/NpcItemToolRenderer.java @@ -0,0 +1,162 @@ +package noppes.npcs.client.renderer.items; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.ItemRenderer; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.texture.TextureManager; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.client.IItemRenderer; +import noppes.npcs.items.ItemRenderInterface; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; + +public class NpcItemToolRenderer implements IItemRenderer { + + // Textures for the assembled paintbrush parts: + private static final ResourceLocation PAINTBRUSH_HANDLE = new ResourceLocation("noppes", "textures/items/paintbrush_handle.png"); + private static final ResourceLocation PAINTBRUSH_BRUSH = new ResourceLocation("noppes", "textures/items/paintbrush_brush.png"); + private static final ResourceLocation ENCHANT = new ResourceLocation("textures/misc/enchanted_item_glint.png"); + + @Override + public boolean handleRenderType(ItemStack item, ItemRenderType type) { + // Only handle equipped types (first person or third person equipped) + return type == ItemRenderType.EQUIPPED || type == ItemRenderType.EQUIPPED_FIRST_PERSON; + } + + @Override + public boolean shouldUseRenderHelper(ItemRenderType type, ItemStack item, ItemRendererHelper helper) { + return false; + } + + @Override + public void renderItem(ItemRenderType type, ItemStack item, Object... data) { + // Ensure the item implements our render interface + if (!(item.getItem() instanceof ItemRenderInterface)) + return; + + EntityLivingBase entity = (EntityLivingBase) data[1]; + + GL11.glPushMatrix(); + // Apply base translations/rotations + GL11.glTranslatef(0.9375F, 0.0625F, 0.0F); + GL11.glRotatef(-315.0F, 0.0F, 0.0F, 1.0F); + + // For meta==1 (paintbrush) we want to assemble the texture from two parts + if (item.getItemDamage() == 1) { + renderPaintbrush(entity, item); + } else { + // For other tools, fall back on the normal special render routine. + ((ItemRenderInterface) item.getItem()).renderSpecial(); + GL11.glRotatef(-20.0F, 0.0F, 0.0F, 1.0F); + GL11.glRotatef(-50.0F, 0.0F, 1.0F, 0.0F); + GL11.glTranslatef(-0.09375F, 0.0625F, 0.0F); + renderItem3d(entity, item); + } + GL11.glPopMatrix(); + } + + /** + * Renders the paintbrush by drawing its handle first, then overlaying the brush part tinted + * by the NBT "Color" value (an integer/hex value). + */ + private void renderPaintbrush(EntityLivingBase entity, ItemStack item) { + Minecraft mc = Minecraft.getMinecraft(); + TextureManager textureManager = mc.getTextureManager(); + Tessellator tessellator = Tessellator.instance; + int width = 16; + int height = 16; + float thickness = 0.0625F; + + GL11.glEnable(GL12.GL_RESCALE_NORMAL); + + // Render the handle (untinted) + textureManager.bindTexture(PAINTBRUSH_HANDLE); + // Using full texture coordinates (0→1) in the same order as vanilla's renderItemIn2D: + ItemRenderer.renderItemIn2D(tessellator, 1.0F, 0.0F, 0.0F, 1.0F, width, height, thickness); + + // Get the NBT color (default is white if not present) + int color = 0xFFFFFF; + if (item.hasTagCompound() && item.getTagCompound().hasKey("Color")) { + color = item.getTagCompound().getInteger("Color"); + } + float red = ((color >> 16) & 0xFF) / 255.0F; + float green = ((color >> 8) & 0xFF) / 255.0F; + float blue = (color & 0xFF) / 255.0F; + GL11.glColor3f(red, green, blue); + + // Render the brush (tinted by the color) + textureManager.bindTexture(PAINTBRUSH_BRUSH); + ItemRenderer.renderItemIn2D(tessellator, 1.0F, 0.0F, 0.0F, 1.0F, width, height, thickness); + + // Reset GL color to white so that subsequent rendering is not tinted + GL11.glColor3f(1.0F, 1.0F, 1.0F); + GL11.glDisable(GL12.GL_RESCALE_NORMAL); + + // If the item is enchanted, render the enchanted glint effect on top + if (item.hasEffect(0)) { + renderEnchantedEffect(tessellator, textureManager); + } + } + + /** + * Fallback 3D item renderer (for non-paintbrush items) + */ + private void renderItem3d(EntityLivingBase entity, ItemStack item) { + Minecraft mc = Minecraft.getMinecraft(); + TextureManager textureManager = mc.getTextureManager(); + Tessellator tessellator = Tessellator.instance; + textureManager.bindTexture(textureManager.getResourceLocation(item.getItemSpriteNumber())); + IIcon icon = entity.getItemIcon(item, 0); + if (icon == null) { + return; + } + float minU = icon.getMinU(); + float maxU = icon.getMaxU(); + float minV = icon.getMinV(); + float maxV = icon.getMaxV(); + int width = icon.getIconWidth(); + int height = icon.getIconHeight(); + + GL11.glEnable(GL12.GL_RESCALE_NORMAL); + // Note: The order here mimics vanilla's 2D item rendering + ItemRenderer.renderItemIn2D(tessellator, maxU, minV, minU, maxV, width, height, 0.0625F); + GL11.glDisable(GL12.GL_RESCALE_NORMAL); + } + + /** + * Renders the enchanted glint overlay. + */ + private void renderEnchantedEffect(Tessellator tessellator, TextureManager textureManager) { + GL11.glDepthFunc(GL11.GL_EQUAL); + GL11.glDisable(GL11.GL_LIGHTING); + textureManager.bindTexture(ENCHANT); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_COLOR, GL11.GL_ONE); + float f7 = 0.76F; + GL11.glColor4f(0.5F * f7, 0.25F * f7, 0.8F * f7, 1.0F); + GL11.glMatrixMode(GL11.GL_TEXTURE); + GL11.glPushMatrix(); + float f8 = 0.125F; + GL11.glScalef(f8, f8, f8); + float f9 = (float) (Minecraft.getSystemTime() % 3000L) / 3000.0F * 8.0F; + GL11.glTranslatef(f9, 0.0F, 0.0F); + GL11.glRotatef(-50.0F, 0.0F, 0.0F, 1.0F); + ItemRenderer.renderItemIn2D(tessellator, 0.0F, 0.0F, 1.0F, 1.0F, 256, 256, 0.0625F); + GL11.glPopMatrix(); + GL11.glPushMatrix(); + GL11.glScalef(f8, f8, f8); + f9 = (float) (Minecraft.getSystemTime() % 4873L) / 4873.0F * 8.0F; + GL11.glTranslatef(-f9, 0.0F, 0.0F); + GL11.glRotatef(10.0F, 0.0F, 0.0F, 1.0F); + ItemRenderer.renderItemIn2D(tessellator, 0.0F, 0.0F, 1.0F, 1.0F, 256, 256, 0.0625F); + GL11.glPopMatrix(); + GL11.glMatrixMode(GL11.GL_MODELVIEW); + GL11.glDisable(GL11.GL_BLEND); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glDepthFunc(GL11.GL_LEQUAL); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + } +} diff --git a/src/main/java/noppes/npcs/items/ItemNpcTool.java b/src/main/java/noppes/npcs/items/ItemNpcTool.java new file mode 100644 index 000000000..005cf26ac --- /dev/null +++ b/src/main/java/noppes/npcs/items/ItemNpcTool.java @@ -0,0 +1,84 @@ +package noppes.npcs.items; + +import cpw.mods.fml.common.registry.GameRegistry; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.IIcon; +import net.minecraft.world.World; +import noppes.npcs.CustomItems; + +import java.util.List; + +public class ItemNpcTool extends Item { + + // Define our tool types based on metadata: + // meta 0: Hammer, meta 1: Paintbrush, meta 2: Wrench + public static final String[] toolTypes = new String[] {"hammer", "paintbrush", "wrench"}; + + @SideOnly(Side.CLIENT) + private IIcon[] icons; + + public ItemNpcTool() { + super(); + maxStackSize = 1; + setHasSubtypes(true); + setMaxDamage(0); + setCreativeTab(CustomItems.tab); + } + + @Override + public String getUnlocalizedName(ItemStack stack) { + int meta = stack.getItemDamage(); + if(meta < 0 || meta >= toolTypes.length){ + meta = 0; + } + return super.getUnlocalizedName() + "." + toolTypes[meta]; + } + + @SideOnly(Side.CLIENT) + @Override + public void registerIcons(IIconRegister iconRegister) { + icons = new IIcon[toolTypes.length]; + for (int i = 0; i < toolTypes.length; i++) { + icons[i] = iconRegister.registerIcon("noppes:npc_tool_" + toolTypes[i]); + } + } + + @Override + public IIcon getIconFromDamage(int meta) { + if(meta < 0 || meta >= icons.length){ + meta = 0; + } + return icons[meta]; + } + + @Override + public void getSubItems(Item item, CreativeTabs tab, List subItems) { + for (int i = 0; i < toolTypes.length; i++) { + subItems.add(new ItemStack(item, 1, i)); + } + } + + @Override + public ItemStack onItemRightClick(ItemStack stack, World world, EntityPlayer player) { + if(world.isRemote) { + int meta = stack.getItemDamage(); + if(meta < 0 || meta >= toolTypes.length) meta = 0; + // Send a simple chat message indicating which tool was used + player.addChatMessage(new ChatComponentTranslation("item.npc_tool." + toolTypes[meta] + ".use")); + } + return stack; + } + + @Override + public Item setUnlocalizedName(String name){ + GameRegistry.registerItem(this, name); + return super.setUnlocalizedName(name); + } +}