Jump to content

[1.12] Inventory Itemstack and world Block interaction.


Recommended Posts

Posted

I have an Item with varying Textures like the compass or the clock, and I want it to change it's texture if the player gets within a certain horizontal distance (lets say 50 blocks) of a certain block. Now please correct me if I am wrong but I think the best way to do this is by letting the Block (or better said the TileEntity of it), while it is loaded constantly check any players in that distance and then their inventory, for that item. If it finds that item, it sends a data packet to set a boolean in that item to true, to change texture.

Now how would I begin to send this data to the itemstack, would nbttags be what I want? But if I understand nbttags correctly, I can only have a very limited amount of them, I'll be reading about nbttags more while trying to solve this, but any help would be very appreciated. 

Also how would i even change the nbt tag of the itemstack in the players inventoy?

Thanks in advance!

Posted

Use IItemPropertyGetters. These will allow you to pass real time information (represented as floats from 0F - 1F) to the model file and change the model based on that information.

 

Look at ItemCompass and compass.json for an example.

Don't PM me with questions. They will be ignored! Make a thread on the appropriate board for support.

 

1.12 -> 1.13 primer by williewillus.

 

1.7.10 and older versions of Minecraft are no longer supported due to it's age! Update to the latest version for support.

 

http://www.howoldisminecraft1710.today/

Posted

These are my Itemclass and .json:

Item class:

Spoiler

public class SimpleDetectorCognicraft extends ItemCognicraft {

	private boolean isInField = false;
	private int distToCenter = -1;
	private int fieldRadius = 0;

public SimpleDetectorCognicraft(String itemName) {
	super(itemName);
	{
		this.addPropertyOverride(new ResourceLocation("power"), new IItemPropertyGetter()
		{
			@SideOnly(Side.CLIENT)
			float power;
			@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 = (Entity)(flag ? entityIn : stack.getItemFrame());

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

					if (stack.hasTagCompound() && stack.getTagCompound().getBoolean("inField") == true)
					{
						double d0 = stack.getTagCompound().getInteger("fieldRadius");
						double d1 = ((stack.getTagCompound().getDouble("Distance"))/d0);
						this.power = MathHelper.positiveModulo((float)d1, 1.0F);

					}
					else
					{
						power = 0;
					}

					return this.power;
				}
			}
		});
	}
}

 


Item.json:

 

Spoiler

{
  "parent": "item/generated",
  "textures": {
    "layer0": "mymod:items/simple_detector"
  },
  "overrides": [
    { "predicate": { "power": 0.0 }, "model": "mymod:item/simple_detector" },
    { "predicate": { "power": 0.125 }, "model": "mymod:item/simple_detector_1" },
    { "predicate": { "power": 0.25 }, "model": "mymod:item/simple_detector_2" },
    { "predicate": { "power": 0.375 }, "model": "mymod:item/simple_detector_3" },
    { "predicate": { "power": 0.5 }, "model": "mymod:item/simple_detector_4" },
    { "predicate": { "power": 0.625 }, "model": "mymod:item/simple_detector_5" },
    { "predicate": { "power": 0.75 }, "model": "mymod:item/simple_detector_6" },
    { "predicate": { "power": 0.875 }, "model": "mymod:item/simple_detector_7" },
    { "predicate": { "power": 1.0 }, "model": "mymod:item/simple_detector_7" },
  ]
}

 


The NBT values are written into the item by a TileEntity but my Item doesn't seem to update it's Texture.
It's not really working for me yet, I'm kinda confused...

Posted

It's not everything of the class but the relevant stuff, everything gets called here when the TE updates:

 

Spoiler

public void detectPlayer(){
		BlockPos pos = getPos();
		AxisAlignedBB detectRange =  new net.minecraft.util.math.AxisAlignedBB(pos.add(-farDistanceValue+1, -farDistanceValue+1, -farDistanceValue+1), pos.add(farDistanceValue, farDistanceValue, farDistanceValue));
		List playerList = world.getEntitiesWithinAABB(EntityPlayer.class, detectRange);
		for (Iterator<EntityPlayer> iter = playerList.iterator(); iter.hasNext();) {
			EntityPlayer player = iter.next();
			getDetectorItem(player);
		}
	}

	public void findDetectorItem(EntityPlayer playerIn){
		ItemStack stack;
		BlockPos playerPos = playerIn.getPosition();
		double distance = playerPos.getDistance(this.getPos().getX(), this.getPos().getY(), this.getPos().getZ());
		InventoryPlayer playerInv = playerIn.inventory;
		double d0 = farDistanceValue;
		double d1 = distance/d0;
		if (d1<1) {
			for(int i=0; i < 36; i++) {
				stack = playerInv.getStackInSlot(i);
				if (stack.getItem() instanceof SimpleDetectorCognicraft){
					NBTTagCompound nbt;

					if (stack.hasTagCompound())
					{
						nbt = stack.getTagCompound();
					}
					else
					{
						nbt = new NBTTagCompound();
					}
					nbt.setBoolean("isInField", true);
					if (nbt.hasKey("Distance")){
						if (nbt.getInteger("Distance") > distance || nbt.getInteger("Distance") == -1){
							nbt.setDouble("Distance", distance);
							nbt.setInteger("fieldRadius", farDistanceValue);
						}
					}
					else{
						nbt.setDouble("Distance", distance);
						nbt.setInteger("fieldRadius", farDistanceValue);
					}

					/*if (nbt.getString("DistanceType") == "Far"){
						if (nbt.getInteger("Distance") < farDistanceValue){
							nbt.setInteger("Distance", farDistanceValue);
						}
					}
					else if (nbt.getString("DistanceType") == "Medium"){
						if(nbt.getInteger("Distance") < mediumDistanceValue){
							nbt.setInteger("Distance", mediumDistanceValue);
						}
					}
					else if (nbt.getString("DistanceType") == "Close"){
						if(nbt.getInteger("Distance") < closeDistanceValue) {
							nbt.setInteger("Distance", closeDistanceValue);
						}
					}*/
					stack.setTagCompound(nbt);
				}
			}
		}
	}

 

 

Posted (edited)

So better to copy it, edit it and then replace it?

 

Wait how do I use the IItemHandler here correctly, I haven't even been using IInventory I used 

InventoryPlayer

to reach the Players Inventory.

Edited by Calous
Posted (edited)

Ok so I had to read a little bit about Capabilities but I think I got it right this time:

TileEntity:

Spoiler


	public void detectPlayerDetector (){
		BlockPos pos = getPos();
		AxisAlignedBB detectRange =  new net.minecraft.util.math.AxisAlignedBB(pos.add(-farDistanceValue+1, -farDistanceValue+1, -farDistanceValue+1), pos.add(farDistanceValue, farDistanceValue, farDistanceValue));
		List playerList = world.getEntitiesWithinAABB(EntityPlayer.class, detectRange);
		for (Iterator<EntityPlayer> iter = playerList.iterator(); iter.hasNext();) {
			EntityPlayer player = iter.next();
			getDetectorItem(player);
		}
	}

	public void getDetectorItem(EntityPlayer playerIn){
		ItemStack stack;
		BlockPos playerPos = playerIn.getPosition();
		double distance = playerPos.getDistance(this.getPos().getX(), this.getPos().getY(), this.getPos().getZ());
		final IItemHandlerModifiable playerInv = (IItemHandlerModifiable) playerIn.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, EnumFacing.UP);
		double d0 = farDistanceValue;
		double d1 = distance/d0;
		if (d1<1) {
			for(int i=0; i < 36; i++) {
				stack = playerInv.getStackInSlot(i);
				if (stack.getItem() instanceof SimpleDetectorCognicraft){
					ItemStack copiedStack = stack.copy();
					NBTTagCompound nbt;
					if (copiedStack.hasTagCompound())
					{
						nbt = copiedStack.getTagCompound();
					}
					else
					{
						nbt = new NBTTagCompound();
					}
					nbt.setBoolean("isInField", true);
					if (nbt.hasKey("Distance")){
						if (nbt.getInteger("Distance") > distance || nbt.getInteger("Distance") == -1){
							nbt.setDouble("Distance", distance);
							nbt.setInteger("fieldRadius", farDistanceValue);
						}
					}
					else{
						nbt.setDouble("Distance", distance);
						nbt.setInteger("fieldRadius", farDistanceValue);
					}
					copiedStack.setTagCompound(nbt);
					playerInv.setStackInSlot(i, copiedStack);
				}
			}
		}
	}

 

But now my item has no Texture at all anymore (before that I could at least see the layer0), it tells me I have a normal location exception even though I didn't change anything in any .json since the first post. 
And it tells me this is caused by a MalformedJsonException so I guess I did something wrong in my .json.

Edited by Calous
Posted

Ok I got it to work pretty decently, but I can't see my Item when it "switches" because it constantly plays the animation of taking out an item I think, is there any way to stop this? 

The Compass for example doesn't do this.

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.