-
Posts
19 -
Joined
-
Last visited
Recent Profile Visitors
The recent visitors block is disabled and is not being shown to other users.
MythicalChromosome's Achievements
Tree Puncher (2/8)
2
Reputation
-
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.
-
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.
-
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.
-
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)
-
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()); } } } } }
-
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.
-
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); } } }
-
[1.12.2] Entity won't attack
MythicalChromosome replied to MythicalChromosome's topic in Modder Support
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. -
[1.12.2] Entity won't attack
MythicalChromosome replied to MythicalChromosome's topic in Modder Support
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; } -
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(); }
-
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.