Jump to content

MythicalChromosome

Members
  • Posts

    19
  • Joined

  • Last visited

Everything posted by MythicalChromosome

  1. After a bit more debugging, the solution to my problem turned out to be simple (as it usually tends to be...:P) I wasn't checking against the tag correctly. The method I was using was checking against the entire tag as a string, when it should've been checking against the value. Simply changing the method called made it work perfectly as intended: public class ItemStandArrow extends Item{ private static final String name = "standArrow"; public ItemStandArrow() { super(); setUnlocalizedName(name); setCreativeTab(CreativeTabs.TOOLS); setMaxStackSize(1); } @Override public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand) { NBTTagCompound nbt; ItemStack stack = player.getHeldItem(hand); NBTTagList nbttaglist; if (stack.hasTagCompound()) { nbt = stack.getTagCompound(); } else { nbt = new NBTTagCompound(); } if (nbt.hasKey("usedOn")){ nbttaglist = (NBTTagList) nbt.getTag("usedOn"); for (int i = 0; i<nbttaglist.tagCount(); i++){ System.out.println("Checking index " + i + ": "+ nbttaglist.getStringTagAt(i)); if (nbttaglist.getCompoundTagAt(i).getString("name").equals(player.getUniqueID().toString())){ System.out.println("Failed to use arrow"); return new ActionResult<ItemStack>(EnumActionResult.FAIL, stack); } } } StandHandlingMethods.grantRandomStandFromTable(player, null); //stub so far addEntityToBlacklist(player, nbt, stack); System.out.println("Successfully used arrow"); return new ActionResult<ItemStack>(EnumActionResult.SUCCESS, stack); } public void addEntityToBlacklist(Entity entity, NBTTagCompound nbt, ItemStack stack){ NBTTagList nbttaglist; if (nbt.hasKey("usedOn")){ nbttaglist = (NBTTagList) nbt.getTag("usedOn"); } else{ nbttaglist = new NBTTagList(); } String entityId = entity.getUniqueID().toString(); NBTTagCompound compound = new NBTTagCompound(); compound.setString("name", entityId); nbttaglist.appendTag(compound); nbt.setTag("usedOn", nbttaglist); stack.setTagCompound(nbt); System.out.println("Blacklisted " + entityId + " from using this Arrow"); } @Override @SideOnly(Side.CLIENT) public void addInformation(ItemStack stack, @Nullable World worldIn, java.util.List<String> tooltip, ITooltipFlag flagIn) { NBTTagList nbttaglist; EntityPlayer player = Minecraft.getMinecraft().player; super.addInformation(stack, worldIn, tooltip, flagIn); if (stack.getTagCompound() != null){ NBTTagCompound nbt = stack.getTagCompound(); if (nbt.getTag("usedOn") != null && nbt.hasKey("usedOn")){ nbttaglist = (NBTTagList) nbt.getTag("usedOn"); for (int i = 0; i<nbttaglist.tagCount(); i++){ if (nbttaglist.getCompoundTagAt(i).getString("name").equals(player.getUniqueID().toString())){ tooltip.add("Already used by " + player.getName()); } } } } } } So the problem wasn't in writing to and reading from the ItemStack's NBT data, it was in how I was interpreting the data within the program. Hopefully you learned some more about NBT from this, as I did.
  2. Heh, well, thanks for your support anyways. If I figure out a solution to what I was looking for I'll post it here. (Btw, happy new year!)
  3. Yeah. I probably should've made that clear earlier, but it should be like this: 1. Each individual item can only be used once per player, i.e. if a player finds another one they can use that item even if they've already used a different one. 2. Each item can be used an infinite number of times, but only once by any individual player, meaning they're reusable by a different person. So yes, if you give it to another player after using it they should also be able to use it.
  4. I thought of using capabilities, but from what I see that makes it so that the item can only be used once in total. The idea I was going for was that the player could find more than one of those items, and could only use each one on themselves once. Your solution isn't quite what I'm going for, but I can't figure out how to make it so that each of the items can only be used once EACH without using NBT... hmm.
  5. Argh, NBT with itemstacks is confusing... Both of my original issues were fixed, but now I have a new one showing up. The item reports a successful usage whenever it's right-clicked with, rather than only the first time it's right-clicked as it's supposed to. The method that's supposed to blacklist entities from using it is definitely being called, but it doesn't seem to be doing anything. I imagine this has something to do with problems reading from or writing to NBT, how would I go about fixing this? @Override public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand) { NBTTagCompound nbt; ItemStack stack = player.getHeldItem(hand); NBTTagList nbttaglist; if (stack.hasTagCompound()) { nbt = stack.getTagCompound(); } else { nbt = new NBTTagCompound(); } if (nbt.hasKey("usedOn")){ nbttaglist = (NBTTagList) nbt.getTag("usedOn"); for (int i = 0; i<nbttaglist.tagCount(); i++){ if (nbttaglist.getStringTagAt(i) == player.getUniqueID().toString()){ System.out.println("Failed to use arrow"); return new ActionResult<ItemStack>(EnumActionResult.FAIL, stack); } } } StandHandlingMethods.grantRandomStandFromTable(player, null); //stub so far addEntityToBlacklist(player, nbt, stack); System.out.println("Successfully used arrow"); return new ActionResult<ItemStack>(EnumActionResult.SUCCESS, stack); } public void addEntityToBlacklist(Entity entity, NBTTagCompound nbt, ItemStack stack){ NBTTagList nbttaglist; if (nbt.hasKey("usedOn")){ nbttaglist = (NBTTagList) nbt.getTag("usedOn"); } else{ nbttaglist = new NBTTagList(); } String entityId = entity.getUniqueID().toString(); NBTTagCompound compound = new NBTTagCompound(); compound.setString("name", entityId); nbttaglist.appendTag(compound); nbt.setTag("usedOn", nbttaglist); System.out.println("Blacklisted " + entityId + " from using this Arrow"); stack.setTagCompound(nbt); } @Override @SideOnly(Side.CLIENT) public void addInformation(ItemStack stack, @Nullable World worldIn, java.util.List<String> tooltip, ITooltipFlag flagIn) { NBTTagList nbttaglist; EntityPlayer player = Minecraft.getMinecraft().player; super.addInformation(stack, worldIn, tooltip, flagIn); if (stack.getTagCompound() != null){ NBTTagCompound nbt = stack.getTagCompound(); if (nbt.getTag("usedOn") != null && nbt.hasKey("usedOn")){ nbttaglist = (NBTTagList) nbt.getTag("usedOn"); for (int i = 0; i<nbttaglist.tagCount(); i++){ if (nbttaglist.getStringTagAt(i) == player.getUniqueID().toString()){ tooltip.add("Already used by " + player.getDisplayName()); } } } } } (Reuploaded code because I changed it somewhat significantly in the interrim)
  6. I'm going to assume this is a typo, but you have nbt.hasKey() being called before nbt is initialized.
  7. I'm having two issues with my custom item, both of which I suspect are related to NBT data. Firstly, the addInformation method crashes the game on loading. This might have to do with some of the necessary variables not being initialized at that point in loading but I can't find anything that could help with that issue. Second, right-clicking with the item for some reason causes the entire stack to disappear. Just to make sure it wasn't just using up only one of them, I changed the max stack size and it still removed the entire stack. public class ItemStandArrow extends Item{ private static final String name = "standArrow"; public ItemStandArrow() { super(); setUnlocalizedName(name); setCreativeTab(CreativeTabs.TOOLS); setMaxStackSize(1); } @Override public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand) { NBTTagCompound nbt; ItemStack stack = player.getActiveItemStack(); NBTTagList nbttaglist; if (stack.hasTagCompound()) { nbt = stack.getTagCompound(); } else { nbt = new NBTTagCompound(); } if (nbt.hasKey("usedOn")){ nbttaglist = (NBTTagList) nbt.getTag("usedOn"); for (int i = 0; i<nbttaglist.tagCount(); i++){ if (nbttaglist.getStringTagAt(i) == player.getUniqueID().toString()){ System.out.println("Failed to use arrow"); return new ActionResult<ItemStack>(EnumActionResult.FAIL, stack); } } } StandHandlingMethods.grantRandomStandFromTable(player, null); System.out.println("Successfully used arrow"); return new ActionResult<ItemStack>(EnumActionResult.SUCCESS, stack); } public void addEntityToBlacklist(Entity entity, NBTTagCompound nbt, ItemStack stack){ NBTTagList nbttaglist; if (nbt.hasKey("usedOn")){ nbttaglist = (NBTTagList) nbt.getTag("usedOn"); } else{ nbttaglist = new NBTTagList(); } String entityId = entity.getUniqueID().toString(); NBTTagCompound compound = new NBTTagCompound(); compound.setString("name", entityId); nbttaglist.appendTag(compound); nbt.setTag("usedOn", nbttaglist); stack.setTagCompound(nbt); } @Override @SideOnly(Side.CLIENT) public void addInformation(ItemStack stack, @Nullable World worldIn, java.util.List<String> tooltip, ITooltipFlag flagIn) { NBTTagCompound nbt = stack.getTagCompound(); NBTTagList nbttaglist; EntityPlayer player = Minecraft.getMinecraft().player; super.addInformation(stack, worldIn, tooltip, flagIn); if (nbt.hasKey("usedOn")){ nbttaglist = (NBTTagList) nbt.getTag("usedOn"); for (int i = 0; i<nbttaglist.tagCount(); i++){ if (nbttaglist.getStringTagAt(i) == player.getUniqueID().toString()){ tooltip.add("Already used by " + player.getDisplayName()); } } } } }
  8. What do the "u" and "v" parameters for that function do? I can't find any documentation that suggests what either of them are.
  9. I got it to show up by changing the event it fired on, but the texture won't display properly. GuiTextureButton's drawButton method: @Override public void drawButton(Minecraft mc, int mouseX, int mouseY, float partialTicks) { if (this.visible) { FontRenderer fontrenderer = mc.fontRenderer; mc.getTextureManager().bindTexture(new ResourceLocation(location)); ScaledResolution res = new ScaledResolution(mc); int width = res.getScaledWidth(); int height = res.getScaledHeight(); GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); this.hovered = mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.width && mouseY < this.y + this.height; int k = this.getHoverState(this.hovered); GlStateManager.enableBlend(); GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0); GlStateManager.blendFunc(770, 771); this.drawTexturedModalRect(this.x, this.y, 0, 46 + k * 20, 16, 16); this.drawTexturedModalRect(this.x + 16 / 2, this.y, width - 16 / 2, 46 + k * 20, 16, 16); this.mouseDragged(mc, mouseX, mouseY); int l = 14737632; if (packedFGColour != 0) { l = packedFGColour; } else if (!this.enabled) { l = 10526880; } else if (this.hovered) { l = 16777120; } this.drawCenteredString(fontrenderer, this.displayString, this.x + this.width / 2, this.y + (this.height / 2), l); } } What it's supposed to show up as: What it shows up as: In addition, whenever I change it to fullscreen mode, the button seems to disappear entirely: I feel as if some of these questions have been addressed before by others but I couldn't find anything specifically solving them.
  10. I'm sure this is probably just an issue with not implementing the code correctly but I can't find any documentation that says exactly how I should do that. GuiTextureButton.java: public class GuiTextureButton extends GuiButton{ private String location; public GuiTextureButton(int buttonId, int x, int y, int width, int height, String location) { super(buttonId, x, y, width, height, ""); this.width = width; this.height = height; this.enabled = true; this.visible = true; this.id = buttonId; this.x = x; this.y = y; this.displayString = ""; this.location = location; } public void drawScreen(Minecraft mc, int mouseX, int mouseY) { if (this.visible) { FontRenderer fontrenderer = mc.fontRenderer; mc.getTextureManager().bindTexture(new ResourceLocation(location)); GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); this.hovered = mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.width && mouseY < this.y + this.height; int k = this.getHoverState(this.hovered); GlStateManager.enableBlend(); GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0); GlStateManager.blendFunc(770, 771); this.drawTexturedModalRect(this.x, this.y, 0, 46 + k * 20, this.width / 2, this.height); this.drawTexturedModalRect(this.x + this.width / 2, this.y, 200 - this.width / 2, 46 + k * 20, this.width / 2, this.height); this.mouseDragged(mc, mouseX, mouseY); int l = 14737632; if (packedFGColour != 0) { l = packedFGColour; } else if (!this.enabled) { l = 10526880; } else if (this.hovered) { l = 16777120; } this.drawCenteredString(fontrenderer, this.displayString, this.x + this.width / 2, this.y + (this.height / 2), l); System.out.println("Drew button"); } } } GuiStandMenuButton.java public class GuiStandMenuButton { public GuiTextureButton standMenuButton; @SubscribeEvent public void addStandMenuButtonToInventory(GuiScreenEvent.KeyboardInputEvent.Pre event){ if (Minecraft.getMinecraft().currentScreen instanceof GuiInventory){ standMenuButton = new GuiTextureButton(0, 50, 50, 50, 50, "stevesbizarrecraft:textures/items/standarrow.png"); standMenuButton.drawScreen(Minecraft.getMinecraft(), 100, 100); } } }
  11. I figured it out... It's because I extended EntityCreature rather than EntityMob. The tutorial I followed (yours, btw, I found it very useful!), having been written in 1.7.10, seems to be a little outdated in that regard.
  12. I overrode all of those methods and keep getting the same issue, so either I implemented them incorrectly or am forgetting something else. Code: @Override public boolean attackEntityAsMob(Entity entityIn) { boolean flag = super.attackEntityAsMob(entityIn); if (flag) { float f = this.world.getDifficultyForLocation(new BlockPos(this)).getAdditionalDifficulty(); if (this.getHeldItemMainhand().isEmpty() && this.isBurning() && this.rand.nextFloat() < f * 0.3F) { entityIn.setFire(2 * (int)f); } } return flag; } @Override public boolean attackEntityFrom(DamageSource source, float amount){//add zombie reinforcements if (source == DamageSource.DROWN || source == DamageSource.FALL){ return false; } else{ return super.attackEntityFrom(source, amount); } } @Override public boolean canAttackClass(Class<? extends EntityLivingBase> entityClass){ if (entityClass == EntityZombie.class || entityClass == EntityVampire.class){ return false; } else{ return super.canAttackClass(entityClass); } } @Override public boolean attackable(){ return true; }
  13. I've seen this issue before for earlier versions, but none of the solutions given seem to have worked for me. Basically the mob will run up to its target as if to attack, but it won't do any actual damage in survival mode. Entity code: public class EntityVampire extends EntityCreature{ public EntityVampire(World worldIn) { super(worldIn); this.setSize(0.6F, 1.95F); } @Override protected void applyEntityAttributes() { super.applyEntityAttributes(); this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(20.0D); this.getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE).setBaseValue(20.0D); this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.40D); this.getEntityAttribute(SharedMonsterAttributes.ARMOR).setBaseValue(40.0D); this.getAttributeMap().registerAttribute(SPAWN_REINFORCEMENTS_CHANCE).setBaseValue(this.rand.nextDouble() * 0.5); getAttributeMap().registerAttribute(SharedMonsterAttributes.ATTACK_DAMAGE); this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(10.0D); getAttributeMap().registerAttribute(SharedMonsterAttributes.ATTACK_SPEED); this.getEntityAttribute(SharedMonsterAttributes.ATTACK_SPEED).setBaseValue(2.0D); } @Override protected void initEntityAI() { this.tasks.addTask(0, new EntityAISwimming(this)); this.tasks.addTask(2, new EntityAIAttackMelee(this, 1.0D, false)); this.tasks.addTask(5, new EntityAIMoveTowardsRestriction(this, 1.0D)); this.tasks.addTask(7, new EntityAIWanderAvoidWater(this, 1.0D)); this.tasks.addTask(8, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); this.tasks.addTask(8, new EntityAILookIdle(this)); this.applyEntityAI(); } protected void applyEntityAI() { this.tasks.addTask(6, new EntityAIMoveThroughVillage(this, 1.0D, false)); this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true, new Class[] {EntityPigZombie.class})); this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<EntityPlayer>(this, EntityPlayer.class, false)); this.targetTasks.addTask(3, new EntityAINearestAttackableTarget<EntityVillager>(this, EntityVillager.class, false)); this.targetTasks.addTask(3, new EntityAINearestAttackableTarget<EntityIronGolem>(this, EntityIronGolem.class, true));} @Override protected void entityInit() { super.entityInit(); }
  14. Ah yeah, that statement was supposed to be nested inside another if-statement but it seems I screwed up the formatting there. Still, the IAttributeInstance keeps crashing the game because it's null, and I can't figure out what to put in the else block to handle that...
  15. Now I keep getting NullPointerExceptions, the error seems to indicate it has something to do with incorrectly creating the AttributeModifier but I'm not sure. Here's the relevant code: static UUID ATTACK_SPEED_MODIFIER = UUID.fromString("b6454cb6-2555-4952-91d4-f20f3ae94eb2"); @SubscribeEvent public static void activeHamonEvent(LivingUpdateEvent event){ if (event.getEntity() instanceof EntityPlayer){ EntityPlayer player = (EntityPlayer) event.getEntity(); final IAttributeInstance iattributeinstance = player.getEntityAttribute(SharedMonsterAttributes.ATTACK_SPEED); if (iattributeinstance != null){ AttributeModifier attributemodifier = iattributeinstance.getModifier(ATTACK_SPEED_MODIFIER); iattributeinstance.removeModifier(attributemodifier); iattributeinstance.applyModifier(new AttributeModifier(attributemodifier.getID(), attributemodifier.getName(), attributemodifier.getAmount()*2, attributemodifier.getOperation())); } else{ AttributeModifier attributemodifier = iattributeinstance.getModifier(ATTACK_SPEED_MODIFIER); iattributeinstance.removeModifier(attributemodifier); iattributeinstance.applyModifier(new AttributeModifier(attributemodifier.getID(), attributemodifier.getName(), 1, attributemodifier.getOperation())); } } } I'm sure it's something simple that I overlooked and that I'm going to kick myself for missing it, but I can't figure out what exactly it is I'm missing.
  16. How should I do that? Do I have to create a specific UUID, or is putting anything fine?
  17. I looked at the class, and managed to figure out a lot of what I need. However, there's still one part that leaves me stumped: AttributeModifier attributemodifier = iattributeinstance.getModifier(); Now getModifier takes a UUID, following the example of other code I've seen I could use the variable ATTACK_SPEED_MODIFIER in there, but trying to put it in there yields nothing. Either that is defined somewhere in the mod's code itself (and I'm just being an idiot) or I'm not referencing it properly. In other words, I'm not sure what UUID I should use in this case, or how to get it.
  18. I saw a post here detailing how to use getAttributeModifiers on a specific item to modify attack speed, which I found very useful. I just want to know if it's possible to modify it in a similar way without overriding the getAttributeModifiers method of a particular item. What I'm trying to achieve is changing attack speed without the need for a specific item (in my case, I'm trying to modify attack speed when holding no item).
  19. I'm pretty sure the src/main/java and src/main/resources files are supposed to be inside the actual Forge folder itself (in the same location as the tutorial mod's files), not the project workspace. I had this problem and moving the files there fixed it for me.
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.