Jump to content

[1.11] Compass with NBT tags to store where it points is getting reset


gibraltar

Recommended Posts

In http://www.minecraftforge.net/forum/index.php?topic=43848.0 I asked about a compass that points to the players personal spawn. Thanks to the pointers I got that working with packets to get the correct spawn point. Now I'm going a slightly different direction, and want the compass to point to the players spawn when it is crafted, and keep pointing to that original location, even when the player's spawn changes. Currently, when the spawn NBT tags aren't on the compass' item stack, the code below asks for the player spawn, gets it, then sets it as NBT tags on the item stack. The problem is that when the player opens their inventory, the compass doesn't have the NBT tags, so they are retrieved again (possibly updating them) and set on the item stack again. I've done some digging and cannot see how the NBT tags are being removed from the item stack when you open your inventory. Note that a similar thing happens when you pick the compass up and drag it to a new inventory slot. Yet, as far as I can tell, whenever an ItemStack is copied, the associated NBT tags are copied as well.

 

public class ItemPersonalCompass extends Item {
    public ItemPersonalCompass() {
        addPropertyOverride(new ResourceLocation("angle"), new IItemPropertyGetter() {
            @SideOnly(Side.CLIENT)
            double rotation;
            @SideOnly(Side.CLIENT)
            double rota;
            @SideOnly(Side.CLIENT)
            long lastUpdateTick;

            @SideOnly(Side.CLIENT)
            public float apply(ItemStack stack, @Nullable World worldIn, @Nullable EntityLivingBase entityIn) {
                if (entityIn == null && !stack.isOnItemFrame()) {
                    return 0.0F;
                }
                else {
                    boolean flag = entityIn != null;
                    Entity entity = flag ? entityIn : stack.getItemFrame();

                    if (worldIn == null) {
                        worldIn = entity.worldObj;
                    }

                    BlockPos destinationPos = getCompassSpawn(stack);
                    if (destinationPos == null) {
                        FMLLog.info("getting compass spawn");
                        destinationPos = FindYourWayChallenge.getPlayerSpawn();
                        if (destinationPos == null) {
                            return 0F;
                        }
                        else {
                            FMLLog.info("setting compass spawn");
                            setCompassSpawn(stack, destinationPos.getX(), destinationPos.getZ());
                        }
                    }

                    double d0;

                    if (destinationPos != null) {
                        double d1 = flag ? (double) entity.rotationYaw : getFrameRotation((EntityItemFrame) entity);
                        d1 = d1 % 360.0D;
                        double d2 = getPosToAngle(worldIn, entity, destinationPos);
                        d0 = Math.PI - ((d1 - 90.0D) * 0.01745329238474369D - d2);
                    } else {
                        d0 = Math.random() * (Math.PI * 2D);
                    }

                    if (flag) {
                        d0 = wobble(worldIn, d0);
                    }

                    float f = (float) (d0 / (Math.PI * 2D));
                    return MathHelper.positiveModulo(f, 1.0F);
                }
            }

            @SideOnly(Side.CLIENT)
            private double wobble(World p_185093_1_, double p_185093_2_) {
                if (p_185093_1_.getTotalWorldTime() != lastUpdateTick) {
                    lastUpdateTick = p_185093_1_.getTotalWorldTime();
                    double d0 = p_185093_2_ - rotation;
                    d0 = d0 % (Math.PI * 2D);
                    d0 = MathHelper.clamp_double(d0, -1.0D, 1.0D);
                    rota += d0 * 0.1D;
                    rota *= 0.8D;
                    rotation += rota;
                }

                return rotation;
            }

            @SideOnly(Side.CLIENT)
            private double getFrameRotation(EntityItemFrame itemFrame) {
                return (double) MathHelper.clampAngle(180 + itemFrame.facingDirection.getHorizontalIndex() * 90);
            }

            @SideOnly(Side.CLIENT)
            private double getPosToAngle(World world, Entity entity, BlockPos blockpos) {
                return Math.atan2((double) blockpos.getZ() - entity.posZ, (double) blockpos.getX() - entity.posX);
            }
        });

        setUnlocalizedName("compass_personal");
        setCreativeTab(CreativeTabs.TOOLS);
        setRegistryName(Reference.MOD_PREFIX + "compass_personal");

        GameRegistry.register(this);
        GameRegistry.addRecipe(new ItemStack(this), " I ", "IRI", " I ", 'I', Items.IRON_INGOT, 'R', Items.REDSTONE);
        ModelLoader.setCustomModelResourceLocation(this, 0, new ModelResourceLocation("iberia:compass_personal", "inventory"));
    }

    public void setCompassSpawn(ItemStack stack, int x, int z) {
	if (verifyNBT(stack) && !stack.getTagCompound().getBoolean("SpawnSet")) {
            FMLLog.info("setting spawn for compass: " + x + ", " + z);
            stack.getTagCompound().setBoolean("SpawnSet", true);
		stack.getTagCompound().setInteger("SpawnX", x);
		stack.getTagCompound().setInteger("SpawnZ", z);
	}
}

    public BlockPos getCompassSpawn(ItemStack stack) {
	if (verifyNBT(stack) && stack.getTagCompound().hasKey("SpawnSet")) {
            return new BlockPos(stack.getTagCompound().getInteger("SpawnX"), 0, stack.getTagCompound().getInteger("SpawnZ"));
	}

        return null;
}

    public boolean verifyNBT(ItemStack stack) {
	if (stack.func_190926_b()) {
            return false;
        }
        if (stack.getItem() != this) {
		return false;
	} else if (stack.getTagCompound() == null) {
            FMLLog.info("setting tag compound");
		stack.setTagCompound(new NBTTagCompound());
	}

	return true;
}

Link to comment
Share on other sites

setCompassSpawn is only called from the client side.  You're then saving the NBT client side.

When you open the inventory you're requesting the server's copy, which does not contain the NBT.

 

Something something this is why you were using packets before.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

setCompassSpawn is only called from the client side.  You're then saving the NBT client side.

When you open the inventory you're requesting the server's copy, which does not contain the NBT.

 

Something something this is why you were using packets before.

 

Dang, Draco, you are always so quick to help. It's awesome.

 

I suspected it was something like this. So I guess the next question is where would be a good place, server side, to set the NBT tags. I could do it in ItemCraftedEvent, because there is a player associated with it. What about when a player pulls one of these compasses from a chest (put there by a loot table), or gets one via a villager trade?

Link to comment
Share on other sites

Crafted works, or if this compass is your item "OnItemRightClick"? You should also be able to have the tooltip check to see if a NBT is set on the ItemStack to display "Please right-click/use to set location" or if set show coords or w/e. For PvP would allow for killing someone to get their "Points of Interest"

Link to comment
Share on other sites

Crafted works, or if this compass is your item "OnItemRightClick"? You should also be able to have the tooltip check to see if a NBT is set on the ItemStack to display "Please right-click/use to set location" or if set show coords or w/e. For PvP would allow for killing someone to get their "Points of Interest"

 

Good points, Hugo. I think I've got it working now, so I can play around with different ways to activate the compass. Regardless, I like the way you're thinking when it comes to PvP.

Link to comment
Share on other sites

What happens if you try to stack your compasses together?

 

When an item is generated by a loot table, then there is no crafting. I'd give such a compass the coords of the chest where it started. It would be kind of cool to have an item that could point back to a special location.

 

But, if you don't like that, then you could treat these like maps. They could be undifferentiated and stackable until activated. Once activated (by right-clicking), a compass would retain the spawn coords of the player who used it.

The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.

Link to comment
Share on other sites

What happens if you try to stack your compasses together?

 

When an item is generated by a loot table, then there is no crafting. I'd give such a compass the coords of the chest where it started. It would be kind of cool to have an item that could point back to a special location.

 

But, if you don't like that, then you could treat these like maps. They could be undifferentiated and stackable until activated. Once activated (by right-clicking), a compass would retain the spawn coords of the player who used it.

 

These compasses will fit into a bigger story in the mod, but I do like the idea of compasses found in strongholds (the only place in vanilla where they can be found) pointing back to the stronghold. As for stackability, once a compass has the NBT tags that tell it where to point, then only other compasses with the exact same tags can be stacked with it. Which makes sense for my purposes.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

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